《51单片机电子万年历设计带有proteus仿真(共25页).doc》由会员分享,可在线阅读,更多相关《51单片机电子万年历设计带有proteus仿真(共25页).doc(25页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上湖南文理学院课程设计课程名称: 单片机课程设计 设计题目: 电子万年历 教学院部: 电气与信息工程学院 专业班级: 自动化09101班 指导教师: 张 晓 虎 学生姓名: 邵 泽 学 号: 0 完成时间: 2012 年6月12日 报告成绩: 评阅意见: 评阅教师 日期 摘要: 电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。它可以对年、月、日、周日、时、分和秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒等信息,还具有时间校准等功能。该电路采用AT89
2、C52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3到5V电压供电。万年历的设计过程在硬件与软件方面进行同步设计。硬件部分主要由AT89C52单片机,液晶显示电路,复位电路,时钟电路,稳压电路电路以及串口下载电路等组成。在单片机的选择上使用了AT89C52单片机,该单片机适合于许多较为复杂控制应用场合。显示器使用液晶LCD1602。软件方面主要包括日历程序、液晶驱动程序,显示程序等。程序采用汇编语言编写。所有程序编写完成后,在Keil C51软件中进行调试,确定没有问题后,在Proteus软件中嵌入单片机内进行仿真。关键词 时钟电钟,DS1302,液晶LCD1602,单片机 Abst
3、ract:Electronic calendar is a very extensive daily timing tool for modern society is more and more popular. It can be to year, month, day, Sunday, when, minutes, and seconds for the time, also has a leap year compensation and other functions, and the DS1302 long service life and small error. For dig
4、ital electronic calendar using intuitive digital display, can also shows that year, month, day, Sunday, when the information such as, minutes and seconds, still have time calibration etc. Function. The AT89C52 single chip microcomputer as circuit adopts core, power consumption is small, can be in 3
5、V of low-pressure work, voltage can choose 3 to 5 V voltage power supply.The design process of the calendar in the hardware and software design of synchronization. Mainly by AT89C52 single chip microcomputer hardware part, liquid crystal display circuit, reset circuit, clocking circuit on the circui
6、t circuit and serial download circuit etc. The processor on the choice of the single chip microcomputer AT89C52 use, the single chip microcomputer suitable for many more complex control applications. Use of liquid crystal display LCD1602. Software is mainly including calendar program, liquid crystal
7、 driver, show program, etc. Program using assembly language. All programming, after the completion of Keil C51 software in commissioning, make sure no, after Proteus software embedded in within the single chip microcomputer simulation.Key words DianZhong clock, DS1302, liquid crystal LCD1602, microc
8、ontroller 目 录 1设计要求与方案论证1.1设计要求 能够显示年、月、日、时、分。 可以人为校正年、月、日、时、分。 地一次开机显示:2000 01 01 12.00。 掉电信息不丢失。1.2 系统基本方案选择和论证系统方案包括单片机的选型、时钟芯片的选择和显示模块的确定等。 1.2.1单片机芯片的选择方案和论证方案一:采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术, 当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧
9、入程序时,对芯片的多次拔插会对芯片造成一定的损坏。方案二: 采用AT89C52,片内ROM全都采用Flash ROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。所以选择采用AT89C52作为主控制系统控制整个系统的正常工作。 1.2.2 显示模块选择方案和论证方案一:采用数码管显示,数码管是由八个发光二极管组成,对于显示数字字符比较适合,但对于电子万年历需要的数码管位
10、数多,编程麻烦,且不稳定,存在抖动现象,需要通过软件延时进行消抖。 方案二:采用LCD1602液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见,易于编程,稳定可靠。通过对比,本课程设计采用LCD1602作为显示模块。 1.2.3时钟芯片的选择方案和论证:方案一:直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、时、分计数。采用此种方案虽然减少芯片的使用,节约成本,但是,实现的时间误差较大。所以不采用此方案。方案二:采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对分、时、日、月、年以及闰年补偿的年进行计数,而且精度高,位的
11、RAM作为数据暂存区,工作电压2.5V5.5V范围内,2.5V时耗电小于300nA。同时在外加电源和外加晶振电路下,掉电后走时准确。本课程设计采用DS1302作为时钟的芯片。1.3 电路设计最终方案决定综上各方案所述,对此次设计的方案选定: 采用AT89C52作为主控制系统; DS1302提供时钟;LCD1602作为显示。2系统的硬件设计与实现2.1 电路设计框图 2.2 系统硬件概述本电路是由AT89C52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由DS1302提供,它是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、时、分和秒进行计时,具有闰年
12、补偿功能,工作电压为2.5V5.5V。采用三线接口(SPI总线)与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31*8的用于临时性存放数据的RAM寄存器。可产生年、月、日、时、分,具有使用寿命长,精度高和低功耗等特点,同时具有掉电自动保存功能;显示部分由LCD1602显示,精度高,显示稳定。2.3 主要单元电路的设计单元电路的设计包括主控制系统、时钟电路模块、显示模块、串口下载模块、复位电路和稳压电路的设计。2.3.1单片机主控制模块的设计AT89C52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3, MCS-51单片机
13、共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能独立地作输出或输入。单片机的最小系统如下图所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和30PF电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和30PF电容的另一端,在片内它是振荡器倒相放大器的输出.第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20引脚为接地端,40引脚为电源端. 如图2-1 所示 图2-1 主控制系统2.3.2时钟电路模块的设计图2-2示出DS1302的引脚排列,其中Vcc1为后备电源,Vcc2为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302
14、由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。X1和X2是振荡源,外接32.、KHz晶振。RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。I/O为串行数据输入端(双向)。SCLK始终是输入端。如图2-2所示。图2-2 DS1302的引脚图2.3.3显示模块电路如图23所示,采用液晶1602数据端由P0提供实现8位并行通信,其数据交换的速率比较快VL是调整液晶显示的亮度,E是使能端口,RW是读写控制端口,高电平读信号,低电平写信号;RS是读写命令与数据控制端口,
15、高电平写数据,低电平写命令。 图2-3 LCD 1062的电路图2.3.4串口下载电路经过KEIL C51编译的汇编程序必须下载到单片机内部运行,才能实现所需要的功能。然而单片机得1、0是用5V、和0V表示的,而电脑中的1、0用的电压并不是5V、和0V,因此,必须用MAX232进行电压转化,于是设计的串口下载电路。如图2-4所示。图2-4 串口下载电路2.3.5复位电路在单片机中运行程序时,如果程序跑飞,即程序运行的地址出现混乱时,可以用复位电路,在低电平时程序从零地址从新开始运行。同时也可以使用看门狗,定时的喂狗,使程序每次从零地址开始运行。防止程序跑飞。如图2-5所示。图2-5 复位电路2
16、.3.6稳压电路当输入的电压高于或者低于51v时,可以用L7805CV稳压到5V,保证单片机稳定的性能和可靠的稳定性,其中的二极管是利用了单片机的单向导电性,导致单片机被烧毁或者系统不能正常工作。如图2-6所示。图2-6 稳压电路3系统的软件设计3.1程序流程框图分离日期时间显示值读日期、时间初始化开始显示子程序返回4软件proteus测试及分析 通过调节四个按键设定时间为2000年1月1日12点整。4.1软件测试电子万年历是多功能的数字显示仪器。由于功能很多,所以对于它的程序也较为复杂,因此本次设计采用简化模型,即只显示年月日,时分秒。但在程序调试时出现了相对较多的错误。最后经过多次的模块子
17、程序的修改,一步一步的完成,最终解决了软件。在软件的调试过程中主要遇到的问题如下:4.2分析与结论4.2.1 调试分析(1)显示的数据秒并没有变化,原因是没有启动定时器,我有不断的读取DS1302时钟芯片寄存器中的数据,并显示才能实现所需要的功能,实时显示年、月、日、星期、分钟、小时、秒等基本功能来满足系统的需求。(2)调整时间后应该先去掉写保护,如果存在写保护,那么在初始化写入初始时间时,是写不进去初始化的时间的。因而会看见显示的时间并不随着设置的初始化的值变化而变化,甚至我们看见的时间并不按着一秒一秒的增加。(3)液晶显示的时候,由于采用的并行总线,显然传输速度快,但是数据端口必须接1K的
18、排阻,以实现驱动,实践证明,没有排阻的时候,液晶显示就会不稳定,甚至出现乱码。因此,排阻的作用很大。写程序时要严格按照时序就行,否则,也不会显示。 4.2.2调试和结论经过多次反复修改程序,对电路各模块的原理及功能更加熟悉,同时提高了设计能力与及对电路的分析能力.同时在软件的编程方面得到更到的提高,对所学的知识得到很大的提高与巩固.5总结通过这次制作使我了解了整个万年历的工作过程和各个部分的工作原理。使我认识到利用单片机设计的万年历便于操作。经过认真的仿真观察,本次设计的万年历能够正确的显示年、月、日等,总体来说算是比较成功的。本次单片机课程设计是使用Protues设计工具、协同使用Keil编
19、程软件制作的。这也使我又掌握了一门非常实用的软件,对于我以后的毕业设计算是又多了一个非常好的选择。在看同学编写程序的过程中我自己也学到了很多的东西,对于一些Protues程序的不同用法和功能能够比较顺畅的读程序和简单的应用。 6参考文献1 刘勇 编 数字电路 电子工业出版社 20042 陈正振 编 电子电路设计与制作 广西交通职业技术学院信息工程系 20073 杨子文 编 单片机原理及应用 西安电子科技大学出版社 20064 王法能 编 单片机原理及应用 科学出版社 2004附录一:系统电路图附录二:系统程序清单专心-专注-专业#include #include #include #defin
20、e uint unsigned int#define uchar unsigned charsbit IO= P10; /DS1302数据线sbit SCLK = P11; /DS130时钟线sbit RST = P12; /DS1302复位线sbit RS = P20; /LCD数据/命令选择端sbit RW = P21; /LCD读/写控制sbit EN = P22; /LCD使能端sbit K1=P34;/选择sbit K2=P35;/加sbit K3=P36;/减sbit K4=P37; /确定uchar tCount=0;uchar MonthsDays=0,31,0,31,30,3
21、1,30,31,31,30,31,30,31;uchar *WEEK=SUN,MON,TUS,WEN,THU,FRI,SAT;uchar LCD_DSY_BUFFER1=DATE 00-00-00 ; /显示格式uchar LCD_DSY_BUFFER2=TIME 00:00:00 ;uchar DateTime7; /所读取的日期时间char Adjust_Index=-1; /当前调节的时间对象:,分,是,日,月,年(1,2,3,4,6)uchar Change_Flag= -MHDM-Y; /(分,时,日,月,年)(不调节秒与周)/*-延时程序-*/void DelayMS(uint m
22、s) uchar i;while(ms-)for(i=0;i120;i+);/-向DS1302写入一字节-/void Write_A_Byte_TO_DS1302(uchar x)uchar i;for(i=0;i=1; / 右移/-从DS1302读取一字节-/uchar Get_A_Byte_FROM_DS1302()uchar i,b=0x00;for(i=0;i8;i+) b |= _crol_(uchar)IO,i);SCLK=1;SCLK=0; /每一个高脉冲读取一位数据return b/16*10+b%16; /返回BCD码/-从DS1302指定位置读数据-/uchar Read_
23、Data(uchar addr) uchar dat;RST = 0;SCLK=0;RST=1; /RST高电平时读/写 Write_A_Byte_TO_DS1302(addr); /先写入地址dat = Get_A_Byte_FROM_DS1302(); SCLK=1;RST=0;return dat;/-向DS1302某地址写入数据-/void Write_DS1302(uchar addr,uchar dat)SCLK=0;RST=1;Write_A_Byte_TO_DS1302(addr);Write_A_Byte_TO_DS1302(dat);SCLK=0;RST=0; /高脉冲写入
24、数据/-设置时间-/void SET_DS1302()uchar i;/写控制字,取消写保护Write_DS1302(0x8E,0x00);/分时日月年依次写入for(i=1;i7;i+) /分的起始地址(0x82),后面依次是时,日,月,周,年,写入地址每次递增2Write_DS1302(0x80+2*i,(DateTimei/104)|(DateTimei%10); Write_DS1302(0x8E,0x80); /加保护/-读取当前日期时间-/void GetTime()uchar i;for(i=0;i7;i+)DateTimei=Read_Data(0X81+2*i);/-读LCD
25、状态-/uchar Read_LCD_State()uchar state;RS=0;RW=1;EN=1; /输出:D0D7=状态字DelayMS(1);state=P0; /从P0口读LCD状态EN = 0;DelayMS(1);return state; /-忙等待-/void LCD_Busy_Wait() while(Read_LCD_State()&0x80)=0x80);DelayMS(5);/-向LCD写数据-/void Write_LCD_Data(uchar dat) LCD_Busy_Wait();RS=1;EN=0;RW=0; /写数据,EN为高脉冲,P0=dat;EN=
26、1;DelayMS(1);EN=0;/-写LCD指令-/void Write_LCD_Command(uchar cmd) LCD_Busy_Wait();RS=0;EN=0;RW=0; /写指令,EN高脉冲,输出:D0D7=数据P0=cmd;EN=1;DelayMS(1);EN=0;/-LCD初始化-/void Init_LCD() Write_LCD_Command(0x38); /设置16*2显示,5*7点阵,8位数据接口DelayMS(1);Write_LCD_Command(0x01); /显示清零,数据指针清零DelayMS(1);Write_LCD_Command(0x06);
27、/写一个字符后地址指针自动加1DelayMS(1);Write_LCD_Command(0x0c); /设置开显示,不显示光标DelayMS(1);/-/设置液晶显示位置/-void Set_LCD_POS(uchar p)Write_LCD_Command(p|0x80);/相当于在0x80基础上加入位置量/-在LCD上显示字符串-/void Display_LCD_String(uchar p,uchar *s)uchar i;Set_LCD_POS(p);for(i=0;i16;i+)Write_LCD_Data(si); /在固定位置显示时间日期DelayMS(1);/-日期与时间值转
28、换为数字字符-/void Format_DateTime(uchar d,uchar *a)a0=d/10+0;a1=d%10+0;/判断是否为闰年uchar isLeapYear(uint y)return (y%4=0&y%100!=0)|(y%400=0);/求自2000.1.1开始的任何一天是星期几/函数没有通过,求出总天数后再求星期几/因为求总天数可能会超出uint的范围void RefreshWeekDay()uint i,d,w=5; /已知1999.12.31是周五for(i=2000;i2000+DateTime6;i+)d=isLeapYear(i)?366:365;w=(
29、w+d)%7;d=0;for(i=1;iDateTime4;i+)d+=MonthsDaysi;d+=DateTime3;/保存星期,06表示星期日,星期一,二,.,六,为了与DS1302的星期格式匹配,返回值需要加1DateTime5=(w+d)%7+1;/*年月日时分+/-*/void DateTime_Adjust(char x)switch(Adjust_Index)case 6: /年00-99if(x=1&DateTime60) DateTime6-;/获取2月天数MonthsDays2=isLeapYear(2000+DateTime6)?29:28;/如果年份变化后当前月份的天
30、数大于上限则设为上限if(DateTime3MonthsDaysDateTime4)DateTime3=MonthsDaysDateTime4;RefreshWeekDay(); /刷新星期break;case 4: /月01-12if(x=1&DateTime41) DateTime4-;MonthsDays2=isLeapYear(2000+DateTime6)?29:28;if(DateTime3MonthsDaysDateTime4)DateTime3=MonthsDaysDateTime4;RefreshWeekDay();break;case 3: /日00-28、29、30、31
31、,调节之前首先根据年份得出该年中断二月 天数MonthsDays2=isLeapYear(2000+DateTime6)?29:28;/根据当前月份决定调节日期的上限if(x=1&DateTime30) DateTime3-;RefreshWeekDay();break;case 2: /时if(x=1&DateTime20) DateTime2-;break;case 1:/分if(x=1&DateTime10) DateTime1-;break;/-定时器0每秒刷新LCD显示-/void T0_INT() interrupt 1TH0=-50000/256;TL0=-50000%256;i
32、f(+tCount !=2)return;tCount=0;/按指定格式生成待显示的日期时间串Format_DateTime(DateTime6,LCD_DSY_BUFFER1+5);Format_DateTime(DateTime4,LCD_DSY_BUFFER1+8);Format_DateTime(DateTime3,LCD_DSY_BUFFER1+11);/星期strcpy(LCD_DSY_BUFFER1+13,WEEKDateTime5-1);/时分秒Format_DateTime(DateTime2,LCD_DSY_BUFFER2+5);Format_DateTime(DateTi
33、me1,LCD_DSY_BUFFER2+8);Format_DateTime(DateTime0,LCD_DSY_BUFFER2+11);/显示年月日,星期,时分秒Display_LCD_String(0x00,LCD_DSY_BUFFER1);Display_LCD_String(0x40,LCD_DSY_BUFFER2);/-键盘中断(INT0)-/void EX_INT0() interrupt 0if(K1=0) /选择调整对象(Y M D H M)DelayMS(10);if(K1=0) /while(K1=0);if(Adjust_Index=-1|Adjust_Index=1)A
34、djust_Index=7;Adjust_Index-;if(Adjust_Index=5) Adjust_Index=4;LCD_DSY_BUFFER213=;LCD_DSY_BUFFER214=Change_FlagAdjust_Index; /显示调节对象LCD_DSY_BUFFER215=;else if(K2=0) /加/while(K2=0);DelayMS(10);if(K2=0) DateTime_Adjust(1);else if(K3=0) /减DelayMS(10);/while(K3=0);if(K3=0)DateTime_Adjust(-1);else if(K4=0
35、) /确定/while(K4=0);DelayMS(10);if(K4=0)SET_DS1302(); /将调整后的时间写入DS1302LCD_DSY_BUFFER213= ;LCD_DSY_BUFFER214= ;LCD_DSY_BUFFER215= ;Adjust_Index=-1;void main()Init_LCD();/液晶初始化IE=0x83; /允许INT0,T0中断,EA=1,ET0=1,EX0=1IP=0x01; /设置外部中断0为高级中断IT0=0x01; /外部中断0为电平触发,低电平有效TMOD=0x01; /设置定时器T0工作方式为方式1,TH0=-50000/256;/装入初始值,定时1秒TL0=-50000%256;TR0=1; /启动定时器while(1)/如果未执行调整操作则正常读取当前时间if(Adjust_Index=-1)GetTime();