找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 38125|回复: 7
打印 上一主题 下一主题
收起左侧

基于单片机的自动定时开关插座的设计文档与源程序

[复制链接]
跳转到指定楼层
楼主
ID:325162 发表于 2018-5-8 16:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
自动定时开关插座的设计
主要内容
以单片机为核心,设计智能定时开关插座,该系统可以实现自动按时控制插座的打开、关闭,以达到控制用电设备工作,节省电能的效果。

基本要求
1、独立完成系统软、硬件设计,并搭电路验证。
2、实现至少十六个时间点。
3、无线打开关闭插座。

摘要
随着近年来各个家庭的家用电器的增多,以及各种公共用电设备的增加,各种智能化控制的功能被附加于产品之内,但不可忽视的是较为老旧的电器产品缺乏这些基本功能。因此这给生活和工作带来很大的不便,同时长期的无用工作状态也带来了大量的电力资源的消耗。
本文介绍了一种基于51系列单片机的系统设计,通过以实时时钟芯片的时间信息为基准,配合单片机内部扩展RAM存储的时间设定值,以及液晶显示屏对各种信息的显示,从而以达到定时控制开关插座电路的目的。此外,在该设计基础之上,再添加红外遥控打开/关闭插座的功能,以进一步使得该设计更具智能化和实用性。该设计虽然结构简单,但能广泛应用于各个用电控制的工作环境中,具有较强的适用性。

目录
摘要
Abstract
第1章 绪论
1.1 课题背景
1.2 当前国内外研究现状
1.3 定时开关的应用
1.4 设计的主要内容和章节安排
第2章 系统总体设计
2.1 总体结构
2.2 总体结构的工作原理
2.3 本章小结
第3章 主控制器与外围器件
3.1 STC12C5A60S2单片机
3.2 LCD1602液晶显示模块
3.3 DS1302实时时钟模块
3.4 红外接收模块
3.4.1 遥控发射器及其编码
3.4.2 遥控信号的接收
3.5继电器控制模块
3.6 本章小结
第4章 硬件设计
4.1 单片机最小系统设计
4.1.1 单片机
4.1.2 电源电路
4.1.3 复位电路
4.1.4 晶振电路
4.1.5 RS232接口转USB接口电路
4.2 显示电路设计
4.3 时钟电路设计
4.4 红外接收电路设计
4.5 继电器控制电路
4.6 按键电路
4.7本章小结
第5章 软件设计
5.1 主程序设计
5.2 LCD1602显示程序设计
5.3 DS1302实时时钟程序设计
5.4 VS1838B中断程序设计
5.5 系统测试
5.6 本章小结
结论
参考文献
致谢
附录1
附录2
附录3
附录4
附录5
附录6


第1章 绪论
1.1 课题背景
自单片机诞生以来,其高可靠性,低功耗以及很强和工作运行环境适应能力,以广泛应用于各个生产生活的管理控制领域。而目前基于单片机的自动控制开关的产品依然未进入大规模应用的阶段,其不成熟的产品设计以及普通大众对于该类产品的易用性与安全性仍存在一定的忧虑。因此,该课题将着眼于当前市场实际需求和具体设计平台性能,力求将该设计做到创新与实用的结合。
1.2 当前国内外研究现状
              智能定时开关目前已经大规模的应用与汽车、工业生产和仓储管理等无人监控的领域;同时,虽然目前已有部分的新推出的家用电器也已具备该功能了,但相对于目前数量更大的传统旧款的家用电器和老式的公共照明设施来说,仍停留在机械式的开关和简单的电子式定时开关。但无论以上两者的性能如何,它们都存在易磨损,安全性较差,需要大量手动操作,且在某些工作环境中还存在难以接触操作的问题。
     因此,虽然市场上都有各式各样的替代产品,但就目前来说,这些产品的功能都还存在很多不完善之处。在经过对该课题背景下的充分的产品需求的调研和仔细的可行性分析,该课题存在很大的改进和创新的空间。
1.3 定时开关的应用
定时开关可用于各种需要按时自动开启和关闭的电器设备。广泛适用于企事业单位和家庭,尤其是对人体伤害环境,如医院,幼儿园,餐饮等单位的紫外线消毒间,化工场所,及含辐射区域,避免人员直接进入内部开启和关闭开关,频繁遭受伤害。
同时定时开关还特别适合各种养殖场,孵化间,鱼塘供养,座位浇灌,鱼缸等场所。一次操作,可每天自动循环保证灯光照射及其投喂饲料的时间和次数,减少了大量人力,且避免因人为失误而导致的损失。
定时开关对于学校,军营尤其需要。每天多个规定的时间,电铃、军号自动响起,学生、军人按要求上课、出操、熄灯,不需要管理者疲劳操作。
定时开关还适用于家庭,每天早上太阳升起,窗帘自动缓缓打开,催醒睡梦中的你; 夜幕降临,窗帘又自动拉合,一个智能温馨而又奇妙的家全天侯拥抱着你。
定时开关为充电电池必备。尤其是电动车电池在整辆车中价值比例非常高,长时间充电会大大减少电池寿命。配上本产品,则即保证了满额充电,也不会在电池充满电之后仍然处于通电状态,对电池的保护起到了极大地作用。
定时开关在人们的生活中扮演着重要的角色,给人们的生活带来极大的便利。主要使用在提醒,计划或者规律化生活、工作上。定时开关的历史十分悠久,用途也很广泛。
从古代的某些建筑、计时器(如滴水计时,当水滴到一定量时会引发机关进行报时),到近代及今日的电脑定时开关机等,都采用了定时开关。
例子:学校的课铃就是采用定时器进行定时,当条件满足(即达到时间设定的点)时,电源就会接通,使电铃打开从而达到发出铃声的目的。
1.4 设计的主要内容和章节安排
              综合该领域的研究现状与现目前单片机应用的性能,该设计课题将主要围绕以下内容展开:
              一、首先,作为课题设计的第一步,应首先完成对该课题的前期调研,确定其应用需求以及对该课题可行性的分析,以求能更好的了解各个设计细节,解决用户所需求的问题;
              二、定时的开关控制是该设计的主要内容,因此应该在先设计出能作为时间基准的时钟模块,然后在此基础之上,完成对定时时间设定,时钟校时以及模式切换等功能或模块的设计。至此,已初步的完成定时时钟的功能,为后续功能完善做好基础;
三、在前一步的基础之上,再完成受控电路的设计,根据定时时钟的开关判断结果,单片机在端口给出控制信号电平,对外围的受控电路进行控制。
此处,要注意的是,由于可能会存在单片机IO口的电平低于外围的模拟器件的驱动电平的问题,因此,对受控期间进行电平上拉是一个必须注意的问题。
四、在以上基本的功能以后,应该说该设计已初具雏形,可进行对一些人性化需求的扩展设计,故此处规划了对该开关进行红外遥控控制的扩展。以期能达到该设计能应用于以往的替代产品无法应用的应用环境中去,体现其产品的差异化。
五、最后,在完成了以上各个步骤以后,各个模块也已大部分完成了最后的定型。但仍需要对程序在实际的硬件上运行的效果进行调试,对于显示和按键反应速度,蜂鸣器提示声音等问题进行最后的完善。
在本文在章节安排方面,将在第2章对整个系统的构思和设想进行阐述;在接着的第3章对方案中所使用的器件进行必要的介绍说明;后续在第4章中将对各个器件模块的硬件电路进行详细的设计说明;在完成硬件电路设计以后,将在第5章中完成对软件的构想流程进行阐述;最后,在第6章中本文将对所设计的软硬件进行运行测试,给出实验效果。在文章结束时得出结论。

                       
2章 系统总体设计
2.1 总体结构
在综合了各种设计方案的情况下,考虑了现有产品的缺陷之处的情况之后,最终确定了一STC12C5A60S2单片机为核心,DS1302实时时钟芯片、LCD1602液晶显示、TL1838红外收发模块、数字式继电器等外围器件构成的模块电路。这些功能器件不仅具有较好的抗干扰性能和高可靠能力,更由于其大都已经大规模的应用于各个应用产品中,开发成本较低,如若进入规模化生产,将进一步的降低生产成本,提高市场的可接受度。
由于这些器件已有成熟的应用,故以下图(图2-1)的总体设计结构为蓝本,进行具体的系统集成和功能细化。

图2-1 系统总体结构图
此外,在核心板的基础之上只有红外的接收模块,而要完成红外的收发控制,在此之外还需有红外的发射装置,在此未节省成本,选用了集成的红外遥控器,采用电池供电,具有超低功耗,超出待机的特点,十分符合设计要求。其整个红外收发的大致原理结构图如下图(图2-2)所示。

图2-2 红外收发模块工作原理图
总体的系统模块就如上述两图所示,整体结构简单明晰,各个模块的功能和特性应该更够较为全面的满足本课题的设计要求,故选用该方案。
2.2 总体结构的工作原理
由于各个模块的具体工作原理较为复杂,且对于该设计课题没有实际的意义,故不在此赘述。现只将该方案的大体工作的流程以及结构做以概述,以便更清新的阐述该课题。
首先,单片机为本次设计的核心设备,它将起着对各个指令的执行和对外围模块的控制的作用,在逻辑功能上相当于中央控制和调度的作用,本次将选择STC12C5A60S2承担该功能。
其次,作为定时开关插座的设计,DS1302实时时钟芯片将承担对时间信息的记录和输出,同时作为时间基准与设定的开关时间做比对,以达到辅助控制的作用。
然后,作为一个交互式的单片机设计课题,在以单片机为核心的基础之上,应当配合一定的输入输出控制设备。在此设计中,按键将作为对校时,定时,以及模式切换等功能的输入设备,辅助DS1302时钟芯片完成其对时间信息操控的功能。
再者,数字式时钟必然要求时间信息的显示效果。因此在比较了LED数码管,普通液晶屏,带汉字字符显示的液晶屏幕,以及有触摸功能的屏幕等等可用的显示设备之后,鉴于LCD1602这款液晶屏较低的采购价格,较好的显示效果和显示字符数的规格均符合设计需求,故决定采用这款不带汉字字符字库和触摸功能液晶显示屏幕。其能很好的满足时间信息,定时信息,和模式状态的显示。
最后,作为扩展功能的红外接收头和红外发射器,将主要以外部中断的方式进行对整个开关系统的闭合和关闭的控制,以期能达到方便应用于大多数较难手动按键控制的应用环境中。
综上所述,在整个系统中,将以整个单片机为核心,而DS1302时钟芯片作为时钟基准,配合按键输入的时间控制信息和红外遥控装置的控制信息,以达到定时开关被控制电路的效果,是典型的以弱电的设备控制强电电路开关的应用。
2.3 本章小结
              本章主要对整个系统的总体结构进行了大致的描述,给出了整个系统的框图,并对于选择该设计方案进行了简单的说明。在此基础之上,对系统总体的结构中的各个部分分别进行了简单的原理阐述,明确了各个部分在系统中的承担的功能和作用。

                       
第3章 主控制器与外围器件
3.1
STC12C5A60S2单片机
STC12C5A60S2单片机是中国大陆企业宏晶科技生产的单时钟/机器周期(1T)的单片机,是一种高速/低功耗/超强抗干扰的新一代增强型8051单片机,它不但完全兼容传统8051指令代码和管脚功能,而且其片内具有FLASH工艺的大容量程序存储器,该款单片机内部就自带高代60K FLASH ROM,这种工艺的存储器用户可以用点的方式瞬间擦除、改写。此外,片上也集成了180字节的RAM。而且STC系列单片机支持串口程序烧写。显而易见,这种单片机对开发设备的要求很低,开发时间也打打缩短。写入单片机内的程序还可以进行加密,又很好的保护了开发者的劳动成果。
其最大的特点是采用以单时钟周期作为机器周期进行指令的执行,大大的提高了指令的执行速度,其速度可快8-12倍。内部也集成了MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S),针对电机控制,强干扰场合。
此外,其I/O口在功能上与标准8051通用,复位后可设置成四种模式:准双向口/弱上拉,强推挽/强上拉,仅为输入/高阻,开漏。每个I/O口驱动能力可达20mA,但整个芯片不要超过120mA。整体来看,虽为弱电控制器件,但其外部驱动能力较强,对于大多外围受控器件,无需再添加模拟放大电路进行驱动,很大程度上降低了开发和制造成本。
在定时器方面,共有4个16位定时器,两个与传统的8051兼容的定时器/计数器,16位定时器T0和T1,没有定时器2,但有独立波特率发生器做串行通信的波特率发生器,再加上2路PCA模块可再实现2个16位定时器。
在外部中断方面,外部中断I/O口7路,传统的下降沿中断或低电平触发中断,并新增支持上升沿中断的PCA模块,Power Down模式可由外部中断唤醒.
其有多种的封装方式,较常用且也为本次设计所用的芯片如下图(图3-1)所示,其采用PDIP(塑料双列直插式封装):


图3-1 STC12C5A60S2单片机封装引脚图
3.2 LCD1602液晶显示模块
LCD1602液晶显示器,是基于液晶显示技术的点阵式显示屏幕,通过电压对其显示区域进行控制,具有厚度薄、适用于大规模集成电路直接驱动,且具有低功耗的特点,也大大的降低了发热量。而液晶的性能也很大部分是取决于其液晶对于各像素点输入信号的响应时间,显然在单片机这样的较低速的控制系统中,LCD1602作为较为简单的液晶显示屏幕,也足以能满足其应用需求,只要注意使用延时设置,基本不会有显示模糊和闪烁的情况发生。
具体上来说,1602液晶是一种专用的字符型液晶,它专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5*7或者5*11等点阵字符位组成,每个点阵字符位都可以显示一个字符。由于其内带字符发生器,通常使用RAM来存储相应字符的各个像素点的信息,因此,字符发生器的控制器在显示时只需要控制显示的行列号及找到需要显示字符的RAM对应的地址,设立光标,在此送上该字符对应的代码即可。
字符型液晶显示器目前常用16*1,16*2,20*2和40*2等规格的模块,综合本设计的实际需求和成本限制,故在此选择了16*2规格(即可以显示两行,每行16个字符)的LC1602模块。
市面上字符型液晶大多数是基于HD44780液晶芯片的,控制原理也是完全相同的,因此基于HD44780写的控制程序可以很方便地应用与市面上大部分的字符型液晶。
引脚功能说明
LCD1602采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表3-1所示:
表3-1 引脚接口说明表
编号
符号
引脚说明
编号
符号
引脚说明
1
VSS
电源地
9
D2
数据
2
VDD
电源正极
10
D3
数据
3
VL
液晶显示偏压
11
D4
数据
4
RS
数据/命令选择
12
D5
数据
5
R/W
读/写选择
13
D6
数据
6
E
使能信号
14
D7
数据

D0
数据
15
BLA
背光源正极
8
D1
数据
16
BLK
背光源负极
第1脚:VSS为地电源。
第2脚:VDD接5V正电源。
第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15脚:背光源正极。
第16脚:背光源负极。
该设计所使用的液晶模块具体如下实物图(图3-2)所示:
图3-2 LCD1602液晶显示模块实物图
3.3 DS1302实时时钟模块
实时时钟模块采用以DS1302实时时钟芯片为核心的集成化模块,DS1302是美国DALLAS公司推出的一款高性能、低功耗的实时时钟芯片,并附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
低功耗时钟芯片DS1302可以对年、月、日、时、分、秒进行计时,且具有闰年补偿等多种功能。DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录。这种记录对长时间的连续测控系统结果的分析以及对异常数据出现的原因的查找有重要意义。
采用DS1302作为记录测控系统中的数据记录,其软硬件设计简单,时间记录准确,既避免了连续记录的大工作量,又避免了定时记录的盲目性,给连续长时间的测量、控制系统的正常运行及检查都来了很大的方便,可广泛应用于长时间连续的测控系统中。在测量控制系统中,特别是长时间无人职守的测控系统中,经常需要记录某些具有特殊意义的数据及其出现的时间。记录及分析这些特殊意义的数据,对测控系统的性能分析及正常运行具有重要的意义。传统的数据记录方式是隔时采样或定时采样,没有具体的时间记录,因此只能记录数据而无法准确记录其出现的时间;若采用单片机计时,一方面需要采用计数器,占用硬件资源,另一方面需要设置中断、查询等,同样耗费单片机的资源,而且某些测控系统可能不允许。而在系统中采用DS1302则能很好地解决这个问题。
DS1302时钟芯片包括实时时钟/日历和31字节的静态RAM。它经过一个简单的串行接口与微处理器通信。实时时钟/日历提供秒、分、时、日、周、月和年等信息。对于小于31天的月和月末的日期自动进行调整,还包括闰年校正的功能。时钟的运行可以采用24h或带AM(上午)/PM(下午)的12h格式。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302有主电源/后备电源双电源引脚:VCC1 在单电源与电池供电的系统中提供低电源,并提供低功率的电池备份;VCC2在双电源系统中提供主电源,在这种运用方式中,VCC1 连接到备份电源,以便在没有主电源的情况下能保存时间信息以及数据。DS1302由VCC1或VCC2中较大者供电。当VCC2大于VCC1+0.2V时,VCC2给DS1302供电;当VCC2小于VCC1时,DS1302由VCC1供电。
DS1302数据操作原理
DS1302在任何数据传送时必须先初始化,把RST脚置为高电平,然后把8位地址和命令字装入移位寄存器,数据在SCLK的上升沿被输入。无论是读周期还是写周期,开始8位指定40个寄存器中哪个被访问到。在开始8个时钟周期,把命令字节装入移位寄存器之后,另外的时钟周期在读操作时输出数据,在写操作时写入数据。时钟脉冲的个数在单字节方式下为8加8,在多字节方式下为8加字节数,最大可达248字节数。

图3-3 DS1302管脚图

如果在传送过程中置RST为低电平,则会终止本次数据传送,并且I/O引脚变为高阻态。上电运行时,在VCC >=2.5V之前,RST脚必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。DS1302的管脚图如图3-3所示,表3-2为各引脚的功能。

表3-2 DS1302引脚功能表

引脚号

引脚名称

功能

1

VCC2

主电源

2,3

X1,X2

振荡源,外接32768HZ晶振

4

GND

地线

5

RST

复位/片选线

6

I/O

串行数据输入/输出端(双向)

7

SCLK

串行时钟输入端

8

VCC1

后备电源


DS1302的控制字如图3-4所示。控制字节的最高有效位(位7)必须是逻辑1;如果它为逻辑0,则不能把数据写入到DS1302中。位6如果为0,则表示存取日历时钟数据;为1表示存取RAM数据。位5~1(A4~A0)指示操作单元的地址。最低有效位(位0)如为0,表示要进行写操作;为1表示进行读操作。控制字节总是从最低位开始输入/输出。


图3-4 控制字节的含义

为了提高对32个地址的寻址能力(地址/命令位1~5=逻辑1),可以把时钟/日历或RAM寄存器规定为多字节(burst)方式。位6规定时钟或RAM,而位0规定读或写。在时钟/日历寄存器中的地址9~31或RAM寄存器中的地址31不能存储数据。在多字节方式中,读或写从地址0的位0开始。必须按数据传送的次序写最先的8个寄存器。但是,当以多字节方式写RAM 时,为了传送数据不必写所有31字节。不管是否写了全部31字节,所写的每一字节都将传送至RAM。数据读写时序如图3-5所示。






       图3-5 数据读写时序图

DS1302共有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见表3-3,其中奇数为读操作,偶数为写操作。

表3-3 片内时钟数据寄存器

寄存器

命令码

数据范围

寄存器中各位的内容

名称

地址

7

6

5

4

3

2

1

0

00H

80H

81H

00~59

CH

秒数据

01H

82H

83H

00~59

0

分数据

02H

84H

85H

01~12

或00~23

12/

24

0

10/

AP

时数据

03H

86H

87H

01~28,29

30,31

0

0

日数据

04H

88H

89H

01~12

0

0

0

月数据

星期

05H

9AH

8BH

01~07

0

0

0

0

0

星期数据

06H

8CH

8DH

00~99

年数据

多字节读写

BEH

BFH


3.4 红外接收模块


图3-6 红外收发工作流程图
红外遥控系统是集光、电于一体的系统,。其工作原理是用户按键信号单片机编码处理后转化为脉冲信号,经由红外发射头发射出去;接收端由红外一体化接收头实现对信号的放大解调并还原数据流,经由单片机解码后对相关I/O口进行操作,从而完成整个遥控操作。整个工作流程图如图3-6所示。
红外控制模块主要分为两个部分:红外发射端和红外接收端。而二者之间进行通信的基础是其共用的编码方式。
3.4.1 遥控发射器及其编码
红外遥控早已进入商用和开发领域多年,故遥控发射器的专用芯片很多。根据编码的格式可以分为两大类:NEC码和RC码,本设计以运用比较广泛,解码比较容易的日本NEC编码方式为开发的基础。现以日本NEC公司的Upd6121G组成的发射电路为例说明编码原理。当发射器按键按下后,即有遥控码发出,所安的键不同遥控编码也不同。这种遥控码具有以下特征:采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”,其波形如图3-7所示。


图3-7 Upd6121G的遥控码
图3-8遥控信号编码波形图
图3-7所示遥控码的“0”和“1”(注:所有波形为接收端的与发射相反),这些“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线像空间发射,如图3-8所示。


图3-9 红外遥控发射波形图
UPD6121G产生的遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的电路设备,以防止不同机种遥控码互相干扰。该芯片的用户识别码固定为十六进制01H;后16位为8位操作码(功能码)及其反码。UPD6121G最多128种不同组合的编码。遥控器在按键按下后,周期性地发出同一种32位二进制编码,周期约为108ms。一组码本身的持续时间随它包含的二进制“0”和“1”的个数不同而不同,大约在45 ~63ms之间,图3-9为发射波形图。
当一个按键按下超过36ms,振荡器使芯片激活,将发射一组108ms的编码脉冲,这108ms发射代码由一个引导码(9ms)、一个结果码(4.5ms)、低八位地址码(9~18ms)、高八位地址码(9~18ms)、8为数据码(9~18ms)和这8位数据的反码(9~18ms)组成。如果按键按下超过108ms仍未松开,接下来发射的代码(连发码)将仅由起始码(9ms)和结束码(2.25ms)组成。引导码和连发码的格式分别如图3-10所示和图3-11所示。



图3-10 引导码                                图3-11 连发码
3.4.2 遥控信号的接收
接收电路可以使用一种集红外线接收和放大于一体的一体化红外线接收器,不需要任何的外接元件,就能完成从红外线接收到输出与TTL电平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输。接收器对外只有3个引脚:OUT、GND、Vcc与单片机接口非常方便;其中,脉冲信号输出直接接单片机的IO口、GND接系统的底线(0V)、Vcc接系统的电源正极(+5V);
3.5继电器控制模块
继电器是一种电子控制器件,它具有控制系统(又称输入回路)和被控制系统(又称输出回路),通常应用于自动控制电路中,它实际上是用较小的电流去控制较大电流的一种“自动开关”。故在电路中起着自动调节、安全保护、转换电路等作用,是一种典型的弱电器件控制强电电路的应用。
电磁式继电器的工作原理和特性较为简单,一般由铁芯、线圈、衔铁、触点簧片等组成的。只要在线圈两端加上一定的电压,线圈中就会流过一定的电流,从而产生电磁效应,衔铁就会在电磁力吸引的作用下克服返回弹簧的拉力吸向铁芯,从而带动衔铁的动触点与静触点(常开触点)吸合。当线圈断电后,电磁的吸力也随之消失,衔铁就会在弹簧的反作用力返回原来的位置,使动触点与原来的静触点(常闭触点)吸合。这样吸合、释放,从而达到了在电路中的导通、切断的目的。对于继电器的“常开、常闭”触点,可以这样来区分:继电器线圈未通电时处于断开状态的静触点,称为“常开触点”;处于接通状态的静触点称为“常闭触点”。
本次设计中采用的继电器为SRD-05VDC-SL-C,继电器电气图如图3-12所示。
由于继电器的开启和关闭需要一定的机械运动,因此一般的继电器仍需要较高的驱动电压。首先,应该查阅继电器的技术说明,查明其额定的驱动电压值,看单片机的端口能否直接将其驱动,如若不能直接驱动或者要串联其他期间,应当考虑在外围构建放大电路,此继电器由于其额定的驱动电压值为5V,而该款STC单片机的端口电压值在5V左右,在没有特殊要求的情况下亦可不必外接放大电路;其次,在设计过程中应当充分的考虑到被控制电路的电压范围和最大电流,避免因超过额定值而造成安全隐患。
图3-12 继电器电气图
3.6 本章小结
   本章十分详细的介绍了实际方案中所用到的STC12C5A60S2单片机、LCD1602液晶显示模块、DS1302实时时钟模块、继电器控制模块等外围模块,对它们各自的功能和性能参数都有了一个详尽的了解,保证了后面方案中的硬件设计和软件设计的顺利进行。
                                                      


第3章 主控制器与外围器件                        

                                                      


第4章 硬件设计                          
第4章 硬件设计4.1 单片机最小系统设计
基于单片机的硬件设计,首先应当考虑的是如何构建起支撑单片机顺利运行的单片机最小系统。单片机最小系统,或者称为最小应用系统,是指用最少的元件组成的单片机可以工作的系统。对于各式各样的单片机在外围电路方面有一定的差异,而针对本设计所用的STC12C5A60S2单片机属于51系列单片机,其最小系统一般都应该包括:单片机、电源电路、复位电路、晶振电路;此外,针对烧录程序时所有的接口,本设计中还添加了RS232转USB接口的电路设计。
4.1.1 单片机
本次设计采用的这款单片机为STC12C5A60S2,属于增强型的51系列单片机。其功能属性及指标都已在第二章中有过介绍了,故在此不作详细介绍了。以下将主要从其余三个电路部分进行阐述。
4.1.2 电源电路
首先,对于一个完整的电子设计来讲,首要问题就是为整个系统提供电源供电模块,电源模块的稳定可靠是系统平稳运行的前提和基础。51单片机虽然使用时间最早、应用范围最广,但是在实际使用过程中,一个和典型的问题就是相比其他系列的单片机,51单片机更容易受到干扰而出现程序跑飞的现象,克服这种现象出现的一个重要手段就是为单片机系统配置一个稳定可靠的电源供电模块。
此最小系统中电源模块的此最小系统中的电源供电模块的电源可以通过计算机的USB口供给,也可使用外部稳定的5V电源供电模块供给。具体电路原理图如图4-1所示。虽然通用的外部变压器和USB的稳压性能一般均能满足单片机的运行需要,但仍考虑到可能运用到的极端环境中去,可能存在电磁干扰以及电源本身的扰动,故在此并联了一个47uF和一个0.1uF的滤波电容。经实际调试试验,其中电容值较大的电容可以很好的过滤掉低频的杂波,而电容值较小电容可以较好的过滤掉高频的杂波。经此电源退耦电路,Vcc端可以有一个较为平稳的供电电源。符合大多数应用环境,符合本设计的要求。


图4-1 电源供电电路
4.1.3 复位电路
单片机的置位和复位,都是为了把电路初始化到一个确定的状态,一般来说,单片机复位电路作用是把一个例如状态机初始化到空状态,而在单片机内部,复位的时候单片机是把一些寄存器以及存储设备装入厂商预设的一个值。
单片机复位电路原理是在单片机的复位引脚RST上外接电阻和电容,实现上电复位。当复位电平持续两个机器周期以上时复位有效。复位电平的持续时间必须大于单片机的两个机器周期。具体数值可以由RC电路计算出时间常数。
复位电路由按键复位和上电复位两部分组成。如图 4-2所示。
上电复位:STC89系列单片及为高电平复位,通常在复位引脚RST上连接一个电容到VCC,再连接一个电阻到GND,由此形成一个RC充放电回路保证单片机在上电时RST脚上有足够时间的高电平进行复位,随后回归到低电平进入正常工作状态,这个电阻和电容的典型值为10K和10uF。
按键复位:按键复位就是在复位电容上并联一个开关,当开关按下时电容被放电、RST也被拉到高电平,而且由于电容的充电,会保持一段时间的高电平来使单片机复位。


图4-2 复位电路原理图
              此外,STC89C51系列单片机自带有“看门狗”电路。由于单片机的工作有可能会受到来自外界电磁场的干扰,造成程序的跑飞,从而陷入死循环,程序的正常运行被打断,由单片机控制的系统便无法继续工作,这样会造成整个系统陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了“看门狗”电路。其工作过程如下:看门狗芯片和单片机的一个I/O引脚相连,该I/O引脚通过单片机的程序控制,使它定时地往看门狗芯片的这个引脚上送入高电平(或低电平),这一程序语句是分散地放在单片机其他控制语句中间的,一旦单片机由于干扰造成程序跑飞后而陷入某一程序段进入死循环状态时,给看门狗引脚送电平的程序便不能被执行到,这时,看门狗电路就会由于得不到单片机送来的信号,便将它和单片机复位引脚相连的引脚上送出一个复位信号,使单片机发生复位,从而单片机将从程序存储器的起始位置重新开始执行程序,这样便实现了单片机的自动复位。从而,“看门狗”电路很好的弥补了上述复位电路的缺陷,大大的增强了整个系统的可靠性与稳定性。
4.1.4 晶振电路
单片机系统里都有晶振,在单片机系统里晶振作用非常大,全称叫晶体振荡器,他结合单片机内部电路产生单片机所需的时钟频率,单片机晶振提供的时钟频率越高,那么单片机运行速度就越快,单片接的一切指令的执行都是建立在单片机晶振提供的时钟频率。
  在通常工作条件下,普通的晶振频率绝对精度可达百万分之五十。高级的精度更高。有些晶振还可以由外加电压在一定范围内调整频率,称为压控振荡器(VCO)。晶振用一种能把电能和机械能相互转化的晶体在共振的状态下工作,以提供稳定,精确的单频振荡。
单片机晶振的作用是为系统提供基本的时钟信号。通常一个系统共用一个晶振,便于各部分保持同步。有些通讯系统的基频和射频使用不同的晶振,而通过电子调整频率的方法保持同步。
晶振通常与锁相环电路配合使用,以提供系统所需的时钟频率。如果不同子系统需要不同频率的时钟信号,可以用与同一个晶振相连的不同锁相环来提供。
图4-3 晶振电路原理图
STC89C51使用外部的晶体振荡器作为振荡源,考虑到本次设计中对时间的精确性和指令执行速度的要求,该设计选用了22.1184MHz的振荡晶体。由于单片机内部有振荡电路,所以外部只要连接一个晶振和两个电容。具体电路如图4-3所示。电容容量一般在15pF至50pF之间,根据实际使用效果该处选用了30pF的电容,有较高的振荡稳定性。
4.1.5 RS232接口转USB接口电路
由于单片机诞生年代较早,而在当时的工业控制领域大多采用了RS232串行口通信协议,但其存在着传输速率低,传输距离有限和信号电平值较高等问题。现在大多的PC设备基本改用了USB标准协议的通信串口,故为了方便的烧录程序,在常规单片机最小系统的基础之上,应该设计必要的接口转换电路。具体电路原理如图4-4所示。
图4-4 RS232转USB接口电路
该硬件系统由4部分组成:USB接口、CH341T、MAX232和RS232接口。其中,USB接口用于连接USB主机,在此选用USB总线接口的A型连接头;CH341T用于完成USB接口转RS232接口的所有硬件功能;MAX232用于完成RS232与TLL/CMOS的电平转换;RS232接口用于连接RS232设备。根据实际需要,选择目前广泛应用的DB9连接器。
USB总线包括一对5V电源线和一对数据信号线。通常,+5V电源线为红色;接地线为黑色;D+信号线为绿色;D-信号线为白色。USB总线提供的电源电流最大可以达到500 mA,CH341T芯片可以直接使用USB总线提供的5V电源。C3和C4是高频瓷片电容,C3容量一般为4700pF~0.02μF,用于CH341T内部电源节点的退耦;C4容量为0.1μF,用于外部电源的退耦。晶振X1、电容C1和C2用于时钟振荡电路。X1的频率是12 MHz,C1和C2是容量为15~30 pF的高频瓷片电容。MAX232提供电平转换。
4.2 显示电路设计
              液晶显示电路选用了LCD1602模块。从成本和适用性的方面考虑,选用了该集成模块。具体的引脚功能与所采用的芯片资料都已经在3.2节中做了详细介绍,在此只做以下电路说明。
              由于单片机的IO口资源极为有限,而对于这样有较多引脚的外围模块,应当考虑未来是否有扩展的需要,能否直接采用串口连接。对于有扩展必要的设计,可采用相关的芯片进行IO口扩展。而此处作为设计简洁性与成本方面的考虑,其剩余单片机的端口在未来使用过程中,仍然有较大的空间。因此,该部分的设计就直接采用了较少使用的串口连接方式。其7—14号8个数据端口直接与单片机的P0口相连,P0口可以外扩存储器作为地址总线,也可以外存储器扩作为数据总线,也可以不外扩直接作为普通IO口,但内部无上拉电阻,作为输入或输出时应在外部接上拉电阻,因此,在与单片机相连是应该再添加上拉电路。具体连接如图4-5所示。
图4-5 LCD1602连接PO口的上拉电路图
此外,该液晶模块的第3脚为液晶对比度调整端,当接电源时对比度最低,接地时对比度最高,但对比度过高会产生“鬼影”,使用该端口的功能是一般是通过串联一个10K的滑动变阻器进行调节。但在此处,考虑到显示毕竟只是一个辅助显示时间设置信息的工具,而大部分运行的时间,是没有不断调节显示效果的需求的,因此,只在此说明,并不做相应设计。
综上所述,该模块功能虽然比较完备和强大,引脚相比于其他模块也较多,但各个引脚的功能分配比较合理,连接时能够比较清晰的认识该模块的基本结构和工作原理,符合预期设计目标所要求的原则。
4.3 时钟电路设计
              实时时钟功能是本次设计的一个核心部分,它作为整个设计部分的时间信息的基准,其设计的稳定性与精确性就基本决定了该设计的精度与能应用的环境,故其设计的重要性不言而喻。
              本设计中选用了较为常用的DS1302实时时钟模块,其性能属性基本满足了所需设计的要求。其共有Vcc1、Vcc2两个电源引脚,GND接地端,X1、X2两个振荡源连接端,I/O端在三线接口时为双向串行数据线,SCLK为串行时钟端,此外,也自带了RST复位端。具体的电路连接如下图4-6所示。其连接的说明如下。
              首先DS1302的连个电源引脚中Vcc1为后备电源,VCC2为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。因此,在如图所示的电源端连接中,Vcc2直接连接了主板上的5V供电端,而Vcc1和纽扣型电磁相连,作为后备电源,保证了即使在主板断电的情况下仍然能够准确的走时,避免了断电后再次启动需再次设置时间起点,体现了其人性化的设计。
              X1、X2为振荡源连接端口,根据技术手册的说明,此处应当外接32.768kHz的晶振。但时钟芯片要能正常较为精确的计时,则对于晶振的稳定性要求极高,故在此处一般是外接两个6pF的接地电容,能大大的提高其走时准确性。但在此处选用了0.1uF的电容,在实际的测试中发现有一定的偏移。经过查找原因,发现DS1302 是依靠外部晶振与其内部的电容配合来产生时钟脉冲的。 由于DS1302在芯片本身已经集成了6pF 的电容,所以, 为了获得稳定可靠的时钟,必须选用具有 6pF 负载电容的晶振。然而,在选用晶振时仅仅注意了晶振的额定频率值,而忽视了晶振的负载电容大小,甚至连许多经销商也不能提供所售晶振的负载电容。所以即使在 使用中选用了符合 32768Hz 的晶振,但如果该晶振的负载电容与 DS1302 提供的 6pF 不一致时,就会影响晶振的起振或导致振荡频率的偏移,出现上述在应用中的问题。
              I/O、SCLK、RST三个端口构成简单的SPI总线接口,是一般低速外围器件与CPU进行数据传输的典型接口。在主器件的移位脉冲下,数据按位传输,高位在前,低位在后,为全双工通信。RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。当RST为高电平时,所有的数据传送被初始
图4-6 DS1302电路图
化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。在此设计中,三个端口分别于与单片机P1.4、P1.5、P1.6三个端口相连,十分方便。
4.4 红外接收电路设计
              本次设计的中的“无线打开关闭插座”的功能,采用红外遥控的方式实现,其有效距离和有效接收角度均符合一般的应用场景。
在发送端使用了较为常用的采用日本NEC编码的一体化红外遥控按键,其超低的发射功耗和丰富的按键资源,已经足够完成该设计目标。其基本工作原理为利用不同的脉冲时间来编码信号。
红外接收电路使用的是红外一体化接收管VS1838B,它有3个管脚,一个脚接地,还有一个脚接电源,另外一个脚接到单片机的I/O口,本次设计用的是P3.3口,如图4-7所示。通常,红外遥控器将遥控信号(二进制脉冲码)调制在40KHZ的载波上,经缓冲放大后送至红外发光二极管,产生红外信号发射出去。经过空间的传送被红外接收管接收到,在接收过程中,脉冲通过光学滤波器和红外接收管转换为40KHZ的电信号,此信号经过放大,检波,整形,解调,送到解码与接口电路,从而完成相应的遥控功能


图4-7红外接收电路连接图
              需要说明的是,在本设计中,为了实物产品的紧凑,节省空间资源。所以DS1302模块和VS1838B红外接收模块是印制在同一块PCB板上的。电路原理图如图4-8所示。实物图如图4-9所示。


图4-8 DS1302和VS1838B整合电路原理图
图4-9 DS1302和VS1838B整合电路实物图
4.5 继电器控制电路
该部分电路是本电路的输出部分,所选用的继电器型号为SRD-05VDC-SL-C,按照技术手册的说明,其额定的驱动电压为5V,而经过测试单片机端口的实际电压在5V±0.2V的范围内,因此理论上是可以进行直接驱动的。但考虑上电路上如果再串联一个用于开关状态指示的发光二极管,会有一定的压降存在,同时也考虑到要保证被控电路的稳定性,保证被控电路上的电器安全,所以在此不适用直接驱动的连接方式,而是采用了一个三极管的放大电路进行驱动,以下作详细说明。
如图4-10所示,由三极管组成共射极放大电路,二极管D2形成继电器回路保护,其中,继电器触发信号有单片机P1.3口直接产生,并串联有LED-RED发光二极管作为工作状态指示灯。当P1.3口输出高电平时,指示灯亮,继电器吸合,被控电路导通;当P1.3口输出低电平时,继电器断开,指示灯熄灭,被控电路断开。此处,输出功率由继电器上所标示的接点容量决定的。

图4-10 继电器控制电路
4.6 按键电路
                由于本设计中设计到时间设置,模式调整等众多的信息输入,故必然
需要较多的按键完成该功能。其按键本身为机械结构,结构十分简单。且由于该设计中单片机的I/O口剩余较多,因此,按键直接与单片机的I/O口相连。但机械式按键最大的问题是按键时存在严重的信号抖动的问题。对于这个问题,可以直接利用数字电路器件进行消除抖动,也可用波形整形器件进
图4-11 按键电路
行信号整形。以上二者均可以较好的消除问题,但器件的增加无疑会带来制造成本的增加和功耗的增加,因此,通常的办法是采用利用软件编程进行延时消抖,经过实际测试,效果什么良好。连接图如图4-11所示。
4.7本章小结
              本章详细的阐述了硬件电路部分的设计过程,从电源电路、晶振电路、复位电路、RS232转USB接口电路开始搭建了单片机最小系统,接着完成了对显示电路部分、实时时钟电路部分、红外接收电路部分、继电器控制电路部分以及按键电路部分的详细设计,并根据设计原理图详尽的说明了各个部分的设计的合理性以及各个部分所需完成的功能。经过该章的说明,本设计在硬件部分已经完备,接下来只剩下驱动其正常工作的软件设计部分。
                      第5章 软件设计
5.1 主程序设计
系统软件设计采用模块化设计,分为LCD1602显示模块、DS1302读写
图5-1 主程序流程图
模块、红外遥控模块、按键处理模块。通过程序实现的可行性分析和软件架构的整体规划,其主程序的流程图大体如下图5-1所示。
              其中,初始化模块主要是对DS1302时钟芯片、LCD1602液晶显示模块进行任务初始化设置,并打开INT0中断进行红外按键检测和设置T0中断允许状态,以上流程均在主程序最前端,但并不在循环体内,只作为开机启动时初始化的部分。            
接着,进入while( )循环体内以后,因为整个软件结构中,设置模式作为了第一级设置菜单,所以首先应进行当前设置模式的判断,如果有设置模式切换的输入(K5按键),要进行相应的设置模式的切换,然后再进行对当前的设置模式进行显示。            
在显示当前所处的设置模式以后,程序继续向下判断应该进入哪个对应的设置模式。根据不同的判定结果,可进入校时子程序、复位子程序、定时子程序、运行子程序、运行模式切换子程序这些这些子程序中的一个,执行对应的子程序,进行相应的操作。若要进行各个子程序间的切换,可利用设置模式切换的程序进行切换。
在正常工作状态时,系统会一直在运行子程序中进行循环,根据当前运行模式的设定,分别可进入长开模式、长关模式和自动逐组查询的模式,在各个运行模式中分别对受控继电器进行常闭、常开和定时开关的操作。至此,整个主程序的循环体结束,运行流程图指向返回循环体起始点。
5.2 LCD1602显示程序设计
              LCD1602液晶显示程序,在本次设计中并无特别复杂的设计要求,只需要写出最基本的显示驱动程序即可。根据液晶屏的技术手册给出的驱动显示的时序图,即可顺利的写出所需显示驱动。在此,值得注意的问题是,由于液晶的驱动有一定的转换时间延迟,所以在调用该显示驱动时要注意恰到好处的使用延时函数,避免显示乱码。除此之外,对于未用到的字符块,为避免不必要的乱码显示,可在对应空白处写入空格,可有效避免该问题的出现。
              根据显示需要,该模块的程序主要由以下三个函数组成,分别为:
void LCD_init( ); //屏幕初始化
void LCD_writecom(unsigned char com);  //写屏幕的指令
void LCD_writedata(unsigned char dat);  //写屏幕的数据
每一个字符块的显示,均采用先利用LCD_writecom()指令写入函数进行显示位置的设置,再利用LCD_writedata()显示数据函数写入需要显示的字符数据。对于需要在连续位置显示字符的情况,可在一次写入显示地址以后,连续写入显示字符的数据;对于需要在非连续位置显示的字符,则必须在每次写入字符数据之前,写入对应的显示地址。整个显示驱动来说,结构什么简单,调用时也十分方便。
5.3 DS1302实时时钟程序设计
              DS1302是本次设计的核心部分,同样,该部分的软件部分也承担了大部分实现功能的任务。从这部分软件模块的任务规划来说,主要负责了时间信息的输出显示,和校时、定时、复位、模式四种键处理。而其中最为核心的部分为校时部分的程序,定时、复位、时间显示也都均基于校时程序而做部分的操作而构建的。所以,下面将主要展示校时子程序的程序流程图,如下图5-2所示。
              当进入定时子程序以后,DS1302写入暂停标志为1,使时钟进入暂停运行状态,然后进入按位调整时间信息的程序,并且默认首先进入“年”调整位,接着再判断是否有“调整位”切换的输入,如果有,则进入切换程序进行位切换,最后进入判断当前所处的“调整位”。进行“调整位”判定以后,再分别进入“年份调整”、“月份调整”、“日期调整”、“小时调整”、“分钟调整”各个具体的调整子程序,在各个子程序中应当注意的是每一个位的溢出判断要考虑周全,特别是在月份溢出判断中,要进行比较复杂的判定过程。最后,在进行了各个位的调整以后,再将调整后的数据分别写入DS1302各位对应的存储单元,并且在LCD1602上显示出来。DS1302写入走时标志,至此,整个校时的子程序处理结束。
              在前面,说过定时、复位也大都基于校时程序而衍变的。其中,定时子程序与校时子程序不同之处在于,在完成各个位调整以后,并不把其设置的时间信息写入DS1302的存储单元,而是写入单片机的内部扩展的RAM单元,以作开/关时间信息。同时,在进行设置的过程中也不需要暂停走时。这两个子程序的主要区别仅为以上两点,其他部分基本无差异。具体流程图如图5-3所示。
图5-2 校时子程序流程图
图5-3 定时子程序流程图
5.4 VS1838B中断程序设计
              VS18038B红外接收端主要实现的功能是无线打开关闭开关,由于是模块化的器件,功能实现也比较简单。在此处主要说明的是如何采用单片机的中断原理实现红外的接收功能。
              由于发射的红外波是以高低电平时长作为编码信息的,所以在VS1838B接收时,要采用定时/计数器进行对每个码元的高低电平持续时间进行测量。而红外接收端的信号触发采用了外部响应中断方式,一旦有接收到红外信号,就立即进入中断程序。其流程图如图5-4所示。
            


图5-4 VS1838B中断接收程序流程图
由中断的基本原理可知,在进入中断以后,首先进入现场保护。然后在检测到红外信号触发以后,进入外部中断程序,在中断程序中启动定时/计数器T0,开始对每个码元的高低电平进行计时,接着完成解码,根据解码的信息对单片机进行相应控制,此处通过对长开\长关运行模式的切换,以实现无线打开/关闭开关的功能。
5.5 系统测试
经过前面系统的总体设计、控制器和外围模块的介绍、软硬件设计,系统所需实现的功能已基本完成。在此章节中将主要以实验结果为介绍主体,对于测试过程中遇到的问题或漏洞进行总结分析。
首先,进入的是系统第三项设置模式,即定时设置模式,如图5-4所示。
图5-5 定时设置模式下的实物图
同时此刻的运行模式为自动逐组查询模式,如图所示X3。此模式下,可根据需要,自行设定开关在某时刻进行开或者关的操作。例如图种所示为2014年1月1日0点10分打开插座。运行结果如下图5-6和图5-7所示。可以看到,在运行模式为自动逐组查询的模式下,设置时间之前指示继电器开关的LED灯为熄灭状态;而当时间到达设定值以后,指示灯亮,继电器吸合。说明其已基本达到了设计              之初的目标。此外,本设计是可以至少对16组时间点进行定时的,经过测试,完全符合预期目标。
除此之外,可以看到图中的红外线接收头和红外遥控器,设计目标中要求能无线打开关闭插座。此处,在演示的过程中已经体现,完全达到了设计目标。
            


图5-6  自动逐组查询运行模式下到达定时之前的运行图

图5-7 自动逐组查询运行模式下到达定时之后的运行图
5.6 本章小结
              本章介绍了自动定时开关插座的软件设计。首先介绍了整个主程序的工作流程,其主要结构为一个大的循环体,在其循环体内根据当前所处的模式分别进入定时子程序、校时子程序、复位子程序、运行子程序、运行模式切换子程序等子程序,各个子程序之间的切换运行,可通过按键进行切换,也可通过红外遥控按键进行切换。其次,对于各个子程序部分,本章主要详细说明了定时子程序、校时子程序和红外接收中断子程序,其中定时和校时子程序核心部分较为相似,而红外接收中断子程序较为详细的介绍了整个中断过程,体现了中断原理的实际应用。
              最后在完成了对源代码的编译后,对所搭建的硬件实物进行了运行测试,所得的测试结果已基本符合了设计目标。对于测试中遇到的问题,也在调试的过程中进行了修改和完善。
                   结论
本文对当前自动定时开关的相关的背景做了简要介绍,并设计了一种简单实用的自动定时开关插座,完成了自动定时开关整体的硬件设计和软件设计,并经过调试、整合,做出来一套完整的最终产品,达到了预期要求。本系统具有功能完备、使用便捷、应用前景广泛等优点,相比于现有的一些机械式定时开关的产品具有较为完善的功能和实用性,主要成果如下:
(1)本设计采用了51系列单片机来设计了自动定时开关插座,能够较为精确的按照设定的时间值对插座进行开关控制,最多可设置16个时间点的开关控制。
(2)该设计中考虑到了自动定时开关插座运用环境的多样性,故在该设计中添加了红外遥控功能,能无线的打开关闭插座;
(3)完成该设计过程中利用了Keil C51进行了软件编程设计,利用Protues完成了对硬件电路的设计。独立完成了该设计软硬件的设计,并搭电路进行了验证测试。
由于时间以及个人能力有限,本文仅对该领域的产品进行了初步的完善和改进,实现了目前最为需求的功能,以后可做如下改进:
(1)本系统在定时方面,运行的模式只加入了长开、长关和自动查询控制模式,而在这方面可以通过软件的进一步优化,添加更多的运行模式,例如,按星期控制开关的模式、例外情况的工作模式等等。
(2)本系统只设计了对一个继电器开关进行的控制,而从节能和功能完善性方面考虑,也可以同时对多组继电器开关进行控制,进一步的调高了整机的工作效率,提升产品功能。


                                                      
                                                致谢
历时将近两个月的时间终于将这篇文档写完,在文档的写作过程中遇到了无数的困难和障碍,都在同学和老师的帮助下度过了。尤其要强烈感谢我的文档指导老师---xx老师,他对我进行了无私的指导和帮助,不厌其烦的帮助我对设计项目指导和改进。另外,在校图书馆查找资料的时候,图书馆的老师也给我提供了很多方面的支持与帮助。在此向帮助和指导过我的各位老师表示最衷心的感谢!
感谢这篇文档所涉及到的各位学者。本文引用了数位学者的研究文献,如果没有各位学者的研究成果的帮助和启发,我将很难完成本篇文档的写作。
感谢我的同学和朋友,在我写文档的过程中给予我了很多相关素材,还在文档的撰写和排版过程中提供热情的帮助。
由于我的学术水平有限,所写文档难免有不足之处,恳请各位老师和学友批评和指正!


附录4
文献翻译
单片机嵌入式闪存技术的演变
摘要------随着单片机(微型控制单元)的产品大量应用,受各种各样性能需求的驱动,嵌入式闪存技术经历了长足的进步。应用于自动控制时要求高温运行下的高可靠性,应用于智能卡时要求非常低功耗的嵌入式EEPROM,应用于医疗时要求超低电压驱动,这些都是嵌入式闪存发展的驱动因素。与存储单元技术一起发展的是,通过开发专用的设计平台,从而使用优化的嵌入式闪存技术,存储器接口和总线设计,以及整个芯片设计方法,解决了性能/功耗均衡的问题。采用分裂式栅极MONOS(金属氧化氮氧化硅)闪存技术,已经实现了高级单片机产品系列,其广泛应用的产品包括了自动控制和安全领域。
该文档发表在:IC设计与技术(ICICDT),2011年IEEE国际会议,发行日期:2011年5月2日至4日,作者:Hidaka,H.
第一部分
介绍
由于2000年代的前十年间实时控制应用的快速增长,闪存型单片机和采用嵌入式闪存的微控制器,在市场接受度方面有了跨越式的进步。可编码的嵌入式存储器取代片上的掩模只读存储器引发了自适应控制应用和数据流应用的快速增长。随着生产和库存的各个方面成本的降低,相比于不可更改的只读存储器或者使用独立的闪存的单片机,这种进步已经体现了它的创新,具有显著地成本/价值的优势。
采用各种各样的嵌入式闪存技术的闪存型单片机产品挑战着新的市场的驱动者,例如自动控制,智能IC卡,医疗应用,以及那些扩展单片机市场的领域,而交互地嵌入式闪存已经成为在嵌入式存储技术领域中最成功和最大的商业应用,它仅次于带有COMS的嵌入式SRAM。在1990年代,闪存型单片机主要用于调试系统的原型。随着闪存型单片机创新的进步,几乎所有的单片机市场都集中到闪存型单片机解决方案,嵌入式闪存技术演进是最重要的代表。

图1.  以存储器的角度划分的单片机产品的演变过程图
本文回顾了过去和现在的发展状况,并从这些过程中的观点,电路和应用方面,来探索单片机的嵌入式闪存技术在未来的发展方向。创新的因素不同于单独的闪存和一个在以存储器的角度划分的演变图中的未来的单片机概念。
第2部分
嵌入式闪存技术的演变
在图2的存储技术树状图中,这些嵌入式应用对存储技术的选择相当
图2. 闪存和嵌入式闪存技术的演变
的挑剔,因为各个嵌入式应用有其各自的具体的需求。因为单纯的使用高密度闪存技术的数据存储器并不能满足嵌入式应用在可靠性和性能方面的要求,并且嵌入式闪存技术也在不断的自我发展中。
图3. 嵌入式闪存技术.高密度的1Tr-NOR存储单元正被高性能的在1.5Tr/2Tr存储单元所取代。电荷储存单元(Charge-trapping cells)正出现在一些要求可靠性的应用里
这两种技术的转换特性对嵌入式闪存技术来说是至关重要的(图3):
1.1T单元到1.5T(分裂栅结构)和2T单元拥有高性能/低功耗的优点,而
2.离散的电荷储存单元技术(MONOS和Nano-dot)拥有更高的可靠性的优点。
这些趋势已经表明正从标准化的单一的闪存产品(例如NAND-flash存储器)开始衍变。虽然传统的浮栅型的NOR结构仍将在一些高密度的嵌入式应用中继续使用,但是由于单片机市场细分的多元化需求,预计不久将普遍性的使用分裂栅结构和电荷储存结构。
考虑到分裂栅结构和的相关先进的COMS逻辑晶体管的兼容性,首先是接入门是更好的选择(最后是控制栅),因为它是唯一的由一个薄膜电荷捕获存储层实现,而不是通过层叠浮动栅极结构。这可能表明其未来技术的融合点在于分裂栅单元和电荷储存单元结构中。这种选择的优点已经在90nm的CMOS逻辑平台上的实验被证明。
第3部分
最先进的单片机设计
除了利用闪存型单片机的可编程性的特点,通过设计,生产和库存控制来全面的降低成本,同时也因为“嵌入式”的高性能和高数据安全性,嵌入式正被优先选择使用。嵌入式闪存的优势和可能的缺点都列在了表1中。产品的设计应该考虑利用嵌入式闪存的特性所带来的整体成本和价值优势,克服更高的晶片制造成本的缺点。通常,只有在统一的设计平台上利用优化的嵌入式闪存的宏命令,更多元化的单片机产品系列才能更有效的被支持。
通过减小设备的尺寸和电路技术的发展,稳步的发展趋势已经在自动控制领域的单片机应用中得以体现,十年间CPU性能增长了20倍,ROM容量增长了8倍。由于受限于其较小的系统芯片和一些需要在较高温度下运行的特定的技术要求,单片机的技术的发展力度并没有最前沿的SOC系统那样大。
                嵌入式闪存的优点:
      -通过内部访问路径
                 (1)快速,低功耗
      (2)高数据安全性
      (3)高可靠性,低电磁干扰,低系统开销
      (4)更高的设计自由度
存储容量,接口,设计的功能和运行电压
           -通较低的激活率,相当于加装发热冷却器
                     -有助于优化大规模集成电路功能和成本
    可能的嵌入式闪存的缺点:
     (1)大、小容量的存储器的成本较高
         (由于其低密度,较高的生产成本)
    (2)由于非标准化带来的成本开支
(3)单一的资源
    (4)多种类型的存储器整合困难
表1.和单独的闪存相比嵌入式闪存的优点和可能的缺点
当前最先进的单片机设计的要求实例如表2.所示。因为单片机中的嵌入式闪存需要很高的访问速度以满足CPU的执行速度,在许多应用中都以性能需求为设计方向进行设计,这点与单独的闪存产品是大为不同的。同时,数据可靠性与耐高温特性和低漏电特性一样,它们都是大多数单片机应用产品的重要指标。
下面描述了当前细分的单片机市场和嵌入式闪存规格的要求
1.自动控制的应用产品,如传动系统需要有高密度,耐高温,有高可靠性的嵌入式闪存设计。利用当前最先进的分层传感设计,优化存储分块和高可靠性的存储单元技术,在嵌入式闪存中随机存取速度能高达10ns达到160?(max),以适用于这种应用环境。
2.防止破解攻击的安全功能设计在单片机智能IC卡产品设计中是占比很大的一个部分。用于数据操作的嵌入式EEPRROM,在编程和擦除时要具有相当快的速度和较低驱动电压,这在非接触式智能卡中是必不可少的要求,因此,这使得在这个领域中对嵌入式闪存技术的选择是非常挑剔的。
图4.高端自动控制产品市场中CPU和嵌入式闪存性能需求趋势
3新型的医疗/保健应用产品需要具有能超低电压驱动或超低功耗的单片机产品。未来,嵌入式闪存的编程/擦除对于高级医疗产品中数据流的收集和存储操作是很有必要的。

图5.高端自动控制产品市场中嵌入式闪存性能需求趋势

表2.单片机产品中对嵌入式闪存的要求
这些需求的例子表明了多元化的单片机产品系列,意味着对嵌入式闪存的性能和功能有着的很广的期望,在技术/电路/系统方面还有很多东西需要探索和开发利用。
图6.描述了在嵌入式闪存设计中的关键的结构和电路技术。在代码存储应用程序中频繁读取的代码,非升压字线利用分裂栅单元结构有望提高随机读取访问速度和低功耗。在充电泵电路的编程/擦除操作会显著影响嵌入式闪存的低功耗设计。因为闪存技术在降低编程/擦除电压方面存在固有的缺点,因此,高能效的编程/擦除算法和优化产生的高压波形来缓解过度功耗的问题对于节能设计是非常重要的。
图7.展示了目前使用分裂栅MONOS嵌入式闪存技术的单片机产品系列,在芯片上500k的EEPROM的编程/擦除容量以高达100MHz的读取访问都低于Tj=160(max)。电池驱动的运行电压范围低至1.62V。
图6.嵌入式设计中主要的考虑方向
图七. 90nm闪存型单片机产品
第四部分
节能型非易失性存储器的影响
节能系统需要能以低耗能的方式频繁的重写非挥发性存储器。当待机丢失的问题在高级的大规模集成电路系统中成为一个关键的问题时,通过间歇性的电源开关方案(图.8),即将频繁的开关空转状态转换为关机状态,因此,嵌入式非易失性存储器在降低系统功耗方面将发挥重要作用。频繁的电源开/关需要频繁的非易失性存储和电路状态与数据的检索。在这里,非易失性存储器需要高速且又节能的重写性能。
图.8间歇性系统运行方案和常规关闭方案
图.9描述了与电磁型RAM相比,各种嵌入式闪存技术的重写速度和能耗。因为在功耗控制方案上各个系统的要求多种多样,但所有当前的嵌入式闪存和下一代的非易失性存储器都适合用于间歇性的电源控制应用。但是,高效省电的方案将要求能立即存储和检索电路的状态,且在芯片上要支持分布式的高速非易失性存储。新兴的非易失性存储器具有一个意义非凡的特性,即利用其高速和低电压的重写能力(图.10),它的每比特重写的能耗比现有的嵌入式闪存低了好几个数量级,这一点可以有效的被开发利用。

图.10 非易失性存储器的重写性能.重写频率范围覆盖系统中的电源开/关方案
参考文献:
[1] S. Kianian et al., Symp. VLSl Tech. Dig. Tech. Papers, pp.71-72 (1994).
[2] B. Eitan et al., Proc. Int. Conf. Solid State Devices and Materials,
     pp. 522-524 (1999).
[3] J. A. Yater et al., NVSMW, pp. 77-78 (2007).
[4] H. M. Lee et al., Dig. NVSMW, pp. 15-16 (2006).
[5] K. Baker, Proc. ICICDT, pp.185-189 (2009).
[6] J. A. Yater et al, International Memory Workshop (2009).
[7] W. Stenzl and J. Hupper, in EE-Times Europe, March 17 (2008).
                                                      


附录4                           
[8] M. Hatanaka and H. Hidaka, Proc. Tech. Papers, ASSCC, pp.38-41 (2007).
[9] H.Hidaka, in chap. 7, ed. K. Zhang, “Embedded memories for nano scale VLSI”, Springer (2009).
[10] M. Zwerg et al., Dig. Tech. Papers, ISSCC, pp. 334-335 (2011).


Evolution of embedded flash memory technology for MCU
Embedded flash memory technology has undergone tremendous growth of demands with various performance requirements driven by expanded applications of MCU (Micro Controller Unit) products. High temperature operations with highest reliability for auto-motive applications, very low power embedded EEPROM functions for smart-cards, and ultra low-voltage operations for medical applications are driving factors in developing embedded flash technologies. Together with evolving memory cell technology, resolving performance/power trade-offs by developing dedicated design platforms with optimized eFlash technology, memory interface & bus designs, and the whole chip design methodologies, has realized advanced MCU products line-ups by split-gate MONOS flash technology with a wide range of applied products including auto-motive and security applications.
This paper appears in: IC Design & Technology (ICICDT), 2011 IEEE International Conference on, Issue Date: 2-4 May 2011, Written by: Hidaka, H.
SECTION I
INTRODUCTION
Flash-MCU, Micro-Controller Unit with embedded flash memory storage (eFlash), has made a leaping progress in the market acceptance according to the expansion of real-time control applications in 2000's. The programmable code storage by eFlash in place of on-chip mask-ROM has triggered rapid expansion of adaptive control and data stream applications. Together with over-all production and inventory cost reduction, this development has realized an innovation with remarkable cost/value advantage over MCU with fixed ROM or MCU with stand-alone flash memory.
Diversified eFlash technologies for flash-MCU products have challenged new market drivers such as auto-motive, smart-IC card, and medical applications and
have expanded the MCU market, while alternately eFlash has become the most successful, largest business in embedded memory technology only second to CMOS-inclusive embedded SRAM. In 1990's Flash-MCU was mainly used in proto-types for debugging systems. With the advancement of Flash-MCU innovation, almost all the MCU market has been focused onto flash-MCU solutions (Fig. 1), where eFlash technology evolution represents the most important factor.


Fig. 1. Evolution of MCU products in a memory-centric view.
This paper reviews the past and current status and explore the future directions of eFlash technology for MCU, from the viewpoints of process, circuit, and applications. Innovative factors different from stand-alone flash memory and a future MCU concept in the memory-centric view are also presented.
SECTION II
EVOLUTION OF EMBEDDED FLASHTECHNOLOGY
In the flash memory technology tree in Fig. 2, those suitable for embedded uses have been quite selective because of requirements specific to embedded uses. Because high-density flash technologies for stand-alone data memory don't meet the requirements for embedded uses in reliability and performance, eFlash technologies have evolved on its own.
Fig. 2. Evolution of Flash and eFlash memory technologies.
Fig. 3. Embedded flash memory technologies. 1Tr-NOR cells for high density are giving way to 1.5Tr/2Tr cell for performance. Charge-trapping cells are emerging in some applications for reliability.
Two technology transitions specific to eFlash technologies have been remarkable (Fig. 3):
1T cell to 1.5T (split-gate structure) and 2T cells for high-performance/low power, and Discrete charge-trapping cell technology (MONOS and Nano-dot[5]) for higher reliability.
These trends prove a deviation from the standardized standalone flash memory products such as NAND-flash memories. Although the conventional floating-gate NOR structure will survive in some of the high-density embedded uses, pervasive use of split-gate and charge-trapping storage structures are expected according to the requirements by diversified MCU market segments.
Considering the structural compatibility of the split-gate with advanced underlying CMOS logic transistor, Access-Gate first (Control-Gate last), which is only realized by a thin-film charge-trapping storage layer, not by stacked floating gate structure, is preferred. This may indicate that the technological convergence point lies in the split-gate, charge-trapping cell structure in the future. The advantage of this choice has been proved by the implementation in the CMOS logic platforms at 90nm[6],[7].
SECTION III
STATE-OF-THE-ART MCU DESIGN
In addition to the over-all cost reduction through design, production and inventory control by programmability in Flash-MCU, the “embedded-ness” is favorably utilized for high performance and data security properties. The advantages and possible drawbacks of embedded flash memory are listed in Table. 1. Product design should consider utilizing embedded flash properties with the overall cost and value advantages over-coming drawbacks of higher wafer process cost to incorporate flash memory. In general much diversified MCU product line-ups are efficiently supported only by a unified design platform to employ optimized eFlash macros.
By scaling the device and by circuit developments, a steady scaling trend has been realized in the auto-motive applications of MCUs (Figs. 4 and 5), with x20 CPU performance growth by 10 years and x8 ROM capacity growth by 10 years. The technology node development for MCU is not so aggressive as most-advanced SOCs because of the smaller system on the chip and somewhat tailored technology for required higher temperature operations.
TABLE1. ADVANTAGESAND POSSIBLE DRAWBACKSOF EMBEDDED FLASH MEMORY,ASCOMPARED WITH STAND-ALONE FLASH MEMORY.
Example requirements to current state-of-the-art MCU designs are shown in Table.2. Because eFlash in MCU is inherently required a high-speed access to meet the CPU execution speed, performance-oriented design is required in many applications, which is quite different from stand-alone flash memory products. Also data reliability as well as high-temperature and low-leakage product strategy are important factors in most of MCU applications.
Requirements here describe the natures of current MCU market segments as well as eFlash specifications.
  •          Auto-motive applications such as power-train require high-density, high-temperature and highly reliable eFlash designs. A random access as fast as 10ns at 160 ?(max) in eFlash is achieved by the current state-of-the-art design with hierarchical sensing, optimized memory mat division, and highly reliable memory cell technology to fit this application.
  •          Security functions against attacks account for a large portion of the MCU design for smart-IC card applications. Embedded EEPROM for data manipulation functions with quite fast and low-power program/erase operation is essential in non-contact smart-cards, which makes this field of application very selective in the choice of eFlash technologies.
  •          Very low-voltage/low-power MCU products are required for emerging medical/health-care applications with battery operations. eFlash program/erase is necessary in the future data collection and storage for data streaming operations in the advanced health-care environments.


Fig. 4. Performance trend in CPU and eFlash for high-end auto-motive market.


Fig. 5. Trend in eFlash capacity for high-end auto-motive market.


TABLE.2. REQUIREMENTS FOR EMBEDDEDFLASH MEMORY IN MCU APPLICATIONS.
These sample requirements indicate much diversified MCU product line-ups, suggesting very wide expectations to eFlash performance and functions, much to be explored and exploited in technology/circuit/system developments.
Fig. 6 depicts key architecture and circuit technologies in eFlash designs. In frequent read operations in the code storage applications, non-boosted word-line utilizing a split-gate cell structure is promising to enhance the random read access speed and for low-power consumptions. Lowe-power design in eFlash is strongly affected by the charge-pumping circuitry in program/erase operations. Because flash memory technologies have inherent difficulty in scaling down the program/erase voltage, energy-efficient program/erase algorithms and optimally generated high-voltage waveforms to mitigate excessive power consumption are important in power-aware designs.
Fig. 7 shows a current MCU product line-up employing a split-gate MONOS eFlash technology, with up to 100MHz read access at code storage with 500K program/erase capability in EEPROM on the chip, all under. The operating voltage ranges down to 1.62V for battery operations.
Fig. 6. Key considerations in eFlash design[8], [9].
Fig. 7. 90nm flash-MCU products.
SECTION IV
IMPACT OF ENERGY-EFFICIENT NV-MEMORY
Energy-efficient system approaches require low-energy frequent re-write performance of non-volatile memories. As the stand-by leakage problem has emerged as a critical factor in the advanced LSI systems, embedded non-volatile memory will play more important roles in reducing the system power by intermittent power switching schemes (Fig. 8), to frequently switch idling states into power-off states. Frequent power On/Off necessitates frequent non-volatile store and retrieval of circuits states and data. Fast and energy-efficient re-write is required for non-volatile memories in this context.
Fig. 8. Intermittent system operations with normally off schemes.
Fig. 9 describes re-write speed and energy in various eFlash technologies compared with Magnetic-RAM. Because system requirements are diverse in power control schemes, all the current eFlash and next-generation NV-memories are good for uses in intermittent power control applications. However, efficient power-down schemes will store and retrieve circuit states instantly, favoring distributed fast non-volatile storage on the chip. One remarkable feature realized by emerging NV memory is orders-of-magnitude lower energy per bit re-write than existing eFlash by fast and low-voltage re-write capabilities (Fig. 10), which can be exploited effectively[10].
Programmability provided on the chip has been an important factor in the design and cost structure of LSI (Table 3). Beginning with the ROM-based logic operated by stored instructions in the CPU, alterable/reconfigurable logic organizations have emerged in the 2nd stage, where the main players are Flash-MCU and re-configurable logic products. The 3-rd stage realized by NV-RAM will see a much broader possibility of innovation by energy-efficient NV memories.
SECTION V
CONCLUUSIONS
Flash-MCU has achieved a rapid market penetration attributed to the leap in value/cost for innovation by virtue of evolving eFlash technologies. eFlash cell and circuit technologies will see some convergence points quite different from stand-alone flash memory, according to diversified market requirements. Designs of energy-efficient MCU and of MCU for energy-efficient systems will be the next focus of technology, circuit, and system co-development in emerging applications, where non-volatile memory technologies will play important roles in the scaled LSI environments.
Fig. 9. Re-write performance by energy/bit in various eFlash and MRAM. Re-write energy and time by memory cell and periphery circuitry.
Fig. 10. Re-write performance by non-volatile memories. Re-write frequency requirement ranges over power On/Off schemes in the system.
TABLE 3. EVOLUTION OF ON-Chip Programmability[9].
ACKNOWLEDGEMENT
The author would like to express sincere thanks to all the members of Embedded Memory Core Development Division, Renesas Electronics Corp. for their supports.
REFERENCES
1. S. Kianian et al., Symp. VLSl Tech. Dig. Tech. Papers, pp.71-72 (1994).
2. B. Eitan et al., Proc. Int. Conf. Solid State Devices and Materials, pp. 522-524 (1999).
3. J. A. Yater et al., NVSMW, pp. 77-78 (2007).
4. H. M. Lee et al., Dig. NVSMW, pp. 15-16 (2006).
5. K. Baker, Proc. ICICDT, pp.185-189 (2009).
6. J. A. Yater et al, International Memory Workshop (2009).
7. W. Stenzl and J. Hupper, in EE-Times Europe, March 17 (2008).
8. M. Hatanaka and H. Hidaka, Proc. Tech. Papers, ASSCC, pp.38-41 (2007).
9. H.Hidaka, in chap. 7, ed. K. Zhang, "Embedded memories for nano scale VLSI", Springer (2009).
10. M. Zwerg et al., Dig. Tech. Papers, ISSCC, pp. 334-335 (2011).

附录5
硬件电路原理图
附录6
程序源代码
主程序



  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include "delay1ms.h"
  4. #include "ds1302.h"
  5. #include "display.h"
  6. #define uchar unsigned char;
  7. unsigned char code digit1[11]={"0123456789-"};     //定义字符数组显示数字,主要用于LCD 的显示
  8. unsigned char code digit2[2]={"GK"};                //digit[0]断开,digit[1]闭合
  9. unsigned char code digit3[16]={"0123456789ABCDEF"};
  10. unsigned char keyflag=4; //判断键盘是否有输入              ?
  11. unsigned char QH_FLAG1=1;
  12. extern unsigned char model_flag;//长开,长关,自动,模式标志
  13. unsigned char xdata dings[16][7]={{0,0,0,1,1,0,14},{0,0,0,1,1,0,14}, {0,0,0,1,1,0,14},{0,0,0,1,1,0,14}, {0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14},{0,0,0,1,1,0,14}, {0,0,0,1,1,0,14}};                                          //0年,0周,0月,0日,0时,0分,0秒
  14. char xdata dings_kaig[16]={0,0,0,0,
  15.                                                                                              0,0,0,0,
  16.                                                                                                        0,0,0,0,
  17.                                                                                                        0,0,0,0};                //0断开,1闭合
  18. char time_buf1[7] ={0,0,0,0,0,0,0};
  19. unsigned char time_buf2[7] ={0,0,0,0,0,0,0};
  20. unsigned char second1,minute1,hour1,day1,month1,year1;      //分别储存苗、分、小时,日,月,年
  21. unsigned char open_close_pd=1;
  22. sfr AUXR=0x8e;
  23. bit K1_FLAG1=0;                                                        //定义按键标志位,当按下K1键时,该位置1,K1键未按下时,该位为0。
  24. unsigned char ReadValue1;
  25. unsigned char ReadValue2;
  26. unsigned char i=0;//i 用于for循环
  27. unsigned char j;//j 用于for循环
  28. unsigned char k=0;//k用于调整数组数目
  29. void KeyProcess1();
  30. void main()
  31. {
  32.    RELAY=0;//默认继电器断开
  33.    model_flag=3;
  34. /************************************************************
  35. 函数功能:红外初始化
  36. ************************************************************/
  37.                     EA=1;        //开启总中断
  38.        EX1=1;       //开外中断1
  39.        ET0=1;       //定时器T0中断允许
  40.        IT1=1;       //外中断的下降沿触发
  41.        TMOD=0x01;   //使用定时器T0的模式1            
  42.                  TR0=0;       //定时器T0关闭
  43. /**********************************************************/
  44.    int_ds1302();
  45.    LCD_init();
  46.    delay1ms(1);
  47.    while(1)
  48.   {
  49.                 LCD_writecom(0x41+0x80);  // 设置显示x位置为第一行的第1个字
  50.      delay1ms(10);
  51.      LCD_writedata(digit1[model_flag]);
  52.               LCD_writecom(0x4f+0x80);  // 设置显示x位置为第一行的第1个字
  53.      delay1ms(10);
  54.      LCD_writedata(digit1[keyflag]);
  55.               if(K5==0)
  56.               {
  57.                             delay1ms(10);
  58.                             while(!K5);
  59.                             Ds1302_beep();
  60.                             keyflag++;
  61.                             if(keyflag>4)
  62.                             keyflag=1;
  63.               }
  64.               if(keyflag==1)                               //校时
  65.               {
  66.                  time_get_show();
  67.                  Ds1302_QLShow();
  68.               }
  69.               if (keyflag==2)                                          //复位和模式切换
  70.               {
  71.                             if(K4==0)                                             //k4 复位
  72.                               {
  73.                                             delay1ms(10);
  74.                                             while(!K4);
  75.                                           Ds1302_beep();
  76.                                           write_ds1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令
  77.                                              write_ds1302(0x80,((00/10)<<4|(00%10)));   //根据写秒寄存器命令字,写入秒的初始值
  78.                                           write_ds1302(0x82,((00/10)<<4|(00%10)));   //根据写分寄存器命令字,写入分的初始值
  79.                                           write_ds1302(0x84,((00/10)<<4|(00%10))); //根据写小时寄存器命令字,写入小时的初始值
  80.                                           write_ds1302(0x86,((1/10)<<4|(1%10))); //根据写日寄存器命令字,写入日的初始值
  81.                                           write_ds1302(0x88,((1/10)<<4|(1%10))); //根据写月寄存器命令字,写入月的初始值
  82.                                           write_ds1302(0x8c,((14/10)<<4|(14%10)));  //根据写年寄存器命令字,写入年的初始值
  83.                                           write_ds1302(0x90,0xa5);                //打开充电功能 选择2K电阻充电方式
  84.                                           write_ds1302(0x8E,0x80);                                             //根据写状态寄存器命令字,写入保护指令
  85.             for(i=0;i<16;i++)
  86.                                           {dings_kaig[i]=0;}
  87.                                           for (i=0;i<16;i++)
  88.                                                         for(j=0;j<7;j++)
  89.                                                         {dings[i][j]=0;}
  90.                                               model_flag=1;
  91.                                           }
  92.                             if(K3==0)                                             //K3模式切换
  93.                               {               
  94.                                delay1ms(10);
  95.                                while(!K3);
  96.                                Ds1302_beep();
  97.                                model_flag++;
  98.                                if( model_flag>3)
  99.                                { model_flag=1;}
  100.                                }                           
  101.                             time_show();
  102.                             Ds1302_QLShow();
  103.               }
  104.                 if(keyflag==3)
  105.               {
  106.                
  107.                  if(K1==0)
  108.                  {
  109.                   delay1ms(10);
  110.                             if(K1==0)
  111.                             {
  112.                               while(!K1);
  113.                               Ds1302_beep();
  114.                               k++;
  115.                     if(k>15)
  116.                       {k=0;}
  117.                               QH_FLAG1=1;
  118.                                }               
  119.        }
  120.                  LCD_writecom(0x4e+0x80);  // 设置显示x位置为第一行的第1个字
  121.        delay1ms(10);
  122.        LCD_writedata(digit3[k]);              //显示第几组的时间设定值
  123.                  for(j=0;j<7;j++)
  124.                             { time_buf1[j]=dings[k][j];              }
  125.                  KeyProcess1();
  126.                  LCD_writecom(0x42+0x80);    //显示三个空格防止乱码
  127.                  delay1ms(1);
  128.                  LCD_writedata(' ');   
  129.                  delay1ms(1);                                                  //延时1ms给硬件一点反应时间
  130.                   second1=dings[k][0];
  131.                               Ds1302_DisplaySecond(0);          //显示秒
  132.                               minute1=dings[k][1];
  133.                             Ds1302_DisplayMinute(minute1);                     //显示分
  134.                    hour1=dings[k][2];
  135.                               Ds1302_DisplayHour(hour1);                           //显示小时
  136.                    day1= dings[k][3];
  137.                               Ds1302_DisplayDay(day1);                //显示日
  138.                               month1=dings[k][4];
  139.                               Ds1302_DisplayMonth(month1);            //显示月
  140.                               year1=dings[k][6];
  141.                               Ds1302_DisplayYear(year1);              //显示年
  142.                             LCD_writecom(0x4c+0x80);    //写显示地址,将在第2行第7列开始显示
  143.                   delay1ms(1);
  144.                   LCD_writedata(digit2[dings_kaig[k]]);    //将百位数字的字符常量写入LCD
  145.                             Ds1302_QLShow();//在对应位置显示date ——
  146.                                }            
  147.                  if(keyflag==4)                                                          //无输入模式
  148.                  {
  149.                                time_show();
  150.                             Ds1302_QLShow();
  151.                             switch(model_flag)
  152.                                           {
  153.                                           case 1:                                          //长开模式              ,一直闭合
  154.                                           RELAY=1;
  155.                                           LCD_writecom(0x4c+0x80);
  156.                                           delay1ms(5);
  157.                                           LCD_writedata(digit2[1]);
  158.                                           break;
  159.                                           case 2:                                          //长关模式 ,一直断开
  160.                                           RELAY=0;
  161.                                           LCD_writecom(0x4c+0x80);
  162.                                           delay1ms(5);
  163.                                           LCD_writedata(digit2[0]);
  164.                                           break;                              
  165.                                           case 3:                                          //自动模式
  166.                                                         ReadValue2=read_ds1302(0x8d);                            //年
  167.                                                         time_buf2[6]=((ReadValue2&0xf0)>>4)*10 + (ReadValue2&0x0F);//将读出数据转化
  168.                                                         ReadValue2=read_ds1302(0x89);                            //月
  169.                                                         time_buf2[4]=((ReadValue2&0x70)>>4)*10 + (ReadValue2&0x0F);//将读出数据转化
  170.                                     ReadValue2=read_ds1302(0x87);                            //日
  171.                                                         time_buf2[3]=((ReadValue2&0x70)>>4)*10 + (ReadValue2&0x0F);//将读出数据转化
  172.                                                         ReadValue2=read_ds1302(0x85);                            //              时
  173.                                                         time_buf2[2]=((ReadValue2&0x70)>>4)*10 + (ReadValue2&0x0F);//将读出数据转化
  174.                                     ReadValue2=read_ds1302(0x83);                              //分
  175.                                                         time_buf2[1]=((ReadValue2&0x70)>>4)*10 + (ReadValue2&0x0F);//将读出数据转化                                          //自动模式
  176.                                           for(i=0;i<16;i++)
  177.                                                         {
  178.               if((time_buf2[6]==dings[k][6])&&(time_buf2[4]==dings[k][4])&&(time_buf2[3]==dings[k][3])&&(time_buf2[2]==dings[k][2])&&(time_buf2[1]==dings[k][1]))
  179.                                                                                       {if(dings_kaig[k]==1)
  180.                                                                                        open_close_pd=1;
  181.                                                                                        else
  182.                                                                                        open_close_pd=0;
  183.                                                                                     }                           
  184.                                                         }
  185.                                                         RELAY=open_close_pd;
  186.                                                         LCD_writecom(0x4c+0x80);
  187.                                                         delay1ms(5);
  188.                                                         LCD_writedata(digit2[open_close_pd]);
  189.                                           }
  190.                  }
  191. }
  192. }  
  193.   /********以下是定时按键处理函数********/
  194. void KeyProcess1()
  195. {
  196.     write_ds1302(0x8e,0x00);                                            //ds13202寄存器允许写

  197.    if(K2==0)                               //K2键调整所要的位,向右企切换年月日
  198.   {
  199.                 delay1ms(10);                                                        //延时去抖
  200.                 if(K2==0)
  201.                 {
  202.                                           while(!K2);                                                                                    //等待K2键释放
  203.                                           QH_FLAG1++;
  204.                                           if(QH_FLAG1>6)
  205.                                           { QH_FLAG1=1;
  206.                                           }            
  207.               }
  208.   }                             
  209.                  switch(QH_FLAG1)
  210.                             {case 1:
  211.                                     LCD_writecom(0x4d+0x80);  // 设置显示位置为第一行的第1个字
  212.                 delay1ms(1);
  213.                                                         LCD_writedata('Y');
  214.                                                         delay1ms(1); break;
  215.                             case 2:
  216.                                     LCD_writecom(0x4d+0x80);  // 设置显示位置为第一行的第1个字
  217.                 delay1ms(1);
  218.                                                         LCD_writedata('M');
  219.                                                         delay1ms(1);  break;
  220.                    case 3:
  221.                                     LCD_writecom(0x4d+0x80);  // 设置显示位置为第一行的第1个字
  222.                 delay1ms(1);
  223.                                                         LCD_writedata('D');
  224.                                                         delay1ms(1);  break;
  225.                               case 4:
  226.                                     LCD_writecom(0x4d+0x80);  // 设置显示位置为第一行的第1个字
  227.                 delay1ms(1);
  228.                                                         LCD_writedata('H');
  229.                                                         delay1ms(1);  break;
  230.                               case 5:
  231.                                     LCD_writecom(0x4d+0x80);  // 设置显示位置为第一行的第1个字
  232.                 delay1ms(1);
  233.                                                         LCD_writedata('F');
  234.                                                         delay1ms(1);  break;
  235.                               case 6:
  236.                                                           LCD_writecom(0x4d+0x80);  // 设置显示位置为第一行的第1个字
  237.                 delay1ms(1);
  238.                                                         LCD_writedata('S');
  239.                                                         delay1ms(1);  break;
  240.                             }                                                  
  241.     if(K3==0)                              // K3键用来进行加1调整
  242.               {
  243.                             delay1ms(10);                      //延时去抖
  244.                     if(K3==0)                              
  245.                             {
  246.                                           while(!K3);                                                                                    //等待K3键释放
  247.                                           switch(QH_FLAG1)
  248.                             {              case 1:      
  249.                                           time_buf1[6]=time_buf1[6]+1;                                   //年加1
  250.                                    if(time_buf1[6]>99) time_buf1[6]=0;                             //当年加到60时初始化为0
  251.                         dings[k][6]=time_buf1[6];
  252.                                 break;
  253.                                           case 2:      
  254.                                           time_buf1[4]=time_buf1[4]+1;                                   //月加1
  255.                                    if(time_buf1[4]>12) time_buf1[4]=1;                             //当分钟加到60时初始化为0
  256.                         dings[k][4]=time_buf1[4];
  257.             break;
  258.                                           case 3:      
  259.                                           time_buf1[3]=time_buf1[3]+1;         //日加1               
  260. if((time_buf1[4]==1)||(time_buf1[4]==3)||(time_buf1[4]==5)||(time_buf1[4]==7)||(time_buf1[4]==8)||(time_buf1[4]==10)||(time_buf1[4]==12))
  261.                                              {if(time_buf1[3]>31)
  262.                                                             time_buf1[3]=1;
  263.                                                         }
  264.                             if((time_buf1[4]==4)||(time_buf1[4]==6)||(time_buf1[4]==9)||(time_buf1[4]==11))
  265.                                              {if(time_buf1[3]>30)
  266.                                                             time_buf1[3]=1;
  267.                                                         }
  268.                                           if(time_buf1[4]==2)
  269.                                           {              if((time_buf1[6]%4)&&(time_buf1[3]>28)) time_buf1[3]=1;
  270.                                               if(!(time_buf1[6]%4)&&(time_buf1[3]>29)) time_buf1[3]=1;
  271.                                           }
  272.                                           dings[k][3]=time_buf1[3];
  273.                                  break;
  274.                                           case 4:      
  275.                                           time_buf1[2]=time_buf1[2]+1;                                   //小时加1
  276.                                    if(time_buf1[2]>23) time_buf1[2]=0;                             //当分钟加到60时初始化为0
  277.                         dings[k][2]=time_buf1[2];
  278.                                           break;
  279. case 5:      
  280.                                           time_buf1[1]=time_buf1[1]+1;                                   //小时加1
  281.                                    if(time_buf1[1]>59) time_buf1[1]=0;                             //当分钟加到60时初始化为0
  282.                         dings[k][1]=time_buf1[1];
  283.                                           break;
  284.                                           case 6:
  285.                                             dings_kaig[k]=dings_kaig[k]+1;
  286.                                             if(dings_kaig[k]>1)
  287.                                             dings_kaig[k]=0;
  288.                                             LCD_writecom(0x4c+0x80);    //写显示地址,将在第2行第7列开始显示
  289.                         delay1ms(1);
  290.                         LCD_writedata(digit2[dings_kaig[k]]);    //将百位数字的字符常量写入LCD
  291.                                           }
  292.                                           delay1ms(500);                              //以下为连发功能  约0.5s触发连发功能
  293.                                           while(K3==0)                                            
  294.                                           {
  295.                                                         delay1ms(150);                //150ms加一次
  296.                                           switch(QH_FLAG1)
  297.                             {              case 1:      
  298.                                           time_buf1[6]=time_buf1[6]+1;                                   //年加1
  299.                                    if(time_buf1[6]>99) time_buf1[6]=0;                             //当分钟加到60时初始化为0
  300.                        
  301.                                           dings[k][6]=time_buf1[6];
  302.                                           LCD_writecom(0x07+0x80);    //写显示地址,将在第2行第7列开始显示
  303.                       delay1ms(1);               
  304.                       LCD_writedata(digit1[time_buf1[6]/10]);    //将百位数字的字符常量写入LCD,不能直接写入,必须转化
  305.                       delay1ms(1);
  306.                       LCD_writedata(digit1[time_buf1[6]%10]);    //将十位数字的字符常量写入LCD
  307.                       delay1ms(1);
  308.                                           break;
  309.                                           case 2:      
  310.                                           time_buf1[4]=time_buf1[4]+1;                                   //月加1
  311.                                    if(time_buf1[4]>12) time_buf1[4]=1;                             //当分钟加到60时初始化为0
  312.                         dings[k][4]=time_buf1[4];
  313.                          break;
  314.                                           case 3:      
  315.                                           time_buf1[3]=time_buf1[3]+1;         //日加1               
  316.                                           if((time_buf1[4]==1)||(time_buf1[4]==3)||(time_buf1[4]==5)||(time_buf1[4]==7)||(time_buf1[4]==8)||(time_buf1[4]==10)||(time_buf1[4]==12))
  317.                                              {if(time_buf1[3]>31)
  318.                                                             time_buf1[3]=1;
  319.                                                         }
  320.                             if((time_buf1[4]==4)||(time_buf1[4]==6)||(time_buf1[4]==9)||(time_buf1[4]==11))
  321.                                              {if(time_buf1[3]>30)
  322.                                                             time_buf1[3]=1;
  323.                                                         }
  324.                                           if(time_buf1[4]==2)
  325.                                           {              if((time_buf1[6]%4)&&(time_buf1[3]>28)) time_buf1[3]=1;
  326.                                               if(!(time_buf1[6]%4)&&(time_buf1[3]>29)) time_buf1[3]=1;
  327.                                           }
  328.                                           dings[k][3]=time_buf1[3];
  329.                                              break;
  330. case 4:      
  331.                                           time_buf1[2]=time_buf1[2]+1;                                   //小时加1
  332.                                    if(time_buf1[2]>23) time_buf1[2]=0;                             //当分钟加到60时初始化为0
  333.                         dings[k][2]=time_buf1[2];
  334.                                           break;
  335. case 5:      
  336.                                           time_buf1[1]=time_buf1[1]+1;                                   //小时加1
  337.                                    if(time_buf1[1]>59) time_buf1[1]=0;                             //当分钟加到60时初始化为0
  338.                         dings[k][1]=time_buf1[1];
  339.                                 break;
  340.                                           }
  341.                                           }
  342.                    }
  343.               }
  344.               if(K4==0)                              // 减
  345.               {            
  346.                   delay1ms(10);                      //延时去抖
  347.                     if(K4==0)                              
  348.                             {
  349.                                           while(!K4);                                                                                    //等待K4键释放
  350.                                           switch(QH_FLAG1)
  351.                                {            
  352.                                 case 1:      
  353.                                           time_buf1[6]=time_buf1[6]-1;                                   //年减1
  354.                                    if(time_buf1[6]<0) {time_buf1[6]=99;}                             //当年到60时初始化为0
  355.                         dings[k][6]=time_buf1[6];
  356.                                           break;
  357.                                           case 2:      
  358.                                           time_buf1[4]=time_buf1[4]-1;                                   //年减1
  359.                                    if(time_buf1[4]<1) time_buf1[4]=12;                             //当分钟加到60时初始化为0
  360.                         dings[k][4]=time_buf1[4];
  361.                                           break;
  362.                                           case 3:      
  363.                                           time_buf1[3]=time_buf1[3]-1;                                   //年减1
  364. if((time_buf1[4]==1)||(time_buf1[4]==3)||(time_buf1[4]==5)||(time_buf1[4]==7)||(time_buf1[4]==8)||(time_buf1[4]==10)||(time_buf1[4]==12))
  365.                                              {if(time_buf1[3]<1)
  366.                                                             time_buf1[3]=31;
  367.                                                         }
  368.                             if((time_buf1[4]==4)||(time_buf1[4]==6)||(time_buf1[4]==9)||(time_buf1[4]==11))
  369.                                              {if(time_buf1[3]<1)
  370.                                                             time_buf1[3]=30;
  371.                                                         }
  372.                                           if(time_buf1[4]==2)
  373.                                           {              if((time_buf1[6]%4)&&(time_buf1[3]<1)) time_buf1[3]=28;
  374.                                               if(!(time_buf1[6]%4)&&(time_buf1[3]<1)) time_buf1[3]=29;
  375.                                           }
  376.                                    dings[k][3]=time_buf1[3];
  377.                                           break;
  378.                                           case 4:      
  379.                                           time_buf1[2]=time_buf1[2]-1;                                   //年减1
  380.                                    if(time_buf1[2]<0) time_buf1[2]=23;                             //当分钟加到60时初始化为0
  381.                         dings[k][2]=time_buf1[2];
  382.                                           break;
  383.                                           case 5:      
  384.                                           time_buf1[1]=time_buf1[1]-1;                                   //年减1
  385.                                    if(time_buf1[1]<0) time_buf1[1]=59;                             //当分钟加到60时初始化为0
  386.                         dings[k][1]=time_buf1[1];
  387.                                           break;
  388.                             case 6:
  389.                                             dings_kaig[k]=dings_kaig[k]-1;
  390.                                             if(dings_kaig[k]<0)
  391.                                             {dings_kaig[k]=1;}
  392.                                             LCD_writecom(0x4c+0x80);    //写显示地址,将在第2行第7列开始显示
  393.                         delay1ms(1);
  394.                         LCD_writedata(digit2[dings_kaig[k]]);    //将百位数字的字符常量写入LCD
  395.                                             break;            
  396.                                             }
  397. ……………………

  398. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

完整的Word格式文档51黑下载地址:
基于单片机的自动定时开关插座的设计.doc (11.87 MB, 下载次数: 163)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:514540 发表于 2019-4-17 14:07 | 只看该作者
请问楼主这是控制模块吗,演示的图片好像没有看到插座啊
回复

使用道具 举报

板凳
ID:532047 发表于 2019-5-9 22:29 | 只看该作者
楼主,有原件清单吗
回复

使用道具 举报

地板
ID:532047 发表于 2019-5-9 22:43 | 只看该作者
楼主,有原件清单吗
回复

使用道具 举报

5#
ID:700403 发表于 2020-2-29 22:45 | 只看该作者
多谢楼主提供思路
回复

使用道具 举报

6#
ID:686739 发表于 2020-3-1 07:48 来自手机 | 只看该作者
学习一下
回复

使用道具 举报

7#
ID:711816 发表于 2020-3-19 19:44 | 只看该作者
小白参观一下
回复

使用道具 举报

8#
ID:200118 发表于 2023-8-31 11:06 | 只看该作者
收藏。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表