• 668.50 KB
  • 2022-04-22 13:32:57 发布

设计主要元器定时开关插座毕业论文.doc

  • 46页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'设计主要元器定时开关插座毕业论文目录引言11设计要求及构思21.1设计要求21.2设计构思22设计方案分析确定32.1系统框图32.2开关的选择32.3显示方式选择42.4时钟的实现及单片机的选择42.5电源部分的选择42.6按键控制部分的实现53主要元器件原理及其应用53.1继电器介绍53.1.1继电器的继电特性53.1.2继电器工作原理及特性63.1.3继电器主要产品技术参数73.1.4继电器的选用73.2单片机AT89S52介绍83.3液晶LCD12232介绍94系统硬件电路设计104.1电源电路104.2单片机最小系统及液晶显示124.3继电器驱动电路134.4键盘电路145系统软件程序设计155.1主程序的设计165.2时钟程序设计175.3时钟设置及定时设置程序设计186系统软硬件的制作与调试196.1硬件的制作196.2调试方案196.3硬件电路调试196.3.1独立元件的检测196.3.2电源电路的调试206.3.3单片机最小系统的调试206.3.4显示模块的调试206.3.5键盘模块的调试20 6.3.6继电器电路的调试216.4软件调试216.5整体系统调试217结论23谢辞24参考文献25附录126附录228附录345 引言现如今,往往由于某些特殊原因给我们的生活或工作带来一些困扰和遗憾。比如:家中的水塔忘记抽水而造成生活的一时不便;学校的起床广播因值班人员睡过头而推迟广播;家中的鱼缸因太久没有供氧造成鱼儿缺氧死亡;许多球迷或者新闻爱好者因为错过了开机时间而与精彩球赛或者新闻擦肩而过;夏天里风扇的定时时间过短(一般为1个小时),不便于晚上分段定时使用等等。而上面的这些问题都可以通过定时开关插座的定时功能得到解决。随着电器产品待机能耗的迅速增长,家庭和社会付出了太多的代价,中国节能认证中心对家庭待机能耗做过的调查显示,待机能耗占到家庭电力消耗的10%左右,仅以电视机为例,平均每台电视机的待机能耗是8.07W,按每天待机2小时大约耗电0.016度。定时开关插座能够实现定时给电器供电,在工作时间之外把电器的电源切断,这样就能解决电器的待机损耗,达到节约用电的目的。定时开关插座是一款能在特定时间段内控制电器通、断电的开关插座。能实现24小时制和100小时制两种时钟走时模式,在24小时制时钟模式,可以实现6组24小时内的任意定时,定时时间范围最小为1分钟;在100小时制时钟模式,可以实现6组100小时内的任意定时,定时时间范围最小也是1分钟。本文阐述了定时开关插座的硬件电路设计、软件算法设计,给出了自动开关插座的设计和定型方案,它可以对家中一些需要在特定时间对电器进行自动断、通电控制,而不需要拔掉插头,减少电器的待机损耗,解决生活中的一些烦恼。1设计要求及构思1.1设计要求本次设计要求实现一个具有定时、按键设置及控制、定时时间显示等功能的定时开关插座,具体要求及指标如下:(1)可以设定三组定时时间值。 (2)设定的定时时间调整范围为:0~99分钟。(3)具有开始/停止操作按键。(4)具有定时时间显示和时钟显示。1.2设计构思根据题目和设计功能要求,系统的实施方案可以分为以下几个步骤:首先,通过模式(模式0为24小时制,模式1为100小时制)选定时钟的走时方式,作为定时时间的判断标准。然后通过按键设置定时时间分别存储在定时开始数组begin和结束数组end,通过数组的值与时钟的值进行比较,时间在定时数组时间范围内则继电器接通,否则断开。用一个红色发光二极管的亮、灭来指示继电器的通、断的状态。定时开关插座的显示则用数码管来实现。电源部分用220V转换为直流5V给定时开关系统供电,并用干电池做储备电源,防止220V交流电断电了单片机控制部分就停止工作,失去作用。用4*3键盘实现时钟、定时的设置及开始/停止等按键设置功能。鉴于以上的构思,定时开关可以实现功能扩展,具体实现的功能指标如下:(1)可以设定六组定时时间值。(2)设定的定时时间调整范围分为两种情况:①模式0状态时可设定的定时时间调整范围为:0~24小时;②模式1状态时可设定的定时时间调整范围为:0~100小时。(3)具有开始/停止操作按键。(4)具有定时时间显示和时钟显示,具有显示模式、显示目前定时组别、定时时间设置等功能。(5)在220V交流电断电的情况下,干电池仍能保证单片机的定时状态及时钟走时正常工作;待交流电通电后干电池停止供电,转换为220V交流电转为5V直流电供电。2设计方案分析确定2.2开关的选择现代自动控制设备中,都存在一个电子电路——电气电路的互相连接的问题,一方面要是电子电路的控制信号能够控制电气电路的执行元件(电动机、电灯、热水器等),另一方面又要为电子线路的电器电路提供良好的电隔离,以保护电子电路和人身的安全。电子继电器和光耦合器便能起到这一桥梁的作用。下面简要介绍各个方案的特点。方案一:采用继电器作为控制220V通、断的开关。固态继电器(SSR)与机电继电器相比,是一种没有机械运动,不含运动零件的继电器,但它具有与机电继电器本质上相同的功能。SSR是一种全部由固态电子元件组成的无触点开关元件,他利用电子元器件的点,磁和光特性来完成输入与输出的可靠隔离,利用大功率三极管,功率场效应管,单项可控硅和双向可控硅等器件的开关特性,来达到无触点,无火花地接通和断开被控电路。选用SRD-05VCD-SL-C继电器最大电路可达到10A ,即继电器的正常工作范围为0到2200瓦,可以给大部分家用电器供电。2.3显示方式选择在模拟电子和数字电子中,常用显示数据的有数码管和液晶显示器。方案一:采用LED数码管显示。虽然功耗低,控制简单,但却只能显示数字和一些简单的字符,而且显示信息少,需要较多位的数码管,占用了较多的单片机I/O口,没有较好的人机界面。2.4时钟的实现及单片机的选择时钟的实现可已通过使用时钟芯片或者单片机的定时器实现。下面简要介绍几种方案的特点。单片机仅用于控制继电器、键盘,实现时钟和定时,用51结构的有Atmel的AT89CXX系列、AT89SXX系列、AT89C20系列(20引脚)或STC的所有单片机都可以实现。根据在学校比较流行的学习单片机是AT89SXX系列,而且AT89S52单片机便宜,购买方便,故单片机选用AT89S52单片机。方案一:时钟通过使用时钟芯片来实现,控制部分通过使用单片机来实现。时钟芯片种类非常多,有内置晶振及充电电池的,也有外置晶振的,现在流行的时钟芯片有DS1302、DS1307、PCF8485、SB2068等。使用时钟芯片可以得到准确的时钟走时,可用简单的程序实现定时开关插座的定时功能。方案二:时钟通过单片机的内部定时器来实现时钟。单片机的内部定时器可实现较为精确的时钟走时,定时50毫秒的误差率极小,可达到定时开关插座的使用要求。使用单片机内部定时器可简化硬件电路,可以节省开支,但是编程的难度有所提高。本次设计的时钟走时用单片机定时器已经可以完全达到定时开关插座的使用要求,并可省去时钟芯片,节省开支。考虑到软件的难度增加可换来更好的性价比,所以选用方案二。2.5电源部分的选择电源给单片机及继电器等使用5V直流电的器件提供电源,供系统正常工作。使用交流电和干电池混合给系统供电。在交流电不失效的情况下由交流电转5V直流电供电,在交流电失效情况下由干电池供电。这样就能解决运行成本过高或者在交流电失效时丢失原先设置数据的问题。本方案对本设计最为合适。综上所述,考虑到成本、实用性等问题,对定时开关插座系统供电方案四是最为合适的。2.6按键控制部分的实现时钟时间和定时时间的设置功能可以通过按键来实现。按键的实现可以通过以下两种方案实现:使用矩阵键盘实现。矩阵键盘可以用较少的I/O口实现多个按键功能,能节省更多的I/O口,利于系统扩展功能。根据本定时开关插座的设置要求,要用到12 个按键。通过两个方案的对比,方案二的实施办法更符合要求。3主要元器件原理及其应用本次设计中主要器件有继电器、51系列单片机AT89S52、数码管、5V稳压芯片7805,在介绍系统的硬件设计之前,下面先简要介绍一下这些关键器件的原理及应用。3.1继电器介绍继电器是一种电子控制器件,它具有控制系统(又称输入回路)和被控制系统(又称输出回路),通常应用于自动控制电路中,它实际上是用较小的电流去控制较大电流的一种“自动开关”。故在电路中起着自动调节、安全保护、转换电路等作用。3.1.1继电器的继电特性继电器的输入信号x从0连续增加达到衔铁开始吸合时的动作值xx,继电器的输出信号立刻继续增大,输出信号y将不再起变化。当输入量x从某一大于xx值下降到xf,继电器开始释放,常开触点断开。我们把继电器的这种特性叫做继电特性,也叫继电器的输入-输出特性。释放值xf与动作值xx的比值叫做反馈系数,即Kf=xf/xx。触点上输出的控制功率Pc与线圈吸收的最小功率P0之比叫做继电器的控制系数,即Kc=Pc/P0。3.1.2继电器工作原理及特性(1)电磁继电器的工作原理和特性电磁式继电器一般由铁芯、线圈、衔铁、触点簧片等组成的。只要在线圈两端加上一定的电压,线圈中就会流过一定的电流,从而产生电磁效应,衔铁就会在电磁力吸引的作用下克服返回弹簧的拉力吸向铁芯,从而带动衔铁的动触点与静触点(常开触点)吸合。当线圈断电后,电磁的吸力也随之消失,衔铁就会在弹簧的反作用力返回原来的位置,使动触点与原来的静触点(常闭触点)释放。这样吸合、释放,从而达到了在电路中的导通、切断的目的。对于继电器的“常开、常闭”触点,可以这样来区分:继电器线圈未通电时处于断开状态的静触点,称为“常开触点”;处于接通状态的静触点称为“常闭触点”。(2)热敏干簧继电器的工作原理和特性热敏干簧继电器是一种利用热敏磁性材料检测和控制温度的新型热敏开关。它由感温磁环、恒磁环、干簧管、导热安装片、塑料衬底及其他一些附件组成。热敏干簧继电器不用线圈励磁,而由恒磁环产生的磁力驱动开关动作。恒磁环能否向干簧管提供磁力是由感温磁环的温控特性决定的。(3)固态继电器(SSR)的工作原理和特性固态继电器是一种两个接线端为输入端,另外两个接线端为输出端的四端器件,中间采用隔离器件实现输入输出的电隔离。固态继电器按负载 电源类型可分为交流型和直流型。按开关型式可分为常开型和常闭型。按隔离型式可分为混合型、变压器隔离型和光电隔离型,其中以光电隔离型最多。(4)磁簧继电器磁簧继电器是以线圈产生磁场将磁簧管发生动作的继电器,为一种线圈传感装置。因此磁簧继电器具有尺寸小、轻量、反应速度快、短跳动时间等特性。当整块铁磁金属或者其它导磁物质与之靠近的时候发生动作,开通或者闭合电路。由永久磁铁和干簧管组成。永久磁铁、干簧管固定在一个不导磁也不带有磁性的支架上。以永久磁铁的南北极的连线为轴线,这个轴线应该与干簧管的轴线重合或者基本重合。由远及近的调整永久磁铁与干簧管之间的距离,当干簧管刚好发生动作(对于常开的干簧管,变为闭合;对于常闭的干簧管,变为断开)时,将磁铁的位置固定下来。这时,当有整块导磁材料,例如铁板同时靠近磁铁和干簧管时,干簧管会再次发生动作,恢复到没有磁场作用时的状态;当该铁板离开时,干簧管即发生相反方向的动作。磁簧继电器结构坚固,触点为密封状态,耐用性高,可以作为机械设备的位置限制开关,也可以用以探测铁制门、窗等是否在指定位置。(5)光继电器光继电器为AC/DC并用的半导体继电器,是发光器件和受光器件一体化的器件。输入侧和输出侧电气性绝缘,但信号可以通过光信号传输。其特点为寿命为半永久性、微小电流驱动信号、高阻抗绝缘耐压、超小型、光传输、无接点等。主要应用于量测设备、通信设备、保全设备、医疗设备等。3.1.3继电器主要产品技术参数(1)额定工作电压额定工作电压是指继电器正常工作时线圈所需要的电压,也就是控制电路的控制电压,根据继电器的型号不同,可以是交流电压,也可以是直流电压。(2)直流电阻直流电阻是指继电器中线圈的直流电阻,可以通过万能表测量。(3)吸合电流吸合电流是指继电器能够产生吸合动作的最小电流。在正常使用时,给定的电流必须略大于吸合电流,这样继电器才能稳定地工作。而对于线圈所加的工作电压,一般不要超过额定工作电压的1.5倍,否则会产生较大的电流而把线圈烧毁。(4)释放电流释放电流是指继电器产生释放动作的最大电流。当继电器吸合状态的电流减小到一定程度时,继电器就会恢复到未通电的释放状态。这时的电流远远小于吸合电流。(5)触点切换电压和电流触点切换电压和电流是指继电器允许加载的电压和电流。它决定了继电器能控制电压和电流的大小,使用时不能超过此值,否则很容易损坏继电器的触点。 3.1.4继电器的选用(1)先了解必要的条件①控制电路的电源电压,能提供的最大电流;②被控制电路中的电压和电流;③被控电路需要几组、什么形式的触点。选用继电器时,一般控制电路的电源电压可作为选用的依据。控制电路应能给继电器提供足够的工作电流,否则继电器吸合是不稳定的。(2)查阅有关资料确定使用条件后,可查找相关资料,找出需要的继电器的型号和规格号。若手头已有继电器,可依据资料核对是否可以利用。最后考虑尺寸是否合适。(3)注意器具的容积。若是用于一般用电器,除考虑机箱容积外,小型继电器主要考虑电路板安装布局。对于小型电器,如玩具、遥控装置则应选用超小型继电器产品。通过上面的性能了解和比较,及考虑的器件的性价比,本设计选择电磁继电器。3.2单片机AT89S52介绍AT89S52单片机片内集成256字节程序运行空间、8K字节Flash存储空间,支持最大64K外部存储扩展。根据不同的运行速度和功耗的要求,时钟频率可以设置在0~33M之间。片内资源有4组I/O控制端口、3个定时器、8个中断、软件设置低能耗模式、看门狗和断电保护。可以在4V到5.5V宽电压范围内正常工作。不断发展的半导体工艺也让该单片机的功耗不断降低。同时,该单片机支持计算机并口下载,简单的数字芯片就可以制成下载线。根据不同场合的要求,这款单片机提供了多种封装,本次设计根据最小系统有时需要更换单片机的具体情况,使用双列直插DIP-40的封装,如图3.1所示。下面对定时开关系统中使用到的管脚进行简单说明。图3.1DIP-40封装89S52引脚图P0口:P0口是一个8位漏极开路的双向I/O口。作为输出口,每位能驱动8个TTL逻辑电平。对P0端口写“1” 时,引脚用作高阻抗输入。当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。在这种模式下,P0不具有内部上拉电阻。P1口:P1口是一个具有内部上拉电阻的8位双向I/O口,P1输出缓冲器能驱动4个TTL逻辑电平。对P1端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。P2口:P2口是一个具有内部上拉电阻的8位双向I/O口,P2输出缓冲器能驱动4个TTL逻辑电平。对P2端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。P3口:P3口是一个具有内部上拉电阻的8位双向I/O口,P3输出缓冲器能驱动4个TTL逻辑电平。对P3端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。RST——复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将是单片机复位。3.3液晶LCD12232介绍现在的字符型液晶模块已经是单片机应用设计中最常用的信息显示器件了。12232型LCD显示模块具有体积小、功耗低、显示内容丰富、价格便宜、性价比高等特点。下面介绍LCD12232的管脚功能、工作参数、电气特性。LCD12232的引脚说明见表3.1。表3.1液晶12232引脚说明PCB板引脚号12232/112232/212232/31VDDVSS同12232-1引脚2GNDVDD3VLCDV04RETA05CS1CS16CS2CS27R/WCL(外振时钟)8A0/RD9D0/WR10D1D011D2D112D3D2同12232-1引脚13D4D314D5D4 15D6D516D7D617背光D718背光res19背光20背光VDD:逻辑电源正GND(VSS):逻辑电源地VLCD(VEE,V0):LCD驱动电源RET:复位端,对于68系列MPU:上升沿(L-H)复位,且复位后电平须保持为高电平(H);对于80系列MPU:下降沿(H-L)复位,且复位后电平须保持为低电平(L)。CS1:读写使能。对于68系列MPU,连接使能信号引脚,高电平有效;对于80系列MPU,连接/RD引脚,低电平有效。CS2:同E1引脚。/RD:读允许,低电平有效。/WR:写允许,低电平有效。R/W:读写选择,对于68系列MPU,高电平时读数据,低电平时写数据;对于80系列MPU,低电平时允许数据传输,上升沿时锁定数据。A0:数据/指令选择。高电平:数据D0-D7将送入显示RAM;低电平:数据D0-D7将送入指令执行器执行。D0-D7:数据输入输出引脚。工作参数(1)逻辑工作电压:2.4~6.0V(2)LCD驱动电压:3.0~13.5V(3)工作温度:0~55℃(常温)/-20~70℃(宽温)(4)保存温度:-10~70℃电气特性(1)输入高电平:3.5Vmin(2)输入低电平:0.55Vmax(3)输出高电平:3.75Vmin(4)输出低电平:1.0Vmax(5)工作电流:2.0mAmax4系统硬件电路设计 整个系统的硬件设计可以分为四个模块:电源电路、单片机最小系统及液晶显示、继电器工作电路、键盘电路。电源电路为整个系统供电,包括单片机AT89S52、继电器、键盘、LCD12232及其他外围电路。电源电路分两个部分:(1)由220V交流电经变压器和7805稳压电路转为5V直流电给系统供电;(2)由4节干电池作为储备电源,在交流电失效时给系统供电,以确保单片机的正常运行。在电源电路给系统供电时,绿色指示灯点亮,只是当前供电正常。单片机最小系统部分是整个系统的智能控制部分,也是整个系统的核心部分。单片机在实现时钟的同时,也负责键盘检测,驱动液晶显示,实现定时功能,并负责控制继电器的通、断,红色指示灯的亮、灭指示继电器的通、断状态。液晶在单片机的控制下显示时钟、定时组别及定时时间的信息。继电器在单片机的控制下实现通、断,从而达到控制插座通、断电的目的。4.1电源电路整个系统的供电电源如图4.2所示。系统要提供稳定的直流5V供单片机及其所控制的外围电路(包括液晶、键盘、继电器等)和提供220交流电给插座。在电源的设计中,用220V交流电经过变压器降压后经7805稳压后给单片机控制系统供电。7805三端稳压集成芯片有很多种型号,但是标称最大输出电流均为1.5A,在实际应用中,该最大输出电流往往取决于两个方面:(1)足够大的散热面积;(2)在设计中,必须保证7805的输入电压Vi和输出电压Vo的压差大于2.5V,即Vi-Vo>=2.5V,否则会失去稳压能力。同时单片机控制系统还用6V干电池作为储备电源,当交流电源失电或者失效时,电压为6V的直流电源通过二极管投入作用,硅二极管的导通压降约为0.2V,因袭满足系统的电源要求。P25接的是经5W变压器降压后的交流电。D33二极管起到保护电路的作用。发光二级DS11是指示电源是否有电压输出。Header2所接的是(由干电池提供)6V直流电的输入接口,2接正,1接负。X78xx系列是三端正电源稳压电路,它的封装形式为TO-220。它有一系列的稳固电压输出,应用非常的广泛。每种类型由于内部电流的限制,以及过热保护和安全工作区的保护,使它基本上不会损坏。如果能够提供足够的散热片,它们就能够提供大于1.5A的输出电流。虽然是按照固定电压值来设计的,但是当接入适当的外部器件后,就能获得各种不同的电压和电流。7805使用时应该注意的事项:在实际应用中,应在三端集成稳压电路上安装足够大的散热器(当然小功率的条件下不用)。当稳压管温度过高时,稳压性能将变差,甚至损坏。当制作中需要一个能输出1.5A以上电流的稳压电源,通常采用几块三端稳压电路并联起来,是其中最大输出电流为N个1.5A,但应用时需要注意:并联使用的集成稳压电路应采用同一厂家、同一批号的产品,以保证参数的一致。另外在输出电流上留有一定的流量,以避免个别集成稳压电路失效时导致其他电路的连锁烧毁。7805稳压管如图4.1所示。 图4.17805稳压管管脚说明图4.2电源电路4.2单片机最小系统及液晶显示单片机控制电路是整个系统的核心,完成数据处理和控制任务。电路原理图如图4.3所示。本次设计采用的单片机的型号为AT89S52。单片机晶振为作用是为系统提供基本的时钟信号。通常一个系统共用一个晶振,便于各部分保持同步。有些通讯系统的基频和射频使用不同的晶振,而通过电子调整频率的方法保持同步。C1、C2叫负载电容。一般单片机的晶振工作于并联谐振状态,也可以理解为谐振电容的一部分。它是根据晶振厂家提供的晶振要求的 负载电容选值的,换句话说,晶振的频率就是在它提供的负载电容下测得的,能最大限度的保证频率值的误差。也能保证温漂等误差。两个电容的取值都是相同的,或者说相差不大,如果相差太大,容易造成谐振的不平衡,容易造成停振或者干脆不起振。P2是单片机的下载口,用于对单片机烧入程序。按键S及其外围电路是实现单片机的硬件复位功能。P5的管脚与液晶12232的管脚相对应(即作为液晶的底座)。LCD12232可以显示4行,所要显示的信息有:第一个行显示时钟的时(两位)、分(两位)、秒(两位),时、分、秒之间用“:”隔开。在时钟前面显示大写字母“T:0”,其中数字式从0到5可变的,显示的是当前定时的组别。第二行显示的是字母“begin:”,冒号后面显示的是当前定时开始的时(两位)、分(两位),时、分之间用“:”隔开。第三行显示的是字母“stop:”,冒号后面显示的是当前定时结束的时(两位)、分(两位),时、分之间用“:”隔开。第四行仅显示运行模式信息“mod:0”,数字部分可在0和1变化。图4.3单片机最小系统及液晶显示4.3继电器驱动电路继电器的驱动电路如图4.4所示。这是典型的继电器驱动电路。单片机是一个弱电器件,一般情况下它们大多工作在5V甚至更低。。驱动电流在mA级以下。而要把它用于一些大功率场合,比如继电器驱动,显然是不行的。所以就要有一个环节来衔接,这个环节就是所谓的“功率驱动”。继电器驱动就是一个典型的、简单的功率驱动环节。 图中三极管8050有两个作用:一个是起放大作用,一个是起开关作用(严格来讲开关作用是放大作用的极限情况)。P1处连接的是单片机的P2.7口。P2.7口给出高电平时,三极管处于导通状态,并起放大作用,这样,继电器就能得到足够的驱动电流来正常工作。当P2.7口给出低电平时,三极管不工作,继电器因没电流通过而不工作。二极管4148起到保护作用。发光二极管LED0用于指示继电器是处于导通状态(灯亮)还是处于断开状态(灯灭)。图4.4继电器驱动电路4.4键盘电路键盘电路如图4.5所示。使用矩阵键盘能用较少的I/O口实现较多的按键功能。下面为按键实现举例:假设按下的是B/S键进行如下检测(4*4键盘)先在P1口输出P100001111低四位行会有变化Cord_h=00001111&00001110=00001110if(!=00001111)延时20msCord_h=00001110&00001111=00001110if(!=00001111)P1再输出11111110P1=00001110|11110000=11111110输出高四位Cord_l=P1&0xf0//此时P1口就是输入值01111110而不是上面的11111110Cord_l=01111110&11110000=01110000Cord_h+cord_l=00001110+01110000=01111110=0x7e//此编码即为B/S的编码通过此方法,就可以计算出其他的键值,从而实现矩阵键盘的按键功能。 下面介绍个个按键实现的功能:B/S按键:用于实现继电器的开始、停止功能。Mone:用于实现模式1的时钟是循环走时还是走时到99:59:59后停止。T:定时一共有6组(0、1、2、3、4、5),每组分为开始和结束两个时间。通过按此按键能实现定时组别的选定。Mod:模式选择,可以实现时钟在24小时制和100小时制之间转换。Enter:在时钟设置或者定时设置时用于确定完成设置。Cancel:用于取消全部目前所设置好的定时组,即对定时做归零处理。Set:时钟或者定时的设置按钮,初次按下,进入定时设置,再次按下,进入时钟设置。液晶上会显示出set的目前值。Set为1时为定时设置,为2时是时钟设置。TB/TS:此按键是实现当前设置在当前定时组别的开始时间和结束时间之间切换。Left:此按键是实现当前设置位左移一位。Up:此按键是实现当前设置位进行加1操作。Down:此按键是实现当前设置位进行减1操作。Right:此按键是实现当前设置位右移一位。图4.5键盘电路5系统软件程序设计这次设计可以用C语言编程序,也可以用汇编语言编程序,由于本次设计中程序涉及到定时和复杂的逻辑控制,系统用C语言编写程序。此次设计所选用的单片机是AT89S52单片机,其C语言语法和结构和标准C语言基本相同,只是有了相应的扩充,用到的编译软件是KeilC。下面结合我的程序编译简要介绍以下KeilC的编译环境的特点。 KeilC51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到KeilC51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。KeilC51在使用前一定要先进行注册,否则程序过大会造成编译时出现地址使用错误。程序在编译时就遇到过这种问题。在单个程序运行时没有错误,但是一整合编译后出现地址冲突现象。这个问题困扰了很长一段时间,通过查资料发现若是KeilC51软件没有注册的话使用时当程序过大就会出现地址冲突现象。在注册完成后,程序编译能顺利通过。5.1主程序的设计在本次设计中,主程序主要是在单片机的控制下,对键盘的输入信息进行存储分析,驱动液晶显示出相关信息,并通过对比分析定时时间与时钟,控制继电器的通、断,从而达到控制插座的通、断电。在这个过程中,单片机首先进行初始化,包括设置单片机各个端口的方向,各个变量的初始化,液晶显示初始化、继电器断开以及单片机振荡频率的校准等。单片机每分钟对定时时间和时钟进行一次比较,如果定时开始,则ray的进行加1操作,结束时ray进行减1操作,若ray为0,则继电器断开,ray非0时继电器接通。在进行定时或时钟设置时对定时时间进行判断。其具体的源程序见附录2。整个系统软件设计的流程图如图5.1所示。开始初始化进入按键所指功能按键是否按下是否30秒内是否无按键按下液晶背光灯关闭是判断定时开始时间与时钟时间是否相等否Ray变量进行加1操作,继电器接通是否Ray进行减1操作,若ray为0,则继电器断开,否则继续接通判断定时结束时间与时钟时间是否相等是 否图5.1主程序软件流程图5.2时钟程序设计单片机AT89S52内的定时器0和定时器1能准确定时一段时间。故用定时器0和定时器1定时,并通过计算定时次数来实现时钟走时。本设计定时器0和定时器1都是定时50ms中断一次,中断20ms就能实现一秒钟。模式(mod)的值为0时时钟是24小时制,为1时是100小时制。其具体的源程序见附录2。整个系统软件设计的流程图如图5.2所示。判断时或分是否有变化开始定时器0初始化定时器1初始化启动走时有关变量初始化是刷新显示否判断秒到否否 是秒指示刷新图5.2时钟程序软件流程图5.3时钟设置及定时设置程序设计为了实现时钟走时与所在地时间走时一致和满足定时的要求,设定了时钟设置和定时设置功能。时钟设置和定时设置用同一个函数实现,通过判断按键的值和所按下的按键来确定所设置的内容。Set值为1时进入定时设置,Set值为2时进入时钟设置。T按键是实现定时组别的选择,TB/TS按键是实现定时设置当前组的开始时间与结束时间的选择。其具体的源程序见附录2。整个系统软件设计的流程图如图5.3所示。开始初始化相关变量,开定时器1关闭定时器1,程序结束时钟设置Left是否按下当前设置位减1操作当前设置位加1操作当前设置位右移一位当前设置位左移一位Down是否按下Up是否按下定时设置Set值判断Set=2Set=1是否Right是否按下是否是否是否Enter是否按下否 是图5.3时钟及定时设置程序软件流程图6系统软硬件的制作与调试6.1硬件的制作电路设计软件Protel是目前国内最流行的通用CAD软件,它是将电路原理图设计、PCB板图设计、电路仿真和PLD设计等多个实用工具软件组合后构成的CAD工作平台。本设计是首先在Protel软件上画好单片机最小系统、液晶与单片机连接电路、继电器的外围电路及与单片机的链接电路、键盘与单片机的连接电路、电源电路等的原理图,然后对原理图进行仿真,仿真无误后生成网络表后装载到PCB环境中生成需要的PCB。其中,单片机控制继电器部分为了确保其在实际应用的准确性,首先在万用板上焊接好继电器电路,并接上插座后对其进行验证,证明使用本电路能正常工作后,再打印PCB、转印到铜板上、用用双氧水稀释浓盐酸腐蚀、钻孔,并根据原理图由低器件(如电阻)到高器件安放元器件(确保元器件的参数与电路中的一致),然后焊接元器件,完成了定时快关插座的硬件电路板的制作。6.2调试方案根据电路原理图、PCB图把电路板实物做出来后,下一步就是电路板调试。电路板调试是最关键的一步,前面所做的电路设计的成功与否就是在调试步骤里体现的。本系统的调试主要分为硬件调试、软件调试和接负载调试等三大部分。经过初步对定时器的分析设计后,在制作硬件电路的同时,调试也在穿插进行。这样有利于问题的分析和解决,不会造成问题的积累,而且不会因为一个小问题而影响整体电路的检查,从而可以节约大量的调试时间。例如当单片机控制模块硬件部分制作好后,就可以先调试显示程序,在LCD12232上显示一个简单的数字0,显示结果正确了,说明LCD显示电路与单片机的连接电路是正确的,单片机能正常工作。软件编程中,首先完成单元功能模块的调试,然后进行系统的调试,调试的整体思想和步骤和硬件大同小异。插座接负载调试是最重要的一部分,虽然软硬件调试都通过了,但是插座接负载调试过程中可能会出现新的问题。6.3硬件电路调试硬件单元电路制作好后,在上电之前,应该先用万用表对各个独立元件进行检查,在排除了虚焊、短路、断路等问题后再通电进行电路功能的调试。具体调试过程如下所述: 6.3.1独立元件的检测任何组装好的电子电路,在通电调试之前,必须认真检查电路连线是否有误。检查的方法是对照电路图,按一定的顺序逐级对应检查,例如:对电路板的电阻阻值进行确定,可以通过读取电阻上的色环进行确认。特别是注意电源是否接错,电源与地是否有短接,集成电路和晶体管的引脚是否接错,轻轻拨一拨元器件,观察焊点是否牢固等。用万用表检测是不是有短路和断路现象。给系统上电后,看下电源(绿色)灯亮不亮。假如不亮,就要检查电源指示灯发光二极管的好坏。还要用万用表测一下单片机等芯片的电压是不是符合要求。假如不是,就要进行各个芯片的检查,看一下各个芯片的引脚有没有焊好,芯片是否损坏。6.3.2电源电路的调试电源电路作为整个系统的供电电路,其输出电压必须在单片机的正常工作电压范围(4V到5.5V之间)内。在电源通220V交流电之前,一定要检查电路是否接错,特别是极性电容是否有接反,防止出现极性电容接反而造成爆电容的现象。在确保器件接法无误的情况下,接通电源,并用万用表测量输出电压,得到其电压为5.3V。符合系统的正常工作电压要求。接上干电池,断开交流电,由于干电池是经过4007二极管后再给系统供电,4007二极管的压降为0.7V,测量得到新电池状态下输出电压为5.4V,达到系统正常工作电压要求。然后再用两部分电源同时供电,由于干电池部分有4007二极管保护,不会出现干电池在电压低于5V时会损耗功率的情况,实现了其储备电源的作用。6.3.3单片机最小系统的调试单片机AT89S52最小系统的检测分为硬件调试及软件调试。硬件调试时用万用表测量单片机的工作电压及各个管脚的电压是否达到正常工作电压。在此检测中还要烧入程序对各个I/O口的输出进行测试,查看I/O口所输出的电压是否与程序所控制值一致。例如:编写一个调试程序,使的所有I/O口从P1.0口开始依次赋予低电平,用万用表测量其输出电压,确定是否与程序所付值一致,一致则证明正确;然后又对其依次赋予高电平,确定是否与程序所付值一致,一致则证明正确。两次测试都正确,证明单片机最小系统是正常工作的。6.3.4显示模块的调试显示模块硬件连接相对比较简单,检查与调试过程中也没有遇到什么困难。这次设计中,结果用LCD12232来显示。在给系统上电后,要观察LCD的亮度,为了减少功耗,LCD12232的背景灯的接地管脚同过I/O口P2.0的高低电平实现灭亮的要求,这种接法其背光灯会较暗,但是能够满足其在白天和夜晚都可以看清楚显示内容的要求。6.3.5键盘模块的调试键盘是用4*3矩阵键盘实现。与一个I/O口控制一个按键的方法不同,每个按键的确定是通过与键盘相连的7个I/O 口的电平产生变化,并使用行列翻转扫描法来唯一确定。在硬件检测时,首先用万用表检测每个按键之间的链接是否有断线的情况,若是有断线,查出后可以使用熔化后的焊锡将线接通。然后再看每个按键按下时反馈回单片机的电平是否与预期的一致,若不一致这要看原理图是否有错,在画PCB时是否有错,然后再查看线路是否有断线情况。在检测键盘过程中,因为存在连线不好的情况,其中一个按键的功能有时候能实现,有时候不能实现。经检查排除后,发现是与此按键相连的一条线被腐蚀是过度了,造成接触不良,用焊锡加固后解决了此问题。6.3.6继电器电路的调试继电器的外围电路硬件检测的工作最为简单,首先是测出三极管8050在给出工作电平时它的各个管脚的电压值,然后看看是否工作在放大状态。三极管工作在放大状态,就能给继电器提供足够的电流,从而驱动继电器工作。通过对定时开关插座的硬件制作与调试,系统的实物图如附录3所示。6.4软件调试软件的调试包括程序本身语法的调试和在电路板上功能的调试两种。在编程过程中,为了得到满足要求的用户程序,一般都需要有一个对程序的调试过程,甚至需要经过多次反复的调试才能完成。在调试程序前为了调试方便,避免程序出错时将单片机拆来拆去的麻烦,在电路板上做了一个下载口,可以将下载线直接插到电路板上进行调试,这样就可以一边进行调试,一边修改程序。程序用KeilC软件写好后,先用该软件的编译功能编译一下所写的程序,检查程序是有语法错误或其他的错误。如果有错误则根据提示进行分析将错误改过来直至编译成功为止。当完成了语法调试后,再根据定时开关插座设计的功能要求修改程序完成系统的各个功能。在编写程序的时候一定要根据系统实现的功能和连接方式,认真分析,画出系统主程序、时钟程序、设置程序的流程图,并根据画出的流程图一步一步的去写出程序。根据系统的特点,软件系统应该按模块进行调试,当各个模块调试通过后再将各个模块整合起来,进行综合调试,直到得到预期结果。软件模块大致可以分为四部分:LCD12232显示模块、时钟模块、按键设置模块、继电器控制模块。在这四个模块中,调试的顺序比较固定:首先调试显示模块,因为只有显示正确后,才能够显示按键操作结果及时钟信息,以便和预期结果比较看是否正确。接着调试时钟程序,然后调试按键模块,最后调试继电器控制模块。与纯粹的C语言编程不同的是,单片机编程要考虑到硬件的设计,所有程序的编写都是根据硬件资源进行。开始程序下载到单片机的时候,液晶没有显示,在排除了程序语法错误和板子虚焊等原因后,还是没有显示,经过仔细检查发现,原来是软件编写中把单片机和液晶接线的引脚定义错了,改正后即得到了显示结果。在键盘扫描时,在编译过程中没有错误,但是因为其中三个按键的键值计算错误,在按键按下时没有反应到液晶显示上,然后重新计算出正确的键值后即得到预期结果。 6.5整体系统调试定时开关插座的硬件模块和软件模块分别调试通过后,接下来就可以进行系统的整体测试。在刚开始的时候也遇到了一些问题。在定时方面,单组定时都能在规定的时间内开始和结束,但是当多组定时有重叠的部分时,由于考虑不周全,在一组结束时继电器会闪一下,这样会造成插座供电也会闪一下。这种状况很容易将负载损坏,最起码会对负载造成伤害。为了解决这个问题,我用了一个中间变量ray来解决定时时间有重叠时的闪烁问题。首先对ray进行归零,在判定定时开始和结束时,每组定时开始都对ray的进行加1操作,结束时对ray进行减1操作,然后通过判断ray的值来控制继电器。当ray为非0值时,继电器导通,当ray为0值时继电器断开。这样,就能避免再有定时叠加时组别之间交接时出继电器闪烁的问题。对定时开关插座进行负载调试时,负载所接的是额定功率为40W的风扇,并在一天24小时中的每一个小时对6定时进行测试。首先是每组定时时间范围为1分钟,定时组别之间的时间间隔也为一分钟。在设定时间内,都能准确的对插座上的风扇进行通电和断电的操作。然后对每组定时时间范围分别设为10分钟,定时开关插座也能实现对风扇在定时时间范围内供电,其他时间则停止(供电)的操作。接着分别对6组定时分别进行各种时间范围的测试,其中包括定时组别的定时时间又交集的情况。例如,要在定时组别1中定时,要求在每天的13时插座断电、14时插座供电,则可在开始时间数组begin中输入13:00,在结束时间数组end中输入14:00。在定时组别的定时时间有交集时,定时开关插座在两组时间的开始和结束的转换过程中插座供电不会出现跳变,从而不会对电器(风扇)产生影响,达到了设计时要求如果两个或两个以上的定时时间交集时继电器不会出现快速通、断的情况,即不会出现插座供电跳变的情况。继电器正常工作允许通过的最大电流是10A,额定工作电压为220V,即允许通过的功率为2200W。但是负载的功率过大会影响到系统的运行。通过测试,系统能承受的最大功率为1500W。当插座的负载在超过1500W(由于缺少设备,所以是用40W的风扇、550W的热水器、1500W和1800W的热得快进行测试的)时,继电器在跳变时会造成单片机重启,影响了系统的正常工作。 7结论本次毕业设计是一个基于单片机AT89S52的定时开关插座,包括方案选择、软硬件设计、单片机最小系统、继电器驱动电路和键盘电路调试、硬件测试结果及解决在电路调试时遇到的问题。在此期间主要完成的工作包括以下几个方面:(1)设计初期收集继电器、单片机等相关资料,对定时开关插座的实现原理有比较清晰的了解。(2)确定系统框图,对电源模块、单片机最小系统模块、键盘电路模块和继电器及其驱动电路模块等的实施方案进行比较,确定最终的定时开关插座的设计方案。(3)根据定时开关插座的原理图制作出硬件电路板,并对系统进行空载调试和接负载调试。(4)根据系统要实现的定时和时钟走时等功能编写出软件程序,并进行定时功能的调试及数据采集分析。(5)软硬件调试通过后进行整体调试,并查找定时开关插座系统存在的缺陷,进行定时功能的完善。(6)最终系统定时组别可以达到6组,定时时间范围根据模式的不同可以分为24小时内任意时间(最小定时范围为一分钟)和100小时没任意时间(最小定时范围为一分钟)两种定时方式。本次设计完成了一款定时开关插座系统。该系统采用51单片机AT89S52编程控制继电器的通、断来实现控制插座的通、断电,而继电器的通、断由定时组别确定。在定时范围内继电器导通,否则断开。并用LCD12232显示出时钟及定时时间等信息。当时钟走到定时开始时间时,继电器接通,插座给负载供电;时钟走到定时结束时间时,继电器断开,插座停止给负载供电。总的来说,本次设计还是比较成功的,各项指标都符合设计要求。由于毕业设计经费有限及有的元器件比较难购买到,故定时开关插座系统存在一定的缺陷,可以做进一步的完善:例如可以用一个按键实现多个功能,这样子按键数目就会大大减少,减小系统的体积。电源部分可以用高频磁芯代替变压器,这样设计出来的电源重量及体积会更小,能使电源模块更加小巧玲珑,从而减小整个系统的重量及体积,便于使用等等。 本次设计的定时开关插座自动化程度较高,符合定时开关插座的发展方向。系统适用于日常家庭电器供电,如:给电风扇定时供电,给水塔定时抽水等等,具有较高的实用价值。系统中的定时组数经简单改造后能增加组数,继电器改用能承受更大的电流的继电器或者光耦合器,能使定时开关的应用更广,具有一定的应用前景。谢辞本毕业设计是在李老师悉心的关怀与指导下完成,在此对老师献上最衷心地感谢。李老师从毕业设计一开始就对我们严格要求,每周的周一都会和我们开见面会,询问我们的毕设进度并了解我们遇到的困难,积极协助我们解决设计过程中的各种难题,并要求我们每天记录在毕业设计中所作的工作进度及遇到的问题,让我们去发现问题,解决问题。在我遇到难已解决的问题心中急躁时,李老师总是及时的给予鼓励,使我能够有勇敢的克服困难,把毕设继续进行下去。李老师对学生的高度关注和对工作高度负责的精神值得我们尊敬,也是我今后走向工作岗位的榜样。通过本次毕业设计,我不仅是对我们所学知识的一个汇总,同时也是考验我们学习能力和动手能力的一个平台;让我们能学到更多的相关知识,更重要的是学到了面对困难的不放弃、不气馁的态度,不骄不躁的办事风格,奋发向上的精神,这些在我今后的生活和学习中都是一笔宝贵的财富。最后,我要再次感谢在毕业设计过程中对我提供过制作电路板等工具的同学和老师,以及在毕业设计中对我进行过知道的所有老师和同学。 参考文献[1]王港元.电子技能基础基础[M].成都:四川大学出版社,2001.[2]白驹珩,雷晓平.单片计算机及其应用[M].北京:高等教育出版社,2004.[3]范风强,兰娟丽.单片机语言C51应用实战集锦[M].北京:电子工业出版社,2005.[4]沈红卫.基于单片机的只能系统设计与实现[M].北京:电子工业出版社,2005.[5]马忠梅,张凯.单片机的C语言应用程序设计[M].北京:航空航天大学出版社,2003.[6]汪德彪,郭杰.MCS-51单片机原理及接口技术[M].北京:电子工业出版社,2003.[7]张晓光.用PIC单片机制作的电源定时插座[J].电子制作2010年05期.[8]雷道仲,李书成,罗政球.基于单片机定时开关的设计[J].科技广场,2009.[9]罗冬,赵海刚等.基于单片机的红外遥控定时开关装置的设计[J].机电工程技术2010年第39卷第03期.[10]谭浩强.C语言程序设计[M].北京:清华大学出版社,2005.[11]康华光,陈大钦.电子技术基础模电部分[M].北京:高等教育出版社,2006.[12]戴佳,戴卫恒,刘博文.51单片机实例精讲[M].北京:电子工业出版社,2008.[13]李瀚荪.电路分析基础[M].北京:高等教育出版社,2006.[14]刘昌华,易逵.8051单片机C语言应用程序设计与实践[M].北京:国防工业出版社,2007.[15]AllanR.Hambley.ElectronicsSecondEdition[M].PublishingHouseofElectronicsIndustry,2005.[16]Bates,Martin.InterfacingPICmicrocontrollers:embeddeddesignbyinteractivesimulation[M].GodinLyttlepress,2009. 附录1电源电路原理图 单片机AT89S52最小系统及液晶12232接入电路原理图Header20是液晶12232的插座,其中管脚编号与液晶管脚编号一致。键盘电路原理图 继电器驱动电路电路的PCB附录2#ifndefLCD12232_C#defineLCD12232_C/*****************************************************LCD12232显示驱动源文件*说明:主控芯片SED1520*文件名:LCD12232.c****************************************************/#include#include"LCD12232.h"/****************************************************函数定义 ***************************************************/voidRstDelay(void)//复位延时{unsignedchari;for(i=0;i<200;i++);}voidWriteDataL(ucharbyte)//向左屏写数据{RW=0;//writeDI=1;//dataE1=1;LCD_DATA=byte;E1=0;}voidWriteDataR(ucharbyte)//向右屏写数据{RW=0;//writeDI=1;//dataE2=1;LCD_DATA=byte;E2=0;}voidWriteCmdL(ucharbyte)//向左屏写指令{RW=0;//writeDI=0;//commandE1=1;LCD_DATA=byte;E1=0;}voidWriteCmdR(ucharbyte)//向右屏写指令{RW=0;//writeDI=0;//commandE2=1;LCD_DATA=byte;E2=0;}voidInit(void)//初始化{RstDelay(); WriteCmdL(OFF);//关显示WriteCmdR(OFF);WriteCmdL(DISP_START);//从第0行开始显示WriteCmdR(DISP_START);WriteCmdL(DRIVE_MODE);//动态显示WriteCmdR(DRIVE_MODE);WriteCmdL(DISP_START);//列地址切换到0WriteCmdR(DISP_START);WriteCmdL(PAGE_ADDR);//页地址切换到0WriteCmdR(PAGE_ADDR);WriteCmdL(DUTY32);//扫描行数为32WriteCmdR(DUTY32);WriteCmdL(END_RMW);//关闭RMR模式WriteCmdR(END_RMW);WriteCmdL(ON);//开显示WriteCmdR(ON);}voidClear(void)//清屏{uchari;ucharpage;for(page=0;page<4;page++)//0~3页{WriteCmdL(PAGE_ADDR|page);WriteCmdR(PAGE_ADDR|page);for(i=0;i<61;i++)//0~60列{WriteCmdL(COL_ADDR|i);WriteCmdR(COL_ADDR|i);WriteDataR(0x00);WriteDataL(0x00);}}}voidWriteASCII(ucharx,uchary,ucharASCII){uchari;uchar*p;p=ASCII_TAB[ASCII-32]; if(x<10)//x=10时,字符要跨越两个屏{x*=6;//虽然字模宽度为5,但是为了美观,在后面加入一个空白列WriteCmdL(COL_ADDR|x);WriteCmdL(PAGE_ADDR|y);for(i=0;i<5;i++)WriteDataL(*p++);WriteDataL(0);//补空白列}elseif(x>10){x*=6;x%=61;WriteCmdR(COL_ADDR|x);WriteCmdR(PAGE_ADDR|y);for(i=0;i<5;i++)WriteDataR(*p++);WriteDataR(0);//补空白列}else{WriteCmdL(COL_ADDR|60);WriteCmdL(PAGE_ADDR|y);WriteDataL(*p++);WriteCmdR(COL_ADDR|0);WriteCmdR(PAGE_ADDR|y);for(i=0;i<4;i++)WriteDataR(*p++);WriteDataR(0);//补空白列}}voidWriteString(ucharx,uchary,uchar*p)//字符串必须以"n"结束{while(*p!="n"){if(x>=21){x=0;y++;}WriteASCII(x++,y,*p++); }}ucharcodeASCII_TAB[][5]={}//由于篇幅有限,所以本数组就不给出了。#endif主函数部分:#include"reg52.h"#include"LCD12232.h"#defineucharunsignedchar#defineuintunsignedintsbitGN=P2^0;sbitVC=P2^5;sbitjidian=P2^7;/***********************************************************************;T0定时中断函数:timer0();定时时间为50ms,方式1的时间常数为3CB0H;每中断1次,计数单元加1;20次为1s,到1s进行相应处理;**************************************************************************/voidtimer0(void)interrupt1using1{ucharx;TH0=0x3c;TL0=0xb0;count++;if(count/6==0)ss=!ss;x=20;if(count!=x)return;else{count=0;second++;if(second!=10)return;secondh++;second=0;if(secondh!=6)return; else{secondh=0;minull++;if(minull!=10)return;else{minull=0;minuhh++;if(minuhh!=6)return;else{minuhh=0;hourll++;if(!mod){if(hourhh==0){if(hourll!=10)return;elsehourll=0;hourhh++;if(hourhh!=3)return;else{hourhh=0;return;}}else{if(hourll!=4)return;else{hourll=0;hourhh++;if(hourhh!=3)return; else{hourll=0;hourhh=0;return;}}}}else{if(hourhh==0){if(hourll!=10)return;elsehourll=0;hourhh++;if(hourhh!=10)return;else{hourhh=0;return;}}else{if(hourll!=10)return;else{hourll=0;hourhh++;if(hourhh!=10)return;else{hourll=0;hourhh=0;return;}} }}}}}}}/*********************************************************************;模式0的定时时间设置函数;带当前时间设置函数:settime();按set键开始进入设置状态(包括设置定时时间和时钟时间),按up键可进行当前位置的+1,按down键则为-1,按left键则为当前位置左移一位,按right则为右移一位;等待按sure或者cancel结束当前设置;设置;*********************************************************************/voidsettime(void){while(set){hh=1;TR1=1;ET1=1;TH1=0x3c;TL1=0xb0;while(1){TR1=1;ET1=1;TH1=0x3c;TL1=0xb0;if(mod){set=0;break;}switch(setflag){case1:{hh=1;hl=0;mh=0;ml=0;break;}case2:{hh=0;hl=1;mh=0;ml=0;break;}case3:{hh=0;hl=0;mh=1;ml=0;break;}case4:{hh=0;hl=0;mh=0;ml=1;break;}} if(set==1){buf[0]=hourhh;buf[1]=hourll;buf[2]=minuhh;buf[3]=minull;if(BS){timing1[timer][0]=hourh;timing1[timer][1]=hourl;timing1[timer][2]=minuh;timing1[timer][3]=minul;}else{timing[timer][0]=hourh;timing[timer][1]=hourl;timing[timer][2]=minuh;timing[timer][3]=minul;}timerr();playsetting();}if(set==2){buf[0]=hourh;buf[1]=hourl;buf[2]=minuh;buf[3]=minul;}timerr();playsetting();keyscan();if(sure){TR1=0;ET1=0;if(set==2){hourhh=hourh;hourll=hourl; minuhh=minuh;minull=minul;}if(set==1){timing1[timer][0]=hourh;timing1[timer][1]=hourl;timing1[timer][2]=minuh;timing1[timer][3]=minul;timing[timer][0]=timing[timer][0];timing[timer][1]=timing[timer][1];timing[timer][2]=timing[timer][2];timing[timer][3]=timing[timer][3];}hourh=0;hourl=0;minuh=0;minul=0;set=0;sure=0;BS=0;hh=1;hl=0;mh=0;ml=0;setflag=1;return;}if(up){up=0;if(hh){hourh++;if(hourh==3)hourh=0;continue;}elseif(hl) {hourl++;if(hourh==2&&hourl==4){hourl=0;continue;};if(hourl==10){hourl=0;continue;}}if(mh){minuh++;if(minuh==6){minuh=0;continue;}continue;}elseif(ml){minul++;if(minul!=10)continue;else{minul=0;continue;}}}if(down){down=0;if(hh){hourh--;if(hourh==-1)hourh=2;continue;}elseif(hl){hourl--;if(hourh==2&&hourl==-1){hourl=3;continue;};if(hourl==-1){hourl=9;continue;}}if(mh){minuh--;if(minuh==-1){minuh=5;continue;}continue;}elseif(ml){minul--;if(minul!=-1)continue;else{minul=9;continue;}} }}}}/**********************************************************************;模式1的定时时间设置函数:settime1();按set键开始进入设置状态,按up键可进行当前位置的+1,按down键则为-1,按left键则为当前位置左移一位,按right则为右移一位;等待按sure或者cancel结束当前设置;设置;*********************************************************************/voidsettime1(void){while(set){hh=1;TR1=1;ET1=1;TR1=1;ET1=1;TH1=0x3c;TL1=0xb0;ray=0;while(1){TR1=1;ET1=1;TH1=0x3c;TL1=0xb0;switch(setflag){case1:{hh=1;hl=0;mh=0;ml=0;break;}case2:{hh=0;hl=1;mh=0;ml=0;break;}case3:{hh=0;hl=0;mh=1;ml=0;break;}case4:{hh=0;hl=0;mh=0;ml=1;break;}}if(set==1){buf[0]=hourhh;buf[1]=hourll; buf[2]=minuhh;buf[3]=minull;if(BS){timing1[timer][0]=hourh;timing1[timer][1]=hourl;timing1[timer][2]=minuh;timing1[timer][3]=minul;}else{timing[timer][0]=hourh;timing[timer][1]=hourl;timing[timer][2]=minuh;timing[timer][3]=minul;}timerr();playsetting();}if(set==2){second=0;secondh=0;if(set==2){buf[0]=hourh;buf[1]=hourl;buf[2]=minuh;buf[3]=minul;}timerr();}timerr();playsetting();keyscan();if(sure) {TR1=0;ET1=0;if(set==2){hourhh=hourh;hourll=hourl;minuhh=minuh;minull=minul;}if(set==1){timing1[timer][0]=hourh;timing1[timer][1]=hourl;timing1[timer][2]=minuh;timing1[timer][3]=minul;timing[timer][0]=timing[timer][0];timing[timer][1]=timing[timer][1];timing[timer][2]=timing[timer][2];timing[timer][3]=timing[timer][3];}hourh=0;hourl=0;minuh=0;minul=0;set=0;sure=0;BS=0;hh=1;hl=0;mh=0;ml=0;setflag=1;ss=0;break;} if(up){up=0;if(hh){hourh++;if(hourh==10)hourh=0;continue;}elseif(hl){hourl++;if(hourh==9&&hourl==9){hourl=0;continue;};if(hourl==10){hourl=0;continue;}}if(mh){minuh++;if(minuh==6){minuh=0;continue;}continue;}elseif(ml){minul++;if(minul!=10)continue;else{minul=0;continue;}}}if(down){down=0;if(hh){hourh--;if(hourh==-1)hourh=9;continue;}elseif(hl){hourl--;if(hourl==-1){hourl=9;continue;}}if(mh) {minuh--;if(minuh==-1){minuh=5;continue;}continue;}elseif(ml){minul--;if(minul!=-1)continue;else{minul=9;continue;}}}}}}/*********************************************************;T1定时中断函数:timer1();定时时间为50ms,方式1的时间常数为3CB0H;没中断1次,计数单元加1,20次为1s,在进行相关处理;因为timer0、timer1不会同时允许中断,可共用工作寄存器1;*******************************************************/voidtimer1(void)interrupt3using1{TH1=0x3c;/*100ms定时常数*/TL1=0xb0;count++;/*中断次数加1*/if((count/6)==0)ss=!ss;if(count!=20)return;count=0;}/***********************************;T1定时初始化函数:t1_init;定时时间为100ms,方式1的时间常数为3CB0H;*******************************************/voidt1_init(void){TMOD=0x11;/*T1定时方式1*/TH1=0x3c;TL1=0xb0;} /*********************************************************************;定时判断函数:compare();通过比较定时时间的开始与结束判断继电器的通断;**********************************************************************/voidcompare(void){ucharn,m,YE=0,OK=0,b=0;if(secondh==0&&second==0)b+=1;elseb=0;if(b!=0){if(ray!=0)jidian=1;elsejidian=0;delay20ms();}if((b==1)&&(set==0)){if((secondh==0)&&(second==0)){for(n=0;n<6;n++){for(m=0;m<4;m++){if((timing[n][m]==timing1[n][m])&&(timing[n][m]==0))OK+=1;continue;}if(OK==4)YE=1;elseYE=0;OK=0;if(!YE){for(m=0;m<4;m++){if(timing[n][m]!=buf[m])continue;OK+=1;}if(OK==4)ray+=1;OK=0;if(ray<0)ray=0;for(m=0;m<4;m++){if(timing1[n][m]!=buf[m])continue; OK+=1;}if(OK==4)ray-=1;}if(ray!=0)jidian=1;elsejidian=0;}}}} 附录3'