1、单片机仿真课程设计基于单片机的实时时钟基于 51 系列单片机及 DS1302时钟芯片的实时时钟仿真设计一、课程设计目的意义通过本次课程设计可以灵活运用单片机的基础知识, 依据课程设计内容, 能够完成从硬 件电路图设计, 到软件编程及系统调试实现系统功能, 完成课程设计, 加深对单片机基 础知识的理解并灵活运用。二、实现目标本设计主要为实现一款可正常显示时钟 / 日历的实时电子时钟。对当前电子钟开发手段 进行了比较和分析,最终确定了采用单片机技术实现电子时钟。本设计应用 AT89C52 芯片 作为核心, LCD 显示屏,使用 DS1302 实时时钟日历芯片完成时钟 / 日历的基本功能。这种 实现
2、方法的优点是电路简单,性能可靠,实时性好,时间精确,操作简单,编程容易。三、硬件设计本设计采用具有 32 根 I/O 引脚的 AT89C52单片机。 AT89C52 单片机是一款低功耗,低 电压,高性能 CMOS8 位单片机,片内含 4KB(可经受 1000 次擦写周期)的 FLASH可编程可 反复擦写的只读程序存储器 ( EPRO)M,器件采用 CMOS工艺和 ATMEI公司的高密度、非易失 性存储器 (NURAM)技术制造,其输出引脚和指令系统都与 MCS-52兼容。片内的 FLASH存储器允许在系统内可改编程序或用常规的非易失性存储器编程器来编程。因此, AT89C52 是 一种功能强,
3、灵活性高且价格合理的单片机,可方便的应用在各个控制领域。AT89C52具有以下主要性能:1.4KB 可改编程序 Flash 存储器;2.全静态工作: 0 24Hz;3.1288 字节内部 RAM;4.32 个外部双向输入 /输出( I/O )口;5.6 个中断优先级; 2 个 16 位可编程定时计数器;6.可编程串行通道;7.片内时钟振荡器。DS1302 是美国 DALLAS公司推出的一种高性能、低功耗的实时时钟日历芯片,附加 31字节静态 RAM,采用 SPI 三线接口与 CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和 RAM数据。实时时钟可提供秒、分、时、日、星期、月和年
4、,一个月 小于 31 天时可以自动调整,且具有闰年补偿功能。工作电压宽达 2.5 5.5V 。采用双电源供电 (主电源和备用电源) ,可设置备用电源充电方式,提供了对后备电源进行涓 细电流充电的能力。有主电源和备份电源双引脚,而且备份电源可由大容量电容 ( 1F)来替代。需要强调的是, DS1302需要使用 32.768KHz 的晶振。五、程序源代码#include #include LCD1602.h#include DS1302.hvoid Delay1ms(unsigned int count) unsigned int i,j;for(i=0;icount;i+) for(j=0;j1
5、; / 相当于汇编中的 RRC ACC7 = DS1302_IO;DS1302_CLK = 1;DS1302_CLK = 0;return(ACC);void Write1302(unsigned char ucAddr, unsigned char ucDa) /ucAddr: DS1302 地址 , ucData:要写的数据DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr);DS1302InputByte(ucDa);DS1302_CLK = 1;DS1302_RST = 0;/ 地址,命令 / 写 1B
6、yte 数据unsigned char Read1302(unsigned char ucAddr) / 读取 DS1302 某地址的数据unsigned char ucData;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr|0x01);/ 地址,命令ucData = DS1302OutputByte();/ 读 1Byte 数据DS1302_CLK = 1;DS1302_RST = 0;return(ucData);void DS1302_SetProtect(bit flag) if(flag)Wri
7、te1302(0x8E,0x10); else/ 是否写保护Write1302(0x8E,0x00);void DS1302_SetTime(unsigned char Address, unsigned char Value) /设置时间函数DS1302_SetProtect(0);Write1302(Address, (Value/10)Second = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MINUTE);Time-Minute = (ReadValue&0x70)4)*10 + (Rea
8、dValue&0x0F);ReadValue = Read1302(DS1302_HOUR);Time-Hour = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_DAY);Time-Day = (ReadValue&0x70)4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_WEEK);Time-Week = (ReadValue&0x70)4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS130
9、2_MONTH);Time-Month = (ReadValue&0x70)4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_YEAR);Time-Year = (ReadValue&0x70)4)*10 + (ReadValue&0x0F); void DateToStr(SYSTEMTIME *Time)Time-DateString0 = Time-Year/10 + 0;Time-DateString1 = Time-Year%10 + 0;Time-DateString2 = -;Time-DateString3 = Time
10、-Month/10 + 0;Time-DateString4 = Time-Month%10 + 0;Time-DateString5 = -;Time-DateString6 = Time-Day/10 + 0;Time-DateString7 = Time-Day%10 + 0;Time-DateString8 = 0;void TimeToStr(SYSTEMTIME *Time)Time-TimeString0 = Time-Hour/10 + 0;Time-TimeString1 = Time-Hour%10 + 0;Time-TimeString2 = :;Time-TimeStr
11、ing3 = Time-Minute/10 + 0;Time-TimeString4 = Time-Minute%10 + 0;Time-TimeString5 = :;Time-TimeString6 = Time-Second/10 + 0;Time-TimeString7 = Time-Second%10 + 0; Time-DateString8 = 0;void Initial_DS1302(void) unsigned char Second=Read1302(DS1302_SECOND); if(Second&0x80)DS1302_SetTime(DS1302_SECOND,0
12、);#endif#ifndef LCD_CHAR_1602#define LCD_CHAR_1602#include /Port Definitionsvoid LCD_SetDisplay(unsigned char DisplayMode)LCD_Write(LCD_COMMAND, 0x08|DisplayMode);/ 设置输入模式#define LCD_AC_UP0x02#define LCD_AC_DOWN0x00/ default#define LCD_MOVE0x01/ 画面可平移#define LCD_NO_MOVE0x00/defaultvoid LCD_SetInput(
13、unsigned char InputMode)LCD_Write(LCD_COMMAND, 0x04|InputMode);/ 初始化 LCDvoid LCD_Initial()LcdEn=0;LCD_Write(LCD_COMMAND,0x38); /8 位数据端口 ,2 行显示 ,5*7 点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); / 开启显示 , 无光标 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); / 清屏 LCD_SetInput(LCD_AC_UP|
14、LCD_NO_MOVE); /AC 递增 , 画面不动void GotoXY(unsigned char x, unsigned char y)if(y=0)LCD_Write(LCD_COMMAND,0x80|x);if(y=1) LCD_Write(LCD_COMMAND,0x80|(x-0x40);void Print(unsigned char *str)while(*str!=0) LCD_Write(LCD_DATA,*str); str+;#endif六、仿真结果七、实验心得通过本次课程设计, 我不仅加深了对单片机理论的理解, 而且能够完成从硬件电路 图设计,到软件编程及系统调试实现系统功能这一流程。还学会了如何应用 proteus 进 行仿真,应用 keil 软件进行编程,加深了对 51 系列单片机的理解。在本次课程设计中遇到了一连串的问题, 经过同学们的帮助, 最终完成了本次课程 设计,我不仅学会了如何将所学的理论知识和实际结合起来,也学会了和他人的合作, 而且锻炼了我的实践能力。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1