基于单片机的作息时间控制系统完整版_第1页
基于单片机的作息时间控制系统完整版_第2页
基于单片机的作息时间控制系统完整版_第3页
基于单片机的作息时间控制系统完整版_第4页
基于单片机的作息时间控制系统完整版_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

./目录一、引言31.1单片机的作息时间控制系统设计的目的和意义31.2方案比较3二、整体设计方框图4三、模块电路设计53.1.单片机核心控制模块53.2键盘模块73.3实时时钟模块123.4数据存储模块143.5温度传感器模块3.6红外模块3.7电机模块3.8显示模块3.9外围驱动模块四、单片机软件系统设计154.1系统实现工作流程 4.2系统流程图 4.3系统源程序五、元件明细表16六、整机电路图196.1整体原理图196.2整体PCB图206.3整体PCB3D图七、总结与致谢24八、参考文献24一、引言1.1单片机作息时间控制系统设计的目的和意义随着计算机技术的发展和在控制系统中的广泛应用,以及设备向小型化、智能化发展,作为高新技术之一的单片机以其体积小、功能强、价格低廉、使用灵活等优势,显示出了很强的生命力。进入21世纪以来,开发推出单片机的公司很多,各种高性能单片机芯片市场也异常活跃,新技术的不断采用,更加使单片机的种类、性能以及应用领域不断扩大和提高。因其功耗低,超高型,低成本,功能完整,在国内越来越受到用户的重视和广泛使用。

本设计是一个具有打铃、当前环境温度显示、教室灯光、广播、校门开关的自动控制等功能的作息时间控制系统。同时该系统也是一可调式万年历,采用SG12864液晶具有良好的菜单式人机界面更使本系统增色不少。它利用PCF8563实时时钟芯片计时,进行年历计算,并用SG12864将当前日期、星期、时间出来;在进行时间计算,分每加一时,都与规定的作息时间比较,如果相等则进行相应的控制或动作。由单片机核心控制模块、键盘模块、电机模块、实时时钟模块、红外模块、液晶显示模块、温度传感器模块、数据存储模块、外围驱动模块九部分组成,系统扩展16个矩阵按键用于打铃时间调整及时间校正。现代机关企业,特别是学校要求对时间加以控制,要按时打铃及播放广播,以保证学习与工作的正常运行。本设计实现了这些功能,给学校及其他机关企业带来方便,整体性好,人性化强、可靠性高,实现了对时间控制的智能化。1.2方案比较作息时间控制系统的设计有很多方案可以实现,其主流技术主要有以下几种:〔1用可编程逻辑器件〔如CPLD、FPGA来实现,而在本设计中如要实现功能相对来说比较复杂,必须得用到FPGA来实现,而FPGA的价格相对较贵,且系统设计比较困难。〔2用PLC来实现,PLC其实就是一被封装起来的单片机,里面设有监控程序,并对I/O端口进行了光电隔离。这样一来使得PLC性能稳定且容易使用,且只需简单外围电路就可以实现该系统功能,但PLC比较昂贵,这样会使成本增高而失去市场竞争。〔3就是用555定时器产生时钟脉冲和数字芯片〔如74LS14来实现,但要来实现本设计需要大量的数字芯片,使得系统稳定性下降,生产难度加大,而且成本会增加。〔4就是应用单片充当主控器来再加上适量的外围实现此功能,且单片机价格便宜,性能稳定。应用的外围器件相对较少,这就提高了系统的稳定性,且单片机控制简易,开发工具简单,很容易大批量生产。经过以上比较,最终我们选择第〔4种方案来实施。二.整体设计方框图三.模块电路设计3.1单片机核心控制模块A.核心器件的选择单片机是本设计的核心器件,因此单片机的选择决定了该设计的稳定和性能,目前单片机市场种类繁多,有几千种不同型号,单片机的选择应遵循在能满足性能条件下尽可能的选择功耗小资源少价格低,而且货源充足的。现在主流单片机种类有以下几类:PIC单片机:是MICROCHIP公司的产品,其突出的特点是体积小,功耗低,精简指令集,抗干扰性好,可靠性高,有较强的模拟接口,代码保密性好,大部分芯片有其兼容的FLASH程序存储器的芯片。EMC单片机:是XX义隆公司的产品,有很大一部分与PIC8位单片机兼容,且相兼容产品的资源相对比PIC的多,价格便宜,有很多系列可选,但抗干扰较差。ATMEL单片机<51单片机>:ATMEL公司的8位单片机有AT89、AT90两个系列,AT89系列是8位Flash单片机,与8051系列单片机相兼容,静态时钟模式;AT90系列单片机是增强RISC结构、全静态工作方式、内载在线可编程Flash的单片机,也叫AVR单片机。PHLIPIS51PLC系列单片机<51单片机>:PHILIPS公司的单片机是基于80C51内核的单片机,嵌入了掉电检测、模拟以及片内RC振荡器等功能,这使51LPC在高集成度、低成本、低功耗的应用设计中可以满足多方面的性能要求。HOLTEK单片机:XX盛扬半导体的单片机,价格便宜,种类较多,但抗干扰较差,适用于消费类产品。TI公司单片机<51单片机>:XX仪器提供了TMS370和MSP430两大系列通用单片机.TMS370系列单片机是8位CMOS单片机,具有多种存储模式、多种外围接口模式,适用于复杂的实时控制场合;MSP430系列单片机是一种超低功耗、功能集成度较高的16位低功耗单片机,特别适用于要求功耗低的场合。最后我们决定选用ATMEL公司的AT89S51单片机,AT89S51是ATMEL公司生产的低功耗,高性能、高性价比的CMOS8位单片机,片内含4Kbytes的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准8051指令系统及引脚。它集Flash程序存储器既可在线编程〔ISP也可用传统方法进行编程及通用8位微处理器于单片芯片中,AT89S51含有128×8字节内部RAM、32个可编程I/O口线、2个16位定时/计数器、6个中断源和全双工串行UART通道,已能满足系统控制需求。B.模块电路设计 单片机运行需要满足几个条件,首先必需提供电源,还时钟振荡源,还有复位。由于十二个时钟周期构成一个机器周期,在这里为方便计算我们选取晶振频率为12MHZ的晶振,因为晶振产生的信号比较弱,电容选取范围只能是小于30PF,在这里我们选取C1、C2为22PF。当单片机的复位端持续为两个机器周期高电平时产生复位,因此复位电路的参数需要根据晶振来决定,单片机控制系统一般都要求达到上电复位,因此这就对电容和电阻的选择有一定的要求,这可以通过计算来得出元件参数,但单片机最小系统的参数有一个经验值,在这里我们选用取R2100Ω、R110K,C3取10UF。由于单片机的P0口结构的特殊性,需加上拉电阻,这里我们选取阻值为10K的电阻,而耐压值的选择我们则只须选择大于7.5V就行了。C.模块电路图3.2键盘模块A.键盘电路选择键盘可以有几种选择:一种是利用键盘LED芯片〔如HD7279、HD8279、MAX7219等,一种则是直接利用单片机I/O口搭建键盘电路。采用键盘LED芯片,具有编程简单,抗干扰能力强、稳定性好、功能强大等特点,但其成本比较高,而且占用额外的功耗和空间,通常用在对键盘读取要求较高的场合。而普通的键盘电路,则有电路简单,成本低等特点,但其抗干扰能力较前者弱。而键盘电路结构又分为直接型和矩阵型,直接型具有编程、电路简单等特点,但占用的I/O口比较多,适用于只需少量键盘的场合。矩阵型具有电路、编程复杂等特点,但占用I/O口少,比较适应于要求键盘比较多的场合。而本设计的显示电路是采用的LCD显示,且对键盘读取要求也不是太高,采取键盘芯片不能充分利用其功能,有点浪费。且单片机I/O口比较紧张,所以决定采用普通矩阵键盘。B.模块电路设计 在本设计中有用到数字键0-9,且还有上、下、左、右、确定、取消键。一共十六个键,刚好可用8个I/O口组成4*4矩阵键盘。而矩阵键盘的搭建比较简单,只需遵循行列相交搭建就行,而必需在行或列添加上拉电阻,而上拉电阻的选取就只需遵循上拉电流小于单片机最大灌电流就行,在这里我们选取10K的电阻来充当上拉电阻。C.模块电路图3.3实时时钟模块A.核心器件选择 在单片机内部,可以利用定时器进行计时,也可以实现功能,但利用内部定时器进行计时会产生计时不精确,且增加了CPU的负担和编程的难度,再就是掉电重启后时间会全部被初始化。因此我们采用实时时钟芯片,实时时钟芯片的种类繁多。在这里我们选用PCF8563实时时钟芯片。PCF8563是低功耗的CMOS实时时钟/日历芯片,它提供一个可编程时钟输出,一个中断输出和掉电检测器,所有的地址和数据通过I2C总线接口串行传递。最大总线速度为400Kbits/s,每次读写数据后,内嵌的字地址寄存器会自动产生增量,可编程时钟输出刚好可以为红外发射管提供载波信号。特性*低工作电流:典型值为0.25μA〔VDD=3.0V,Tamb=25℃时。*世纪标志*大工作电压范围:1.0~5.5*低休眠电流;典型值为0.25μA<VDD=3.0V,Tamb=25℃>*400KHz的I2C总线接口〔VDD=1.8~5.5V时。*可编程时钟输出频率为:32.768KHz,1024Hz,32Hz,1Hz。*报警和定时器。*掉电检测器。*内部集成的振荡器电容。*片内电源复位功能。*I2C总线从地址:读,0A3H;写,0A2H。*开漏中断引脚。PCF8563有16个8位寄存器:一个可自动增量的地址寄存器,一个内置32.768KHz的振荡器〔带有一个内部集成的电容,一个分频器〔用于给实时时钟RTC提供源时钟,一个可编程时钟输出,一个定时器,一个报警器,一个掉电检测器和一个400KHzI2C总线接口。所有16个寄存器设计成可寻址的8位并行寄存器,但不是所有位都有用。前两个寄存器〔内存地址00H,01H用于控制寄存器和状态寄存器,内存地址02H~08H用于时钟计数器〔秒~年计数器,地址09H~0CH用于报警寄存器〔定义报警条件,地址0DH控制CLKOUT管脚的输出频率,地址0EH和0FH分别用于定时器控制寄存器和定时器寄存器。秒、分钟、小时、日、月、年、分钟报警、小时报警、日报警寄存器,编码格式为BCD,星期和星期报警寄存器不以BCD格式编码。当一个RTC寄存器被读时,所有计数器的内容被锁存,因此,在传送条件下,可以禁止对时钟/日历芯片的错读。一个或多个报警寄存器MSB〔AE=AlarmEnable报警使能位清0时,相应的报警条件有效,这样,一个报警将在每分钟至每星期范围内产生一次。设置报警标志位AF〔控制/状态寄存器2的位3用于产生中断,AF只可以用软件清除。8位的倒计数器〔地址0FH由定时器控制寄存器〔地址0EH控制,定时器控制寄存器用于设定定时器的频率〔4096,64,1,或1/60Hz,以及设定定时器有效或无效。定时器从软件设置的8位二进制数倒计数,每次倒计数结束,定时器设置标志位TF,定时器标志位TF只可以用软件清除,TF用于产生一个中断〔/INT,每个倒计数周期产生一个脉冲作为中断信号。TI/TP控制中断产生的条件。当读定时器时,返回当前倒计数的数值。管脚CLKOUT可以输出可编程的方波。CLKOUT频率寄存器〔地址0DH;参见表23决定方波的频率,CLKOUT可以输出32.768KHz<缺省值>,1024,32,1Hz的方波。CLKOUT为开漏输出管脚,通电时有效,无效时为高阻抗。表1PCF8563寄存器结构地址寄存器名称D7D6D5D4D3D2D1D000H控制/状态寄存器1TEST0STOP0TTESTC00001H控制/状态寄存器2000TI/TPAFTFAIETIE02H秒寄存器VL00~59BCD码格式数03H分寄存器-00~59BCD码格式数04H时寄存器-00~23BCD码格式数05H日寄存器-00~31BCD码格式数06H星期寄存器-00~06BCD码格式数07H月/世纪寄存器C00~12BCD码格式数08H年寄存器00~99BCD码格式数09H分钟报警寄存器AE00~59BCD码格式数0AH时钟报警寄存器AE00~23BCD码格式数0BH日报警寄存器AE00~31BCD码格式数0CH星期报警寄存器AE00~06BCD码格式数0DHCLKOUT频率寄存器FE-----FD1FD00EH定时控制寄存器TETD1TD00FH定时器倒计时数值寄存器定时器倒数计数数值B.模块电路设计 本模块电路比较简单,只需注意一个地方,那就是实时时钟芯片一般装有后备电池,以保证当断电时仍继续计时,这就需要考虑一个当断电时电流反灌而损坏电源的问题,还有就是当从断电状态进入上电电压的瞬时上升会造成电池寿命的缩短,因此我们在电源和地之间需加一二极管和缓冲电容,二极管的选取只须考虑最大正向整流电流和最大反向电压,在这里们选取4148,而缓冲电容则选取0.047F。而晶振必须选取32.768KHZ,在晶振和地之间须串联一耦合电容,耦合电容只须小于35P就可以了,在这里我们先取18P。C.模块电路图2.4数据存储模块A.核心器件选择 本模块的设计是为了增加在线调整作息时间,以更适应现实生活中的需要。而数据存储芯片,我们采用非掉电易失的串行EEPROM芯片进行存储。串行EEPROM中,较为典型的有ATMEL公司的AT24CXX系列以及该公司生产的AT93CXX系列,较为著名的半导体厂家,包括Microchip,国家半导体厂家等,都有AT93CXX系列EEPROM产品。AT24CXX系列的串行电可改写及可编程只读存储器EEPROM有10种型号,其中典型的型号有AT24C01A/02/04/08/16等5种,它们的存储容量分别是1024/2048/4096/8192/16384位,也就是128/256/512/1024/2048字节。这个系列一般用于低电压,低功耗的工业和商业用途,并且可以组成优化的系统。信息存取采用2线串行接口。这里我们就24C02的结构特点,其它系列比较类似。AT24C02有地址线A0~A2,串行时钟引脚SDA,串行时钟输入引脚SCL,写保护引脚WP等引脚。很明显,其引脚较少,对组成的应用系统可以减少布线,提高可靠性。各引脚的功能和意义如下:①VCC引脚,电源+5V。②GND引脚,地线。③SCL引脚,串行时钟输入端。在时钟的正跳沿即上升沿时把时钟写入EEPROM;在时钟的负跳沿即下降沿时把数据从EEPROM中读出来。④SDA引脚,串行数据I/O端,用于输入和输出串行数据。这个引脚是漏极开路的埠,故可以组成"线或"结构。⑤A0,A1,A2引脚,是芯片地址引脚。在型号不同时意义有些不同,但都要接固定电平。⑥WP引脚,写保护端。这个端提供了硬件数据保护。当把WP接地时,允许芯片执行一般读写操作;当把WP接VCC时,则对芯片实施写保护。内存的组织:对于不同的型号,内存的组织不一样,其关键原因在于内存容量存在差异。对于AT24CXX系列的EEPROM,其典型型号的内存组织如下。AT24C01A:内部含有128个字节,故需要7位地址对其内部字节进行寻址AT24C02:内部含有256个字节,故需要8位地址对其内部字节进行读写。起始状态:当SCL为高电平时,SDA由高电平变到低电平则处于起始状态。起始状态应处于任何其它命令之前。停止状态:当SCL处于高电平时,SDA从低电平变到高电平则处于停止状态。在执行完读序列信号之后,停止命令将把EEPROM置于低功耗的备用方式<StandbyMode>.应答信号:应答信号是由接受资料的器件发出的。当EEPROM接受完一个写入资料之后,会在SDA上发一个"0"应答信号。反之,当单片机接受完来自EEPROM的资料后,单片机也应向SDA发ACK信号。ACK信号在第9个时钟周期时出现。备用方式<StandbyMode>:AT24C01A/02/04/08/16都具有备用方式,以保证在没有读写操作时芯片处于低功耗状态。在下面两种情况中,EEPROM都会进入备用方式:第一,芯片通电的时候;第二,在接到停止位和完成了任何内部操作之后。AT24C01等5种典型的EEPROM在进入起始状态之后,需要一个8位的"器件地址字"去启动内存进行读或写操作。在写操作中,它们有"字节写","页面写"两种不同的写入方法。在读操作中,有"现行地址读",随机读和"顺序读"种各具特点的读出方法。下面分别介绍器件寻址,写操作和读操作。①器件寻址:所谓器件寻址<DeviceAddressing>就是用一个8位的器件地址字<DeviceAddressWord>去选择内存芯片。在逻辑电路中的AT24CXX系列的5种芯片种,即AT24C01A/02/04/08/16中,如果和器件地址字相比较结果一致,则读芯片被选中。下面对器件寻址的过程和意义加以说明。②芯片的操作地址D7D6D5D4D3D2D1D01010A2A1A0R/W用于内存EEPROM芯片寻址的器件地址字如图所示。它有4种方式,分别对应于1K/2K,4K,8K和16K位的EEPROM芯片。从图中看出:器件地址字含有3个部分。第一部分是高4位,它们称为EEPROMAT24C01A/02/04/08/16的标识第二部分称为硬布线地址,它们是标识后的3位。第三部分是最低位,它是读/写操作选择位。第一部分:器件标识,器件地址字的最高4位。这4位的内容恒为"1010",用于标识EEPROM器件AT24C01A/02/04/08/16。第二部分:硬布线地址,是与器件地址字的最高4位相接的低3位。硬布线地址的3位有2种符号:Ai<i=0~2>,Pj<j=0~2>其中Ai表示外部硬布线地址位。对于AT24C10A/02这两种1K/2K位的EEPROM芯片,硬布线地址为"A2,A1,A0"。在应用时,"A2,A1,A0"的内容必须和EEPROM芯片的A2,A1,A0的硬布线情况,即逻辑连接情况相比较,如果一样,则芯片被选中;否则,不选中。AT24C01/02:真正地址=字地址。第三部分:读/写选择位,器件地址字的最低位,并用R/W表示。当R/W=1时,执行读操作;当R/W=0时,执行写操作。当EEPROM芯片被选中时,则输出"0";如果EEPROM芯片没有被选中,则它回到备用方式。被选中的芯片。其以后的输入,输出情况视写入和读出的内容而定。③写操作:AT24C01A/02/04/08/16这5种EEPROM芯片的写操作有2种:一种是字节写,另一种是页面写。字节写:这种写方式只执行1个字节的写入。字节写的过程如图所示,其写入过程分外部写和内部写两部分,分别说明如下。在起始状态中,首先写入8位的器件地址。则EEPROM芯片会产生一个"0"信号ACK输出作为应答;接着,写入8位的字地址,在接受了字地址之后,EEPROM芯片又产生一个"0"应答信号ACK;随后,写入8位资料,在接受了资料之后,芯片又产生一个"0"信号ACK作为应答。到此为止,完成了一个字节写过程,故应在SDA端产生一个停止状态,这是外部写过程。在这个过程中,控制EEPROM的单片机应在EEPROM的SCL,SDA端送入恰当的信号。当然在一个字节写过程结束时,单片机应以停止状态结束写过程。在这时,EEPROM进入内部定时的写周期,以便把接受的数据写入到存储单元中。在EEPROM的内部写周期中,其所有输入被屏蔽,同时不响应外部信号直到写周期完成。这是内部写过程。内部写过程大约需要10ms时间。内部写过程处于停止状态与下一次起始状态之间。页面写:这种写入方式执行含若干字节的1个页面的写入。对于AT24C01A/02,它们的1个页面含8个字节;页面写的开头部分和字节写一样。在起始状态,首先写入8位器件地址;待EEPROM答当了"0"信号ACK之后,写入8位字地址;又待芯片应答了"0"信号ACK之后,写入8位资料。随后页面写的过程则和字节写有区别。当芯片接受了第一个8位资料并产生应答信号ACK之后,单片机可以连续向EEPROM芯片发送共为1页面的资料。对于AT24C01A/02,可发送共1个页面的8个字节〔连第一个8位资料在内。对于AT24C04/08/16,则共可发送1个页面共16个字节〔连第一个8位资料在内。当然,每发一个字节都要等待芯片的应答信号ACK。之所以可以连续向芯片发送1个页面资料,是因为字地址的低3~4位在EEPROM芯片内部可实现加1,字地址的高位不变,用于保持页面的行地址。页面写和字节写两者一样可,都分为外部写和内部写过程。应答查询:应答查询是单片机对EEPROM各种状态的一种检测。单片机查询到EEPROM有应答"0"信号ACK输出,则说明其内部定时写的周期结束,可以写入新的内容。单片机是通过发送起始状态及器件地址进行应答查询的。由于器件地址可以选择芯片,则检测芯片送出到SDA的状态就可以知道其是否有应答了。④读操作:读操作的启动是和写操作类同的。它一样需要图所示的器件地址字。和写操纵不同的就是信号为时执行读操作。读操纵有3种方式,即现行地址读,随机读和顺序读。下面分别说明它们的工作过程。现行地址读:在上次读或写操纵完成之后。芯片内部字地址计数器会加1,产生现行地址。只要没有再执行读或写操作,这个现行地址就会在EEPROM芯片保持接电的期间一直保存。一旦器件地址选中EEPROM芯片,并且有R/W=1,则在芯片的应答信号ACK之后把读出的现行地址的资料送出。现行地址的资料输出时,就由单片机一位一位接受,接收后单片机不用向EEPROM发应答信号ACK"0"电平,但应保证发出停止状态的信号以结束现行地址读操作。现行地址读会产生地址循环覆盖现象,但和写操纵的循环覆盖不同。在写操纵中,地址的循环覆盖是现行页面的最后一个字节写入之后,再行写入则覆盖同一页面的第一个字节。而在现行地址读操纵中,地址的循环覆盖是在最后页面的最后一个字节读出之后,再行读出才覆盖第一个页面的第一个字节。随机读:随机读和现行地址读的最大区别在于随机读会执行一个伪写入过程以把字地址装入EEPROM芯片中,然后执行读出,显然,随机读有2个步骤。第一,执行伪写入——把字地址送入EEPROM,以选择需读的字节。第二,执行读出——根据字地址读出对应内容。当EEPROM芯片接收了器件地址及字地址时,在芯片产生应答信号ACK之后,单片机必须再产生一个起始状态,执行现行地址读,这时单片机再发出器件地址并且令R/W=1,则EEPROM应答器件地址并行输出被读数据。在资料读出时由单片机执行一位一位接收,接收完毕后,单片机不用发"0"应答信号ACK,但必须产生停止状态以结束随机读过程。应该注意:在随机读的第二个步骤是执行现行地址读的,由于第一个步骤时芯片接收了字地址,故现行地址就是所送入的字地址。顺序读:顺序读可以用现行地址读或随机读进行启动。它和现行地址读。随机读的最大区别在于:顺序读在读出一批资料之后才由单片机产生停止状态结束读操作;而现行地址读和随机读在读出一个资料之后就由单片机产生停止状态结束读操作。执行顺序读时,首先执行现行读或随机读的有关过程,在读出第一个资料之后,单片机输出"0"应答信号ACK。在芯片接收应答信号ACK后,就会对字地址进行计数加1,随后串行输出对应的字节。当字地址计数达到内存地址的极限时,则字地址会产生覆盖,顺序读将继续进行。只有在单片机不再产生"0"应答信号ACK,而在接收资料之后马上产生停止状态,才会结束顺序读操作。B.模块电路设计 本模块电路简单,只须将三地址端和写保护接地就可以了。C.模块电路图3.5温度传感器模块A.核心器件选择Dallas半导体公司的数字化温度传感器DS1820是世界上第一片支持"一线总线"接口的温度传感器。现场温度直接以"一线总线"的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。与前一代产品不同,新的产品支持3V~5.5V的电压范围,使系统设计更灵活、方便。DS18B20测量温度范围为-55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。DS18B20可以程序设定9~12位的分辨率,及用户设定的报警温度存储在EEPROM中,掉电后依然保存。DS18B20内部结构DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20的管脚排列如下:DQ为数字信号输入/输出端;GND为电源地;VDD为外接供电电源输入端〔在寄生电源接线方式时接地。光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位〔28H是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码〔CRC=X8+X5+X4+1。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。DS18B20中的温度传感器可完成对温度的测量,以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以0.0625℃/LSB形式表达,其中S为符号位。LSByte:Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit0232221202-12-22-32-4MSByte:Bit15Bit14Bit13Bit12Bit11Bit10Bit9Bit8SSSSS262524这是12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘以0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘以0.0625即可得到实际温度。例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FF6FH,-55℃的数字输出为FC90H。温度数据输出〔二进制数据输出〔十六进制+125℃000001111101000007D0h+85℃00000101010100000550h+25.0625℃00000001100100010191h+10.125℃000000001010001000A2h+0.5℃00000000000010000008h0℃00000000000000000000h-0.5℃1111111111111000FFF8h-10.125℃1111111101011110FF5Eh-25.0625℃1111111001101111FE6Fh-55℃1111110010010000FC90hDS18B20温度传感器的存储器DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的E2RAM,后者存放高温度和低温度触发器TH、TL和结构寄存器。暂存存储器包含了8个连续字节,前两个字节是测得的温度信息,第一个字节的内容是温度的低八位,第二个字节是温度的高八位。第三个和第四个字节是TH、TL的易失性拷贝,第五个字节是结构寄存器的易失性拷贝,这三个字节的内容在每一次上电复位时被刷新。第六、七、八个字节用于内部计算。第九个字节是冗余检验字节。该字节各位的意义如下:TMR1R011111低五位一直都是1,TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。在DS18B20出厂时该位被设置为0,用户不要去改动。R1和R0用来设置分辨率,如下表所示:〔DS18B20出厂时被设置为12位分辨率设置表:R1R0分辨率温度最大转换时间009位93.75ms0110位187.5ms1011位375ms1112位750ms根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后释放,DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。B.模块电路设计 本模块接口电路简单,在这里不对电路进行讲解了。C.模块电路图3.6红外模块A.核心元件选择红外通信是利用950nm近红外波段的红外线作为传递信息的媒体,即通信信道。发送端采用脉时调制〔PPM方式,将二进制数字信号调制成某一频率的脉冲序列,并驱动红外发射管以光脉冲的形式发送出去;接收端将接收到的光脉转换成电信号,再经过放大、滤波等处理后送给解调电路进行解调,还原为二进制数字信号后输出。红外发送器电路包括脉冲振荡器、驱动管Q1和Q2、红外发射管Q3等部分。其中脉冲振荡器用以产生38kHz的脉冲序列作为载波信号;红外发射管Q3用来向外发射950nm的红外光束。红外发送器的工作原理为:串行数据由单片机的串行输出端DATA送出并驱动Q1管,数位"0"使Q1管导通,通过Q2管调制成38kHz的载波信号,并利用红外发射管Q3以光脉冲的形式向外发送。数位"1"使Q1管截止,红外发射管Q3不发射红外光。若传送的波特率设为1200bps,则每个数位"0"对应32个载波脉冲调制信号的时序,如图1所示。图1调制信号时序图红外接收电路选用专用红外接收模块。该接收模块是一个三端元件,使用单电源+5V电源,具有功耗低、抗干扰能力强、输入灵敏度高、对其它波长〔950nm以外的红外光不敏感的特点,其内部结构框图如图2所示。图2红外接收模块内部结构框图接收模块的工作原理为:首先,通过红外光敏元件将接收到的载波频率为38kHz的脉冲调制红外光信号转化为电信号,再由前置放大器和自动增益控制电路进行放大处理。然后,通过带通滤波器和进行滤波,滤波后的信号由解调电路进行解调。最后,由输出级电路进行反向放大输出。为保证红外接收模块接收的准确性,要求发送端载波信号的频率应尽可能接近38kHz,因此在设计脉冲振荡器时,要选用精密元件并保证电源电压稳定。再有,发送的数位"0"至少要对应14个载波脉冲,这就要求传送的波特率不能超过2400bps。B.模块电路设计 红外发射二极管的额定电流为5-50mA在这里我选取限流电阻R10470Ω,而从PCF8563产生的信号比较微弱,须加上拉电阻,在这里选取R810K的上拉电阻。为减少噪声影响我们在基极和载波信号间加一抗干扰电阻R9,阻值为1K。在接收管处为增加输出信号强度和减少噪声影响,输出端也加一拉电阻R11,阻值为10K,由于本设计是利用单片机中断以做出及时响应,在这里输出需加一反向器然后再送入单片才能达到控制功能,在这里我采用74LS04。C.模块电路图3.7电机模块A.核心器件选择 电机分直流电机和步进电机,而步进电机力矩大且便于精准控制,步进电动机有三线式、五线式、六线式三种,但其控制方式均相同,必须以脉冲电流来驱动。若每旋转一圈以20个励磁信号来计算,则每个励磁信号前进18度,其旋转角度与脉冲数成正比,正、反转可由脉冲顺序来控制。步进电动机的励磁方式可分为全步励磁及半步励磁,其中全步励磁又有1相励磁及2相励磁之分,而半步励磁又称1-2相励磁。图为步进电动机的控制等效电路,适应控制A、B、/A、/B的励磁信号,即可控制步进电动机的转动。每输出一个脉冲信号,步进电动机只走一步。因此,依序不断送出脉冲信号,即可步进电动机连续转动。1相励磁法:在每一瞬间只有一个线圈导通。消耗电力小,精确度良好,但转矩小,振动较大,每送一励磁信号可走18度。若欲以1相励磁法控制步进电动机正转,其励磁顺序如图所示。若励磁信号反向传送,则步进电动机反转。励磁顺序:A→B→C→D→ASTEPABCD110002010030010400012相励磁法:在每一瞬间会有二个线圈同时导通。因其转矩大,振动小,故为目前使用最多的励磁方式,每送一励磁信号可走18度。若以2相励磁法控制步进电动机正转,其励磁顺序如图所示。若励磁信号反向传送,则步进电动机反转。励磁顺序:AB→BC→CD→DA→ABSTEPABCD111002011030011410011-2相励磁法:为1相与2相轮流交替导通。因分辨率提高,且运转平滑,每送一励磁信号可走9度,故亦广泛被采用。若以1相励磁法控制步进电动机正转,其励磁顺序如图所示。若励磁信号反向传送,则步进电动机反转。励磁顺序:A→AB→B→BC→C→CD→D→DA→ASTEPABCD1100021100300104011050010600117000181001电动机的负载转矩与速度成反比,速度愈快负载转矩愈小,当速度快至其极限时,步进电动机即不再运转。所以在每走一步后,程序必须延时一段时间。B.模块电路设计 刚凭单片机的I/O口是无法驱动步进电机的,因此需要加驱动芯片,在这里我们选择ULN2003,ULN2003是耐高压、大电流NPN达林顿管,恰好能满足驱动需求,在输出端串联一小电阻以减少噪声干扰,在这里电阻取20Ω。C.模块电路图3.8显示模块A.核心器件选择显示可用LED数码管或LCD显示,LCD显示器具有显示丰富、功耗低、低闪烁和低幅射等特点。为使人机界面更加和谐丰富在这里我们采用128*64LCD显示器。本设计采用内置控制器、不带字库的图形点阵液晶显示模块,点阵数为128×64。它主要由行驱动器/列驱动器及128×64全点阵液晶显示器组成,可完成图形显示也可以显示8×4个<16×16点阵>汉字。主要技术参数和性能:1电源VDD+5V模块内自带-10V负压用于LCD的驱动电压2显示内容128<列>64<行>点3全屏幕点阵4七种指令5与CPU接口采用8位数据总线并行输入输出和8条控制线6占空比1/647工作温度-10+55存储温度-20+60模块主要硬件构成说明<结构框图>IC1、IC2为列驱动器,IC1控制模块的右半屏,IC2控制模块的左半屏,IC3为行驱动器。IC1、IC2、IC3含有以下主要功能器件,了解如下器件有利于对LCD模块的编程。1指令寄存器<IR>IR是用于寄存指令码,与数据寄存器数据相对应,当D/I=0时在E信号下降沿的作用下指令码写入IR2数据寄存器<DR>DR用于寄存数据,与指令寄存器寄存指令相对应,当D/I=1时在下降沿作用下,图形显示数据写入DR,或在E信号高电平作用下,由DR读到DB7~DB0数据总线,DR和DDRAM之间的数据传输是模块内部自动执行的。3忙标志BFBF标志提供内部工作情况,BF=1表示模块在内部操作,此时模块不接受外部指令和数据;BF=0时模块为准备状态,随时可接受外部指令和数据。利用STATUSREAD指令可以将BF读到数据总线从而检验模块之工作状态。4显示控制触发器DFF用于模块屏幕显示开和关的控制,DFF=1为开显示,DDRAM的内容就显示在屏幕上;DFF=0为关显示。DDF的状态是指令DISPLAYON/OFF和RST信号控制的。5XY地址计数器XY地址计数器是一个9位计数器高,3位是X地址计数器,低6位为Y地址计数器。XY地址计数器实际上是作为DDRAM的地址指针,X地址计数器为DDRAM的页指针,Y地址计数器为DDRAM的Y地址指针。X地址计数器没有记数功能,只能用指令设置。Y地址计数器具有循环记数功能,各显示数据写入后Y地址自动加1,Y地址指针从0到63。6显示数据RAMDDRAMDDRAM是存储图形显示数据的,数据为1表示显示选择,数据为0表示显示非选择。7Z地址计数器Z地址计数器是一个6位计数器,此计数器具备循环记数功能,用于显示行扫描同步,当一行扫描完成此地址计数器自动加1,指向下一行扫描数据,RST复位后Z地址计数器为0。Z地址计数器可以用指令DISPLAYSTARTLINE预置,因此显示屏幕的起始行就由此指令控制,即DDRAM的数据从哪一行开始显示在屏幕的第一行,此模块的DDRAM共64行,屏幕可以循环滚动显示64行。3.模块的外部接口外部接口信号如下表所示管脚号管脚名称LEVER管脚功能描述1VSS0电源地2VDD5.0V电源电压3V05.0V-13V液晶显示器驱动电压4D/IH/LD/I=H表示DB7~DB0为显示数据D/I=L表示DB7~DB0为显示指令数据5R/WH/LR/W=HE=H数据被读到DB7~DB0R/W=LE=HL数据被写到IR或DR6EH/LR/W=LE信号下降沿锁存DB7~DB0R/W=HE=HDDRAM数据读到DB7~DB07DB0H/L数据线8DB1H/L数据线9DB2H/L数据线10DB3H/L数据线11DB4H/L数据线12DB5H/L数据线13DB6H/L数据线14DB7H/L数据线15CS1H/LH:选择芯片<右半屏>信号16CS2H/LH:选择芯片<左半屏>信号17RETH/L复位信号,低电平复位18VEE-10VLCD驱动负电压19ELAC背光板电源20ELAC背光板电源4.指令说明指令表:指令指令码功能R/WD/ID7D6D5D4D3D2D1D0显示ON/OFF0000111111/0控制显示器的开关不影响DDRAM中数据和内部状态显示起始行0011显示起始行063指定显示屏从DDRAM中哪一行开始显示数据设置X地址0010111X07设置DDRAM中的页地址〔X地址设置Y地址0001Y地址063设置地址〔Y地址读状态10BUSY0ON/OFFRST0000读取状态RES1:复位0:正常ON/OFF1:显示开0:显示关BUSY0:READY1:INOPERATION写显示数据01显示数据将数据线上的数据DB7DB0写入DDRAM读显示数据11显示数据将DDRAM上的数据读入线数据DB7DB01显示开关控制<DISPLAYON/OFF>代码R/WD/IDB7DB6DB5DB4DB3DB2DB1DB0形式000011111DD=1:开显示<DISPLAYON>意即显示器可以进行各种显示操作D=0:关显示<DISPLAYOFF>意即不能对显示器可以进行各种显示操作2设置显示起始行代码R/WD/IDB7DB6DB5DB4DB3DB2DB1DB0形式0011A5A4A3A2A1A0显示起始行是由Z地址计数器控制的,A5~A0的6位地址自动送入Z地址计数器起始行的地址可以是0~63的任意一行。例如选择A5~A0是62则起始行与DDRAM行的对应关系如下DDRAM行62630123……2829屏幕显示行123456……31323设置页地址代码R/WD/IDB7DB6DB5DB4DB3DB2DB1DB0形式0010111A2A1A0所谓页地址就是DDRAM的行地址,8行为一页,模块共64行即8页,A2~A0表示0~7页读写数据对地址没有影响,页地址由本指令或RST信号改变复位后页地址为0,页地址与DDRAM的对应关系见DDRAM地址表:4设置Y地址<SETYADDRESS>代码R/WD/IDB7DB6DB5DB4DB3DB2DB1DB0形式0001A5A4A3A2A1A0此指令的作用是将A5~A0送入Y地址计数器,作为DDRAM的Y地址指针,在对DDRAM进行读写操作后,Y地址指针自动加1,指向下一个DDRAM单元。DDRAM地址表:5读状态<STATUSREAD>代码R/WD/IDB7DB6DB5DB4DB3DB2DB1DB0形式00BUSY0ON/OFFRETA3A2A1A0当R/W=1D/I=0时,在E信号为H的作用下,状态分别输出到数据总线DB7~DB0的相应位。ON/OFF表示DFF触发器的状态。RSTRST=1表示内部正在初始化,此时组件不接受任何指令和数据。6写显示数据<WRITEDISPLAYDATE>代码R/WD/IDB7DB6DB5DB4DB3DB2DB1DB0形式01D7D6D5D4D3D2D1D0D7~D0为显示数据,此指令把D7~D0写入相应的DDRAM单元,Y地指针自动加1。7读显示数据<READDISPLAYDATE>代码R/WD/IDB7DB6DB5DB4DB3DB2DB1DB0形式11D7D6D5D4D3D2D1D0此指令把DDRAM的内容D7~D0读到数据总线DB7~DB0,Y地址指针自动加1。B.核心电路设计 SG12864内置数字芯片控制器,可以直接和单片机I/O口进行对接,在这里不作介绍。C.模块电路图3.9外围驱动模块A.模块电路设计 本模块电路是用来控制打铃和教室灯光。而课铃和灯光都是由220V交流电驱动,这对单片机有很强的干扰。因此在设计时必需考滤到电气隔离的问题,在这里我们采用光电耦合器进行电气隔离,再用继电器来达到弱电控制强电的目的。 而刚凭单片机的I/O口是无法驱动光电耦合器的,因些要对单片机引脚信号进行放大,在这里我们采用一个三极管8550进行放大,而为了提高抗噪能力和保护三极管需在三极管基极加一电阻,我们这里取10K。在发射极的需加一限流电阻,取值1K,为更好的保护元器件在电源端并上一滤波电容,取值0.1uF。 继电器线圈具有储能作用,当断电时由于电磁感应会产生一个很高的反电热,为此两端需加一回路来消除反电势。在这里是直流电路所以只需在线圈两端加一续流二极管。在这里还是用三极管进行驱动,取限流电阻R19为100。前偏置电阻R17为1K,后偏置电阻为10K。B.模块电路图四、单片机系统设计4.1系统实现工作流程 本系统采用PCF8563计时并产生日期、星期、时间数据,当单片机上电复位时,首先初始化单片机内部资源,开中断、初始化定时器和全局变量、设置外部中断触发方式,然后对PCF8563进行初始化让其在精确计时模式下运行并在每一分钟产生一个中断信号,接下来就由单片机对PCF8563产生的日期、时间数据进行读取,将读取到的数据和存储器E2PROM中的数据进行比较,判断当前日期是否是在假期内,如果在假期内那就关掉外部中断0,也就屏蔽掉教室灯光、打铃和广播。然后就进入主循环,在循环内首先对窗口计数字节进行判断,然后根据相应的窗口计数值进行相应窗口的显示〔如时间界面、主菜单界面、时间调整界面、打铃设置界面,接下来对校门控制标志位进行判定,如果控制标志位为1则启动电机,当电机转动的弧长达到预设值,则关闭电机,同时置电机状态标志位〔表示校门已经是打开状态,并启动定时器0,当定时器计时达到15S时则又启动电机,但此次电机为反转〔也就是校门开始关闭。校门的控制标志位的修改则是由外部中断1来控制的,当有人或物体靠近校门时,人或物体就会挡住红外发射管发射的载波,红外接收管就会产生一低电平,从而引发单片机的外部中断1,从而置位控制标志位,从而启动电机就达到校门自动开关的效果,而当有人或物体经过到校门的打开只需要微秒级的时间,已远远能满足控制需求。而本设计中的温度传感器模块则是,使用数字接口芯片DS18B20单片机可以直接向其读取温度数据,再经转换就能实现温度的实时显示,且DS18B20的精度可达0.0625℃。4.2系统流程图A.主程序流程图B.外部中断0流程图C.外部中断1流程图4.3系统源程序#include<reg52.h>#include<intrins.h>#include"code_number.h"//#include"I2c.h"//#include"DS18B20.H"//#include"Main.h"#defineucharunsignedchar#defineuintunsignedint#defineDISP_ON0x3f#defineDISP_OFF0x3e#defineCOL_ADD0x40#definePAGE_ADD0xb8 //8:星期;20:月份;40以上:小时、月份、日期#defineSTART_LINE0xc0#definePCF8563_Start0x00#definePCF8563_Stop0x20#definePCF8563Time_Ineffect0x83#definePCF8563Time_UnIneffect0x03sbitHD7279_Key=P1^4;sbitHD7279_Clk=P1^5;sbitHD7279_Dat=P1^6;sbitHD7279_CS=P1^7;sbitLED_CONTROL=P3^5;sbitJOW_CONTROL=P2^5;sbitTELEVISE_CONTROL=P2^5;sbitSG12864_CS1=P2^4;sbitSG12864_CS2=P2^3;sbitSG12864_E=P2^2;sbitSG12864_RW=P2^1;sbitSG12864_DI=P2^0;sbitSDA=P3^7;/*模拟I2C数据传送位*/sbitSCL=P3^6;/*模拟I2C时钟控制位*/sbitMotorStepper_A=P1^0;sbitMotorStepper_B=P1^1;sbitMotorStepper_C=P1^2;sbitMotorStepper_D=P1^3;ucharcodeMotorStepper_Data[]={0x0e,0x0c,0x0d,0x09,0x0b,0x03,0x07,0x06};bitack;/*应答标志位*/uchardataDisp_Count1,Disp_Count2,Temperature[2];ucharWindow_Count,Page_Count,TimeRevision_Count,JowRevision_Count,Help_Byte[7];ucharTime_Count,Time_Sec,MotorStepper_Count;bitMotorStepper_Start,MotorStepper_State,MotorStepper_Sign;sbitDQ=P3^4;bitDS18B20_Bit; //用来检查是否存在DS18B20存在置1否则清零/*******************************************************************延时函数延时为11+7*zus函数原型:voidDS18B20_delay<ucharz>功能: 用来响应DS18B20时序********************************************************************/voidDS18B20_delay<ucharz> { while<z-->; }/*******************************************************************DS18B20初始化函数函数原型:DS18B20_Init<>功能: 对DS18B20进行复位,如果复位成功则置DS18B20_Bit,否则则清零DS18B20_Bit.********************************************************************/voidDS18B20_Init<>{ uchari; DQ=1; _nop_<>; DQ=0; DS18B20_delay<75>; DQ=1; _nop_<>;_nop_<>;_nop_<>; i=8; while<i--> { if<!DQ> break; } if<i!=65535> { DS18B20_Bit=1; DS18B20_delay<31>; DQ=1; } else { DQ=1; DS18B20_Bit=0; }}/*******************************************************************DS18B20字节写函数函数原型:Write_DS18B20<uchardat>功能: 向DS18B20写入字节数据********************************************************************/voidDS18B20_Write<uchardat>{ uchari; bitk; for<i=0;i<8;i++> //一个字节八位,从低位开始发送 { k=0x01&dat; //判断最低位是否为1,用来发送 DQ=0; DS18B20_delay<1>; DQ=k; DS18B20_delay<6>; DQ=1; _nop_<>; dat>>=1; //发送数据右移一位 } DQ=1;}/*******************************************************************DS18B20双字节读取函数函数原型:Read_Temperature功能:向DS18B20读取双字节数据********************************************************************/voidDS18B20_Read<>{ uchari,j; for<i=0;i<2;i++> { for<j=0;j<8;j++> { Temperature[i]>>=1; DQ=1; _nop_<>;_nop_<>; DQ=0; _nop_<>;_nop_<>;_nop_<>; DQ=1; DS18B20_delay<1>; if<DQ> { Temperature[i]=Temperature[i]|0x80; } DS18B20_delay<6>; } }}/*******************************************************************DS18B20温度读取函数函数原型:Get_Temperature<>功能:启动温度转换并读取温度,温度存储在temperature中********************************************************************/voidGet_Temperature<>{ DQ=1; DS18B20_Init<>; if<DS18B20_Bit> { DS18B20_Write<0xcc>; DS18B20_Write<0x44>; DS18B20_delay<200>; DS18B20_Init<>; DS18B20_Write<0xcc>; DS18B20_Write<0xbe>; DS18B20_Read<>; }}/*******************************************************************总线延时函数函数原型:voidDelay_5us<>功能:响应I2c时序********************************************************************/voidDelay_5us<>{ _nop_<>;_nop_<>; _nop_<>;_nop_<>;}/*******************************************************************起动总线函数函数原型:voidStart_I2c<>;功能:启动I2C总线,即发送I2C起始条件.********************************************************************/voidStart_I2c<>{SDA=1;/*发送起始条件的数据信号*/_nop_<>;SCL=1;Delay_5us<>;/*起始条件建立时间大于4.7us,延时*/SDA=0;/*发送起始信号*/Delay_5us<>;/*起始条件锁定时间大于4μs*/SCL=0;/*钳住I2C总线,准备发送或接收数据*/Delay_5us<>;}/*******************************************************************结束总线函数函数原型:voidStop_I2c<>;功能:结束I2C总线,即发送I2C结束条件.********************************************************************/voidStop_I2c<>{SDA=0;/*发送结束条件的数据信号*/_nop_<>;/*发送结束条件的时钟信号*/SCL=1;/*结束条件建立时间大于4us*/Delay_5us<>;SDA=1;/*发送I2C总线结束信号*/Delay_5us<>;}/*******************************************************************字节数据发送函数函数原型:voidSendByte<ucharc>;功能:将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.<不应答或非应答都使ack=0>发送数据正常,ack=1;ack=0表示被控器无应答或损坏。********************************************************************/voidSendByte<ucharc>{ucharBitCnt;for<BitCnt=0;BitCnt<8;BitCnt++>/*要传送的数据长度为8位*/{if<<c<<BitCnt>&0x80>SDA=1;/*判断发送位*/elseSDA=0;Delay_5us<>;SCL=1;/*置时钟线为高,通知被控器开始接收数据位*/Delay_5us<>;/*保证时钟高电平周期大于4μs*/SCL=0;}Delay_5us<>;SDA=1;/*8位发送完后释放数据线,准备接收应答位*/Delay_5us<>;SCL=1;Delay_5us<>;if<SDA==1>ack=0;elseack=1;/*判断是否接收到应答信号,由从机返回*/SCL=0;Delay_5us<>;}/*******************************************************************字节数据接收函数函数原型:ucharRcvByte<>;功能:用来接收从器件传来的数据,并判断总线错误<不发应答信号>,发完后请用应答函数应答从机。********************************************************************/ucharRcvByte<>{ucharretc;ucharBitCnt;retc=0;SDA=1;/*置数据线为输入方式*/for<BitCnt=0;BitCnt<8;BitCnt++>{Delay_5us<>;SCL=0;/*置时钟线为低,准备接收数据位*/Delay_5us<>;/*时钟低电平周期大于4.7μs*/SCL=1;/*置时钟线为高使数据线上数据有效*/Delay_5us<>;retc=retc<<1;if<SDA==1>retc=retc+1;/*读数据位,接收的数据位放入retc中*/}SCL=0;Delay_5us<>;return<retc>;}/********************************************************************应答子函数<用于主机读取数据后,应答从机>函数原型:voidAck_I2c<bita>;功能:主控器进行应答信号<可以是应答或非应答信号,由位参数a决定>********************************************************************/voidAck_I2c<bita>{if<a==0>SDA=0;/*在此发出应答或非应答信号*/elseSDA=1;Delay_5us<>;SCL=1;Delay_5us<>;/*时钟低电平周期大于4μs*/SCL=0;/*清时钟线,钳住I2C总线以便继续接收*/Delay_5us<>;}/*******************************************************************向有子地址器件发送多字节数据函数函数原型:bitISendStr<ucharsla,ucharsuba,ucahr*s,ucharno>;功能:从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。如果返回1表示操作成功,否则操作有误。注意:使用前必须已结束总线。********************************************************************/bitISendStr<ucharsla,ucharsuba,uchar*s,ucharno>{uchari;Start_I2c<>;/*启动总线*/SendByte<sla>;/*发送器件地址*/if<ack==0>return<0>;SendByte<suba>;/*发送器件子地址*/if<ack==0>return<0>;for<i=0;i<no;i++>{SendByte<*s>;/*发送数据*/if<ack==0>return<0>;//检测从机发送过来的应答位,ack由sendbyte函数返回s++;}Stop_I2c<>;/*结束总线*/return<1>;}/*******************************************************************向有子地址器件读取多字节数据函数函数原型:bitIRcvStr<ucharsla,ucharsuba,ucahr*s,ucharno>;功能:从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。如果返回1表示操作成功,否则操作有误。注意:使用前必须已结束总线。********************************************************************/bitIRcvStr<ucharsla,ucharsuba,uchar*s,ucharno>{uchari;Start_I2c<>;/*启动总线*/SendByte<sla>;/*发送器件地址*/if<ack==0>return<0>;SendByte<suba>;/*发送器件子地址*/if<ack==0>return<0>;Start_I2c<>;/*重新启动总线*/SendByte<sla+1>;if<ack==0>return<0>;for<i=0;i<no-1;i++>{*s=RcvByte<>;/*接收数据*/Ack_I2c<0>;/*读完一个数据,就发送一个应答位*/s++;}*s=RcvByte<>;Ack_I2c<1>;/*全部读完,发送非应位*/Stop_I2c<>;/*结束总线*/return<1>;}//*************************************延时函数*****************************************//voidSG12864_Delay<uintz>{ uintx,y; for<x=z;x>0;x--> for<y=10;y>0;y-->;}//**************************************com_write***************************************//voidSG12864_CMDWrite<ucharw_cmd> { SG12864_RW=0; SG12864_DI=0; P0=w_cmd; SG12864_Delay<0>; SG12864_E=1; SG12864_Delay<0>; SG12864_E=0; }//*************************************data_write***************************************//voidSG12864_DATWrite<ucharw_data> { SG12864_RW=0; SG12864_DI=1; P0=w_data; SG12864_Delay<0>; SG12864_E=1; SG12864_Delay<0>; SG12864_E=0; }//*************************************lcd16*16填充*************************************//voidSG12864_16Pad<ucharpad_data,ucharrow,ucharline>{ uchark; SG12864_CMDWrite<PAGE_ADD+<line<<1>>; SG12864_CMDWrite<COL_ADD+

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论