单片机控制电子日历Word格式.docx
《单片机控制电子日历Word格式.docx》由会员分享,可在线阅读,更多相关《单片机控制电子日历Word格式.docx(30页珍藏版)》请在冰豆网上搜索。
MCU;
AT89C51;
DS1302;
adjustable
目录
摘要III
AbstractIV
第一章引言1
1.1电子日历原理1
1.2方案选择1
1.2.1时钟方案一2
1.2.2时钟方案二2
1.2.3显示方案一3
1.2.4显示方案二3
1.2.5显示方案三3
第二章硬件设计4
2.1电路设计框图4
2.2系统硬件概述4
2.3主要单元电路的设计5
2.3.1单片机主控制模块的设计5
2.3.2时钟电路DS13027
2.3.3显示模块的设计9
第三章软件设计10
3.1主程序流程图10
3.2按键扫描子程序11
3.3液晶初始化子程序15
第四章实验仿真16
上电或者复位后LED显示16
结语18
参考文献19
致谢20
附录:
21
第一章引言
随着科技的快速发展,时间的流逝,至从观太阳、摆钟到瑞士的机械手表,现在的电子钟。
现代人生活节奏越来越快,人们的对时间的要求越来越高,因而就需要更好的电子钟。
美国DALLAS公司推出的具有涓细电流充电能的低功耗实时时钟电路DS1302。
它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。
对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒阴历月、日信息,还具有时间校准等功能。
该电路采用AT89C51单片机作为核心,功耗小,电压可选用3~5V电压供电。
综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
本设计是基于51系列的单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。
在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。
在硬件与软件设计时,没有良好的基础知识和实践经验会受到很大限制,每项功能实现时需要那种硬件,程序该如何编写,算法如何实现等,没有一定的基础就不可能很好的实现。
1.1电子日历原理
本设计中采用AT89C51作为主控部分,由精准的时钟芯片DS1302提供时钟信号,并且配合四个按钮调节年、月、日、星期、时、分、秒,显示部分采用LCD1602显示
1.2方案选择
由于电子万年历的种类比较多因此方案选择在设计中是至关重要的。
正确地选择方案可以减小开发难度缩短开发周期降低成本更快地将产品推向市场。
1.2.1时钟方案一
基于AT89C51单片机的电子万年历设计不使用时钟芯片而直接用AT89S52单片机来实现电子万年历设计。
AT89C51是一种带8K字节闪烁可编程可擦除只读存储器的低电压高性能CMOS8位微处理器俗称单片机。
单片机的可擦除只读存储器可以反复擦写1000余次。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中ATMEL的AT89S52是一种高效微控制器为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
若采用单片机计时利用它的一个16位定时器/计数器每50ms产生一个中断信号中断20次后产生一个秒信号然后根据时间进制关系依次向分、时、日、星期、月、年进位。
这样就实现了直接用单片机来实现电子万年历设计。
用单片机来实现电子万年历设计无须外接其他芯片充分利用了单片机的资源。
但是精度不够高误差较大掉电后丢失所有数据软件编程较复杂。
1.2.2时钟方案二
基于DS1302的电子万年历设计在以单片机为核心构成的装置中经常需要一个实时的时钟和日历以便对一些实时发生事件记录时给予时标,实时时钟芯片便可起到这一作用。
过去多用并行接口的时钟芯片如MC146818,DS1288等。
它们已能完全满足单片机系统对实时时钟的要求但是这些芯片与单片机接口复杂、占用地址,数据总线接线多、芯片体积大占用空间多、近年来串行接口的各种芯片在单片机系统中应用愈来愈多串行接口的实时时钟芯片也出现了不少DS1302是一个综合性能较好且价格便宜的串行接口实时时钟芯片。
利用单片机进行控制采用DS1302作为实时时钟芯片其三线接口SCLK、I/O、/RST与单片机进行同步通信外加掉电存储电路、显示电路、键盘电路即构成一个基本的电子万年历系统若还要添加其他功能在这基础上外扩电路即可。
由于在系统设计时需要考虑以下几点因素功耗低、精确度高、软件编程较简单芯片的体积小、芯片成本低等而DS1302芯片有上面所述的诸多优点所以本设计采用时钟方案二。
1.2.3显示方案一
采用点阵式数码管显示点阵式数码管是由八行八列的发光二极管组成对于显示文字比较适合,如采用在显示数字显得太浪费,且价格也相对较高,所以也不用此种作为显示。
1.2.4显示方案二
采用LED数码管动态扫描,LED数码管价格虽适中,对于显示数字也最合适,而且采用动态扫描法与单片机连接时,占用的单片机口线少。
但是由于数码管动态扫描需要借助74LS164移位寄存器进行移位该芯片在电路调试时往往会有很多障碍所以不采用LED数码管作为显示。
1.2.5显示方案三
采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见,对于电子万年历而言一个1602的液晶屏即可价格也还能接受,需要的接口线较多,但会给调试带来诸多方便所以此设计中采用LCD1602液晶显示屏作为显示模块。
第二章硬件设计
2.1电路设计框图
AT89C51
主控制模块
图2.1系统原理图
2.2系统硬件概述
本电路是由AT89C51单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;
时钟电路由DS1302提供,它是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31*8的用于临时性存放数据的RAM寄存器。
可产生年、月、日、周日、时、分、秒,具有使用寿命长,精度高和低功耗等特点,同时具有掉电自动保存功能;
显示部份由LCD液晶显示屏显示。
系统总电路图如下
图2.2
2.3主要单元电路的设计
2.3.1单片机主控制模块的设计
AT89C51是一种带4K字节FLASH存储器(FPEROM—FlashProgrammableandErasableReadOnlyMemory)的低电压、高性能CMOS8位微处理器,俗称单片机。
AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除1000次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。
AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
主要特性:
·
与MCS-51兼容
4K字节可编程FLASH存储器
寿命:
1000写/擦循环
数据保留时间:
10年
全静态工作:
0Hz-24MHz
三级程序存储器锁定
128×
8位内部RAM
32可编程I/O线
两个16位定时器/计数器
5个中断源
可编程串行通道
低功耗的闲置和掉电模式
片内振荡器和时钟电路
主控制器主要由单片机AT89C51、振荡器和复位电路三部分组成,它是单片机工作的必要组成部分,又称为单片机最小系统。
其中XTAL1和XTAL2外接一个晶体振荡器,RST外接一个复位电路,晶体振荡电路为单片机提供时钟控制信号[11]。
复位电路采用上电复位方式,通电的一瞬间,电容C1可看成通路,这时单片机RST端为高电平,单片机复位。
电压稳定后,电容C1可看成断路,单片机RST端为低电平。
整个外围电路图如图2.3
图2.3
2.3.2时钟电路DS1302
DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
DS1302内部有一个31×
8的用于临时性存放数据的RAM寄存器。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
X1和X2是振荡源,外接32.768KHz晶振。
RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。
RST输入有两种功能:
首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;
其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RSTS置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电动行时,在Vcc大于等于2.5V之前,RST必须保持低电平。
中有在SCLK为低电平时,才能将RST置为高电平,I/O为串行数据输入端(双向)。
SCLK始终是输入端。
在此电路中I/O接51单片机的P1.0口,P1.1口输出接SCLK输入,复位端RST接单片机P1.2口,如图2.4。
图2.4
电路原理及说明
(1)时钟芯片DS1302的工作原理:
DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置“0”,接着把RST端置“1”,最后才给予SCLK脉冲;
读/写时序如下图4所示。
DS1302的控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。
对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0,位1至位5指操作单元的地址。
位0是读/写操作位,进行读操作时,该位为1;
该位为0则表示进行的是写操作。
控制字节总是从最低位开始输入/输出的。
表.2为DS1302的日历、时间寄存器内容:
“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;
当该位为0时,时钟开始运行。
“WP”是写保护位,在任何的对时钟和RAM的写操作之前,WP必须为0。
当“WP”为1时,写保护位防止对任一寄存器的写操作。
(2)DS1302的控制字节:
DS1302控制字节的高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果0,则表示存取日历时钟数据,为1表示存取RAM数据;
位5至位1指示操作单元的地址;
最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出
(3)数据输入输出(I/O)
在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
(4)DS1302的寄存器
DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式。
此外,DS1302还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。
时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。
DS1302与RAM相关的寄存器分为两类:
一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;
另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
2.3.3显示模块的设计
1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用。
1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字),如图2.5。
图2.5
在此系统的仿真电路中,采用LM016L作为液晶显示,可显示两行,由于单片机的驱动能力有限,我们加入一个排阻来提高驱动能力,具体如图2.6.
图2.6
第三章软件设计
3.1主程序流程图
图3.1
主程序:
voidmain()
{
init();
write_setds(0x80,0x50);
write_setds(0x82,0x59);
write_setds(0x84,0x10);
write_setds(0x86,0x17);
write_setds(0x88,0x03);
write_setds(0x8a,0x03);
write_setds(0x8c,0x10);
write_setds(0x90,0xa4);
while
(1)
{
keyscan();
}
display();
3.2按键扫描子程序
调整时间用4个调整按钮,1个作为选择控制用,另外3个分别作为加调整,减调整和确定用。
时间调整程序流程图如图3.2所示:
图3.2
voidSET_DS1302()
{
uchari;
Write_DS1302(0x8e,0x00);
for(i=0;
i<
7;
i++)
Write_DS1302(0x80+2*i,(DateTime[i]/10<
<
4|(DateTime[i]%10)));
}
Write_DS1302(0x8e,0x80);
/*------------------------------------
读取当前时期时间
------------------------------------*/
voidGetTime()
{
uchari;
for(i=0;
DateTime[i]=Read_Data(0x81+2*i);
}
时间和日期转换成数字字符
voidFormat_DateTime(uchard,uchar*a)
a[0]=d/10+'
0'
;
a[1]=d%10+'
判断是否为闰年
ucharisLeapYear(uinty)
return(y%4==0&
&
y%100!
=0)||(y%400==0);
星期转换
voidRefreshWeekDay()
uinti,d,w=5;
for(i=2000;
2000+DateTime[6];
d=isLeapYear(i)?
366:
365;
w=(w+d)%7;
d=0;
for(i=1;
DateTime[4];
i++)d+=MonthsDays[i];
d+=DateTime[3];
DateTime[5]=(w+d)%7+1;
年月日时分秒++/--
voidDateTime_Adjust(charx)
switch(Adjust_Index)
case6:
//年
if(x==1&
DateTime[6]<
99)DateTime[6]++;
if(x==-1&
DateTime[6]>
0)DateTime[6]--;
MonthsDays[2]=isLeapYear(2000+DateTime[6])?
29:
28;
if(DateTime[3]>
MonthsDays[DateTime[4]])
DateTime[3]=MonthsDays[DateTime[4]];
RefreshWeekDay();
break;
case4:
//月
DateTime[4]<
12)DateTime[4]++;
DateTime[4]>
1)DateTime[4]--;
case3:
//日
DateTime[3]<
MonthsDays[DateTime[4]])DateTime[3]++;
DateTime[3]>
0)DateTime[3]--;
case2:
//时
DateTime[2]<
23)DateTime[2]++;
DateTime[2]>
0)DateTime[2]--;
case1:
//秒
DateTime[1]<
59)DateTime[1]++;
DateTime[1]>
0)DateTime[1]--;
3.3液晶初始化子程序
/*************初始化*************/
voidT0_INT()interrupt1
TH0=-50000/256;
TL0=-50000%256;
if(++tCount!
=2)return;
tCount=0;
Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5);
Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8);
Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11);
strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]);
Format_DateTime(DateTi