基于单片机万年历设计.doc
《基于单片机万年历设计.doc》由会员分享,可在线阅读,更多相关《基于单片机万年历设计.doc(25页珍藏版)》请在冰点文库上搜索。
基于单片机万年历设计
摘要:
本文介绍了基于STC89C52单片机的多功能电子万年历的硬件结构和软硬件设计方法。
本设计由数据显示模块、温度采集模块、时间处理模块和调整设置模块四个模块组成。
系统以STC89C52单片机为控制器,以串行时钟日历芯片DS1302记录日历和时间,它可以对年、月、日、时、分、秒进行计时,还具有闰年补偿等多种功能。
温度采集选用DS18B20芯片,万年历采用直观的数字显示,数据显示采用1602A液晶显示模块,可以在LCD上同时显示年、月、日、周日、时、分、秒,还具有时间校准等功能。
此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,具有广阔的市场前景。
关键字:
万年历温度计液晶显示
0前言
随着科技的快速发展,时间的流逝,从观太阳、摆钟到现在电子钟,人类不断研究,不断创新纪录。
它可以对年、月、日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。
对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、时、分、秒和温度等信息,还具有时间校准等功能。
该电路采用STC89C52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
1总体方案设计
单片机电子万年历的制作有多种方法,可供选择的器件和运用的技术也有很多种。
所以,系统的总体设计方案应在满足系统功能的前提下,充分考虑系统使用的环境,所选的结构要简单使用、易于实现,器件的选用着眼于合适的参数、稳定的性能、较低的功耗以及低廉的成本。
系统的功能往往决定了系统采用的结构,经过成本,性能,功耗等多方面的考虑决定用三个8位74LS164串行接口外接LCD显示器,RESPACK-8对单片机STC89C52进行供电,时间芯片DS1302连接单片机STC89C52。
从而实现电子万年历的功能。
按照系统设计的要求,初步确定系统由电源模块、时钟模块、显示模块、键盘接口模块、温度测量模块和闹钟模块共六个模块组成,电路系统构成框图如图1所示。
闹钟模块
独立按键
显示模块
始终模块
STC89C52
温度模块
电源模块
图1硬件电路框图
2硬件电路设计
2.1单片机的选择
2.1.151单片机及12单片机结构及功能
单片机又称单片微控制器,可以完成复杂的运算、逻辑控制、通信等功能。
80C51单片机的时钟信号用来提供单片机内各种位操作时间基准,80C52单片机的时钟信号。
通常有两种电路形式:
内部震荡方式和外部震荡方式。
由于80C52的系统性能满足系统数据采集及时间精度的要求,而且产品产量丰富来源广,应用也很成熟,故采用来作为控制核心。
单片机系统是实现环境电压多路采集功能的核心模块。
每次选通一路通道信号进行模拟量转换数字量和输出允许。
STC12C5A60AD/S2系列带A/D转换的单片机的A/D转换口在P1口,上电复位后P1口为弱上拉型IO口,用户可以通过软件设置将8路中的任何一路设置为A/D转换,不须作为A/D使用的口可继续作为IO口使用。
STC12C5A60AD/S2系列单片机与89C52单片机最小系统相同,而功能上较51单片机相比更为强大。
单片机最小系统电路如图2所示。
图2单片机最小系统
2.1.2时钟电路
89C51系列单片机的时钟信号通常有内部振荡和外部振荡方式。
本最小系统采用外部晶振电路,利用11.0592MHZ的晶体振荡器和两个30pF的电容组成。
其中晶体振荡器起振荡作用,两电容起到去耦合的作用,具体设计图如图3所示:
图3时钟电路
2.1.3复位电路
本系统的复位电路是采用按键复位的电路,复位输入引脚RET为其提供了初始化的手段。
当其ALE及PSEN两引脚输出高电平,RET引脚高电平到时,单片机复位。
按下按钮,则直接把+5V加到了RET端从而复位称为手动复位。
复位后,P0到P3并行I/O口全为高电平,其它寄存器全部清零,只有SBUF寄存器状态不确定。
系统复位电路如图4所示。
图4复位电路
2.2时钟芯片DS1302接口设计与性能分析
2.2.1DS1302性能简介
DS1302是Dallas公司生产的一种实时时钟芯片。
它通过串行方式与单片机进行数据传送,能够向单片机提供包括秒、分、时、日、月、年等在内的实时时间信息,并可对月末日期、闰年天数自动进行调整;它还拥有用于主电源和备份电源的双电源引脚,在主电源关闭的情况下,也能保持时钟的连续运行。
另外,它还能提供31字节的用于高速数据暂存的RAM。
DS1302时钟芯片内主要包括移位寄存器、控制逻辑电路、振荡器。
DS1302与单片机系统的数据传送依靠RST,I/O,SCLK三根端线即可完成。
其工作过程可概括为:
首先系统RST引脚驱动至高电平,然后在SCLK时钟脉冲的作用下,通过I/O引脚向DS1302输入地址/命令字节,随后再在SCLK时钟脉冲的配合下,从I/O引脚写入或读出相应的数据字节。
因此,其与单片机之间的数据传送是十分容易实现的,DS1302的引脚排列及内部结构图如图4:
DS1302引脚说明:
X1,X232.768kHz晶振引脚
GND地线
RST复位端
I/O数据输入/输出端口
SCLK串行时钟端口
VCC1慢速充电引脚
VCC2电源引脚图4DS1302的引脚
2.2.2DS1302接口电路设计
1时钟芯片DS1302的接口电路及工作原理:
图5DS1302与MCU接口电路
图5为DS1302的接口电路,其中Vcc1为后备电源,Vcc2为主电源。
VCC1在单电源与电池供电的系统中提供低电源并提供低功率的电池备份。
VCC2在双电源系统中提供主电源,在这种运用方式中VCC1连接到备份电源,以便在没有主电源的情况下能保存时间信息以及数据。
DS1302由VCC1或VCC2两者中较大者供电。
当VCC2大于VCC1+0.2V时,VCC2给DS1302供电。
当VCC2小于VCC1时,DS1302由VCC1供电。
DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置“0”,接着把RST端置“1”,最后才给予SCLK脉冲;读/写时序如下图6所示。
表-1为DS1302的控制字,此控制字的位7必须置1,若为0则不能对DS1302进行读写数据。
对于位6,若对时间进行读/写时,CK=0,对程序进行读/写时RAM=1。
位1至位5指操作单元的地址。
位0是读/写操作位,进行读操作时,该位为1;进行写操作时,该位为0。
控制字节总是从最低位开始输入/输出的。
表-2为DS1302的日历、时间寄存器内容:
“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。
“WP”是写保护位,在任何的对时钟和RAM的写操作之前,“WP”必须为0。
当“WP”为1时,写保护位防止对任一寄存器的写操作。
2、DS1302的控制字
DS1302的控制字如表2所示。
控制字节的高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为1表示进行读操作,为0表示进行写操作。
控制字节总是从最低位开始输出。
表2DS1302的控制字格式
1
RAM/CK
A4
A3
A2
A1
A0
RD/WR
3、数据输入输出(I/O)
在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
如下图6所示。
图6DS1302读/写时序图
4、DS1302的寄存器AM
DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见表3。
表3DS1302的日历、时间寄存器
写寄存器
读寄存器
Bit7
Bit6
Bit5
Bit7
Bit3
Bit2
Bit1
Bit0
80H
81H
CH
10秒
秒
82H
83H
10分
分
84H
85H
12/
0
10
时
时
/PM
86H
87H
0
0
10日
日
88H
89H
0
0
0
10月
月
8AH
8BH
0
0
0
0
0
星期
8CH
8DH
10年
年
8EH
8FH
WP
0
0
0
0
0
0
0
此外,DS1302还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。
时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。
DS1302与RAM相关的寄存器分为两类:
一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
2.3温度芯片DS18B20接口设计与性能分析
2.3.1DS18B20性能简介
1.DS18B20的主要特性
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9-12位的数字值读数方式。
现场温度直接以"一线总线"的数字方式传输,大大提高了系统的抗干扰性。
适合于恶劣环境的现场温度测量,如:
环境控制、设备或过程控制、测温类消费电子产品等。
与前一代产品不同,新的产品支持3V~5.5V的电压范围,使系统设计更灵活、方便。
其性能特点可归纳如下:
1独特的单线接口仅需要一个端口引脚进行通信;
2测温范围在-55℃到125℃,分辨率最大可达0.0625℃;
3采用了3线制与单片机相连,减少了外部硬件电路;
4零待机功耗;
5可通过数据线供电,电压范围在3.0V-5.5V;
6用户可定义的非易失性温度报警设置;
7报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件;
8负电压特性,电源极性接反时,温度计不会因发热烧毁,只是不能正常工作。
2.DS18B20工作原理
DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。
DS18B20测温原理如图5所示。
图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送给计数器1。
高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。
计数器1和温度寄存器被预置在-55℃所对应的一个基数值。
计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。
图7中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。
LSB
位置/清除
增加
计数器1
斜率累加器
计数比较器
温度寄存器
减到0
预置
计数器2
减到0
停止
预置
低温度系数晶振
高温度系数晶振
图7DS18B20测温原理
2.3.2DS18B20接口电路设计
如8图所示,该系统中采用数字式温度传感器DS18B20,具有测量精度高,电路连接简单特点,此类传感器仅需要一条数据线进行数据传输,用P3.7与DS18B20的DQ口连接,Vcc接电源,GND接地。
图8温度传感器DS18B20接口电路
2.3.3DS18B20的工作时序
1、复位时序图
图9复位时序图
2、读时序图
图10读时序图
3、写时序图
图11写时序图
4、工作时序
1)总线时序
图12总线时序
2)写周期时序
图13写周期时序
3)起始/停止时序
图14起始/停止时序
4)应答时序
图15应答时序
5)立即地址读时序
图16立即地址读时序
2.4LCD显示模块
2.4.1LCM1602的特性及使用说明
1.LCM1602的接口信号说明如表4:
表4LCM1602的接口信号
编号
引脚符号
功能说明
编号
引脚符号
功能说明
1
VSS
电源地
9
D2
DATAI/O
2
VDD
电源正极
10
D3
DATAI/O
3
VL
液晶显示偏压信号
11
D4
DATAI/O
4
RS
数据/命令选择端(H/L)
12
D5
DATAI/O
5
R/W
读/写选择端(H/L)
13
D6
DATAI/O
6
E
使能信号
14
D7
DATAI/O
7
D0
DATAI/O
15
BLA
背光正极
8
D1
DATAI/O
16
BLK
背光负极
2、基本操作时序如下:
1)读状态:
RS=L,RW=H,E=H
2)写指令:
RS=L,RW=L,D0~D7=指令码,E=高脉冲
3)读数据:
RS=H,RW=H,E=H
4)写数据:
RS=H,RW=L,D0~D7=数据,E=高脉冲
3、初始化设置
1)显示模式设置如表5:
表5显示模式设置
指令码
功能
0
0
1
1
1
0
0
0
设置16*2显示,5*7点阵,8位数据接口
2)显示开/关及光标设置如表6:
表6显示开/关及光标设置
指令码
功能
0
0
0
0
1
D
C
B
D=1开显示;D=0关显示
C=1显示光标;C=0不显示光标
B=1光标闪烁;B=0光标不显示
0
0
0
0
0
1
N
S
N=1当读或写一个字符后地址指针加一,且光标加一
N=0当读或写一个字符后地址指针减一,且光标减一
S=1当写一个字符,整屏显示左移(N=1)
2.4.2LCM1602与MCU的接口电路
LCD的D0~D7分别接单片机的的P2口,作为数据线,因为P0口内部没有上拉电阻,所以外部另外加上10K的上拉电阻;P1.0—P1.2分别接LCD的RS、RW、E三个控制管脚;RV1用来调节LCD的显示灰度;BLK、BLA为背光的阴极和阳极,接上相应电平即点亮背光灯。
2.5按键模块设计
本系统用到了5个按键,其中一个用作系统手动复位,另外4个采用独立按键,该种接法查询简单,程序处理简单,可节省CPU资源,按键电路如图17所示,4个独立按键分别与STC89C52的P3.4、P3.5、P3.6、P3.7接口相连。
图17按键电路
对以上4个按键作简要说明:
S4——SET键,S3——UP键,S2——DOWN键,S5——OUT/STOP键。
SET键:
按下SET键进入时间校准状态,按一下进入秒调整,两下分调整,依此类推可进行各年月日,时分秒以及星期的校准;
UP键:
当SET键按下时,UP进行SET选定项(如:
小时)的加操作;
DOWN键:
当SET键按下时,DOWN进行SET选定项(如:
小时)的减操作;
OUT键:
当OUT键按下时,此键功能为退出校准功能,进入下一模式,显示温度值和上下限的温度值。
2.6复位电路的设计
当STC89C52单片机的复位引脚RST(全称RESET)出现2个机器周期以上的高电平时,单片机就完成了复位操作。
如果RST持续为高电平,单片机就处于循环复位状态,而无法执行程序。
因此要求单片机复位后能脱离复位状态。
而本系统选用的是12MHz的晶振,因此一个机器周期为1μs,那么复位脉冲宽度最小应为2μs。
在实际应用系统中,考虑到电源的稳定时间,参数漂移,晶振稳定时间以及复位的可靠性等因素,必须有足够的余量。
根据应用的要求,复位操作通常有两种基本形式:
上电复位、手动复位。
上电复位要求接通电源后,自动实现复位操作。
STC89C52单片机的上电复位POR(PowerOnReset)实质上就是上电延时复位,也就是在上电延时期间把单片机锁定在复位状态上。
在单片机每次初始加电时,首先投入工作的功能部件是复位电路。
复位电路把单片机锁定在复位状态上并且维持一个延时(记作TRST),以便给予电源电压从上升到稳定的一个等待时间;在电源电压稳定之后,再插入一个延时,给予时钟振荡器从起振到稳定的一个等待时间;在单片机开始进入运行状态之前,还要至少推迟2个机器周期的延时。
本设计采用上电且开关复位电路,如图18所示上电后,由于电容充电,使RST持续一段高电平时间。
当单片机已在运行之中时,按下复位键也能使RST持续一段时间的高电平,从而实现上电且开关复位的操作。
通常选择C=10~30μF,本设计采用的电容值为10μF的电容和电阻为4.7K的电阻。
图18复位电路
3系统的软件设计
电子万年历的功能是在程序控制下实现的。
该系统的软件设计方法与硬件设计相对应,按整体功能分成多个不同的程序模块,分别进行设计、编程和调试,最后通过主程序将各程序模块连接起来。
这样有利于程序修改和调试,增强了程序的可移植性。
本系统的软件部分主要要进行公历计算程序设计,温度测量程序设计,按键的扫描输入等。
程序开始运行后首先要进行初始化,把单片机的各引脚的状态按程序里面的初始化命令进行初始化,初始化完成后运行温度测量程序,读取出温度传感器测量出来的温度,然后运行公历计算程序,得到公历的时间、日期信息,再运行按键扫描程序,检测有无按键按下,如果没有按键按下则直接调用节日计算程序,根据得到的公历日期信息计算出节日,如果有按键按下则更新按键修改后的变量后送给节日计算程序,由节日计算程序根据修改后的变量计算出对应的节假日,计算完成后运行显示程序,显示程序将得到的温度数据、公历信息、节假日信息送给对应的数码管让其显示。
3.1主程序流程图的设计
主程序流程图:
开始
DS1302初始化
设置DS1302
读年月日星期时分秒
将读取的数据处理后送液晶屏显示
返回
图19主程序流程图
3.2程序设计
3.2.1DS1302读写程序设计
本系统的时间读取主要来源于单片机对DS1302的操作,在硬件上时钟芯片DS1302与单片机的连接需要三条线,即SCLK(7)、I/O(6)、RST(5),具体连接图见系统硬件设计原理图。
读取写程序设计如下:
sbitclk=P1^3; //ds1302时钟线定义
sbitio=P1^4; //数据线
sbitrst=P1^5; //复位线
//秒分时日月年星期
ucharcodewrite_add[]={0x80,0x82,0x84,0x86,0x88,0x8c,0x8a};//写地址
ucharcoderead_add[]={0x81,0x83,0x85,0x87,0x89,0x8d,0x8b};//读地址
ucharcodeinit_ds[]={0x58,0x00,0x00,0x01,0x01,0x13,0x1};
ucharmiao,fen,shi,ri,yue,week,nian;
uchari;
ucharfen1=0x11,shi1=0; //两个闹钟变量的定义
bitopen1;
/*************写一个数据到对应的地址里***************/
voidwrite_ds1302(ucharadd,uchardat)
{
rst=1; //把复位线拿高
for(i=0;i<8;i++)
{ //低位在前
clk=0; //时钟线拿低开始写数据
io=add&0x01;
add>>=1; //把地址右移一位
clk=1; //时钟线拿高
}
for(i=0;i<8;i++)
{
clk=0; //时钟线拿低开始写数据
io=dat&0x01;
dat>>=1; //把数据右移一位
clk=1; //时钟线拿高
}
rst=0; //复位线合低
clk=0;
io=0;
}
/*************从对应的地址读一个数据出来***************/
ucharread_ds1302(ucharadd)
{
ucharvalue,i;
rst=1; //把复位线拿高
for(i=0;i<8;i++)
{ //低位在前
clk=0; //时钟线拿低开始写数据
io=add&0x01;
add>>=1; //把地址右移一位
clk=1; //时钟线拿高
}
for(i=0;i<8;i++)
{
clk=0; //时钟线拿低开始读数据
value>>=1;
if(io==1)
value|=0x80;
clk=1; //时钟线拿高
}
rst=0; //复位线合低
clk=0;
io=0;
returnvalue; //返回读出来的数据
}
/*************把要的时间年月日都读出来***************/
voidread_time()
{
miao=read_ds1302(read_add[0]); //读秒
f