万年历课程设计_第1页
万年历课程设计_第2页
万年历课程设计_第3页
万年历课程设计_第4页
万年历课程设计_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、万年历课程设计-作者 : _-日期 : _基于 51 单片机的万年历的设计学生姓名学号所在专业电子信息工程所在班级电子 1111小组成员指导教师完成日期基于 51 单片机的万年历的设计需求分析1.1 “需“的分析万年历是一个可以显示当前时间、日历、温度信息以及设置闹钟报警的应用系统,其具有以下功能:1)可以显示当前的时间信息;2)可以显示当前的温度;3)可以手动修改时间;4)可以设置闹钟,并且达到设置的时间点发出音响信号。1.2“求“的分析设计万年历,需要考虑以下几方面的内容:1)如何获取当前的时间信息,这些时间信息包括时、分、秒、年、月、日、和星期;2)如何获得当前的温度信息,精确到 1C即

2、可;3)提供必要的用户输入设置通道;4)提供相应的显示和报警部件;5)需要写出合适的软件应用代码。方案设计与论证2.1时间获取方法的方案设计与论证方案一:使用单片机的内部定时器进行定时,使用软件算法来计算当前的时间信息。此种方案虽然可以不使用时钟芯片,节约成本,但是时间的精准度一般,软件代码复杂。方案二:采用外部扩展实时时钟芯片DS12C887的方式来获取相应的时间信息。DS12C887是一种高性能的芯片,能自动产生年、月、日、时、分、秒等信息,并有闰年修正功能。采用双电源供电方式,可设置备用电源充电方式,提供了对后备电源进行涓细电流的充电的能力,在能满足精度要求的同时价格也比较便宜,性价比较

3、高。所以采用方案二。2.2显示模块的方案设计与论证方案一:采用LED数码管动态扫描。 LED数码管价格适中 , 但只能显示数字和简单的字符,且其的接口线少。方案二:采用点阵式数码管显示。点阵式数码管是由八行八列的发光二极管组成,并不太适合于对数字跟字母进行显示,其主要用于汉字的显示。方案三:采用 LED液晶显示屏。液晶显示屏的显示功能强大, 可显示大量文字 , 图形 , 显示多样, 清晰可见,虽然价格稍微贵了点,但其接口线多。所以采用方案三。2.3温度采集的方案设计与论证方案一:使用 PT铂电阻采集。 PT铂电阻根据温度变化的只是其电阻值,在实际使用过程,需要额外的辅助器件将其转化为电压信号,

4、并且通过调整后送到模/ 数字转换器件才能让 51 单片机进行处理。方案二:使用数字温度传感器采集。温度传感器虽然、精度采样速度等性能比不上 PT铂电阻,但是其没有额外的附加器件,且能满足系统对采集精度的要求。所以采用数字温度传感器。硬件设计3.1万年历的硬件模块显示模块声音报警模块51单片用户输入模块机温度传感器模块时钟日历模块图 3-1万年历的硬件模块3.2 万年历的电路图 3-2 万年历的电路3.3 硬件基础DS1302的硬件基础:时钟芯片 DS1302的工作原理:DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置 “0”,接着把RST端置“1”,最后才给予SCLK脉冲。图

5、5 为 DS1302的控制字的位 7 必须置 1,若为 0 则不能把对 DS1302进行读写数据。对于位6,若对程序进行读 / 写时 RAM=1,对时间进行读/ 写时, CK=0。位 1 至位 5 指操作单元的地址。位0 是读 / 写操作位,进行读操作时,该位为 1;该位为 0 则表示进行的是写操作。控制字节总是从最低位开始输入/ 输出的。 DS1302的日历、时间寄存器内容:“ CH”是时钟暂停标志位,当该位为 1 时,时钟振荡器停止, DS1302处于低功耗状态;当该位为0 时,时钟开始运行。“WP”是写保护位,在任何的对时钟和RAM的写操作之前, WP必须为 0。当“WP”为1 时,写保

6、护位防止对任一寄存器的写操作。(2) DS1302 的控制字节DS1302的控制字如表 -1 所示。控制字节的高有效位(位7)必须是逻辑 1,如果它为 0,则不能把数据写入DS1302中,位 6 如果 0,则表示存取日历时钟数据,为1表示存取 RAM数据;位 5 至位 1 指示操作单元的地址;最低有效位(位0)如为 0 表示要进行写操作,为1 表示进行读操作,控制字节总是从最低位开始输出。表 3-1 DS1302 的控制字格式RAMRD1A4A3A2A1A0/CK/WR数据输入输出( I/O )在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位 0 开

7、始。同样,在紧跟8 位的控制指令字后的下一个SCLK脉冲的下降沿读出 DS1302的数据,读出数据时从低位0 位到高位 7。如下图 3-3 所示:图 3-3 DS1302 读 / 写时序图(4) DS1302 的寄存器DS1302有 12 个寄存器,其中有7 个寄存器与日历、时钟相关,存放的数据位为BCD码形式 , 其日历、时间寄存器及其控制字见表3-2 。表 3-2 DS1302 的日历、时间寄存器此外, DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 DS1302 与 RAM相关的

8、寄存器分为两类:一类是单个RAM单元,共 31 个,每个单元组态为一个8 位的字节,其命令控制字为C0H FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的 31个字节,命令控制字为FEH(写) 、FFH(读) 。1602 液晶的硬件基础:1602 通常有 14 条引脚线或 16 条引脚线的 LCD,多出来的 2 条线是背光电源线VCC(15脚) 和地线 GND(16脚) ,其控制原理与14 脚的 LCD完全一样,引脚定义如表3-所示:表 3-3 1602 的引脚及其对应的功能1602 支持的一系列指令:( 1)清屏指令:表 3-4 清

9、屏指令归零指令:表 3-5 归零指令( 3)输入方式选择指令:表 3-6 输入方式选择指令( 4)显示开关控制指令:表 3-7 显示开关控制指令光标和画面移动指令:表 3-8 光标和画面移动指令( 6)功能设定指令:表 3-9 功能设定指令(7) CGRAM设置指令:表 3-10 CGRAM设置指令(8)DDRAM设置指令:表 3-11 DDRAM设置指令( 9)读 BF和 AC指令:表 3-12 读 BF 和 AC指令( 10)写数据指令:表 3-13 写数据指令( 11)读数据指令:表 3-14 读数据指令软件设计系统初始化初始化时钟芯片和液晶显读取 DS1302的时钟数据读取 DS18B

10、20数据并且显示当前的数据和温度是驱动蜂鸣器报警时钟数据否是设置闹钟按键被按图 4-1 万年历的工作流程总结5.1仿真结果及分析经过多次调试、修改程序,万年历终于在pruteus 正常运行起来了。前面由于初次写的代码有较多不完善的地方,所以调试的时候出了很多大的问题,第一次发现大的问题后,团队认真地讨论并修改了程序,后面调试遇到的都是些小问题,无非是打漏或者打错这类问题。5.2心得工程上的问题很多不是一个人的能力可以解决的,所以不能老是想着单干、蛮干,一定要发挥团队的力量,多讨论,讨论往往可以碰撞出思想的火花来。做事的时候一定要静下心来,保持专注,不能老想着快,不然会弄出很多本可以避免的问题,

11、敲代码的时候,为了求快,结果调试的遇到小问题花了可不少时间才解决。本次课程设计,让我知道了要想解决工程上的问题,必须现将问题具体化、模块化,然后再逐个击破,这样才能更有效率地解决整个工程设计再到实物的问题。附录一:仿真图附录二:程序#include#include#define TIME (0X10000-50000)#define FLAG 0XEF/ 闹钟标志引脚连接图sbit rst=P35;sbit clk=P34;sbit dat=P33;sbit rs=P15;sbit rw=P16;sbit e=P17;sbit DQ=P14;/温度输入口sbit ACC_7=ACC7;全局变量

12、及常量定义unsigned char i=20,j,time116;unsigned char alarm2,time215,time3;unsigned char code Day=31,28,31,30,31,30,31,31,30,31,30,31;/12个月的最大日期 ( 非闰年 )音律表unsigned int code table1=64260,64400,64524,64580,64684,64777, 64820,64898,64968,65030,65058,65110,65157,65178,65217;发声部分的延时时间unsigned char code table2=

13、0 x82,1,0 x81,0 xf4,0 xd4,0 xb4,0 xa4, 0 x94,0 xe2,1,0 xe1,0 xd4,0 xb4,0 xc4,0 xb4,4,0;/LCD 自建字unsigned char code tab=0 x18,0 x1b,5,4,4,5,3,0,0 x08,0 x0f,0 x12,0 x0f,0 x0a,0 x1f,0 x02,0 x02,/年0 x0f,0 x09,0 x0f,0 x09,0 x0f,0 x09,0 x11,0 x00,/月0 x0f,0 x09,0 x09,0 x0f,0 x09,0 x09,0 x0f,0 x00;/日/*温度小数部分

14、用查表法 */unsigned char codeditab16=0 x00,0 x01,0 x01,0 x02,0 x03,0 x03,0 x04,0 x04,0 x05,0 x06,0 x06,0 x07,0 x08,0 x08,0 x09,0 x09;闹钟中用的全局变量unsigned char th1,tl1;unsigned char temp_data2=0 x00,0 x00;/读出温度暂放bit flag;/18b20存在标志位/*11微秒延时函数*/delay(unsigned int t)for(;t0;t-);/*18B20复位函数 */RST18B20(void)uns

15、igned char i;DQ=1;_nop_();_nop_();DQ=0;/delay(50); / 550usDQ=1;/delay(6); / 66usfor(i=0;i0; i-) /DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();/5usDQ=val&0 x01;/最低位移出delay(6);/66usval=val/2;/右移一位DQ=1;delay(1);/*18B20读 1 个字节函数 */从总线上读取一个字节unsigned char Read1Byte18B20(void)unsigned

16、 char i;unsigned char value=0;for (i=8;i0;i-)DQ=1;_nop_();_nop_();value=1;DQ=0;/_nop_();_nop_();_nop_();_nop_();/4usDQ=1;_nop_();_nop_();_nop_();_nop_();/4usif(DQ)value|=0 x80;delay(6);/66usDQ=1;return(value);/*读出温度函数 */Read18B20()RST18B20();/ 总线复位if(!flag)/ 判断 ds1820 是否存在 ?若ds18b20 不存在则返回return;/Wr

17、ite1Byte18B20(0 xCC);/Write1Byte18B20(0 x44);/delay(70);/ Skip ROM/发转换命令Write1Byte18B20(0 xCC);/ 发Skip ROM命令Write1Byte18B20(0 xBE);/ 发读命令temp_data0=Read1Byte18B20();/温度低8 位temp_data1=Read1Byte18B20();/温度高8 位RST18B20();Write1Byte18B20(0 xCC);/ Skip ROMWrite1Byte18B20(0 x44);/发转换命令/*温度数据处理函数 */DealTem

18、pData()unsigned char n=0,m;if(temp_data1127)/负温度求补码temp_data1=(256-temp_data1);temp_data0=(256-temp_data0);n=1;time213=ditabtemp_data0&0 x0f+0;time212=.;m=(temp_data0&0 xf0)4)|(temp_data1&0 x0f)4);/if(n)m-=16;time29=m/100+0;time211=m%100;time210=time211/10+0;time211=time211%10+0;if(time29=0)/最高位为 0

19、时都不显示time29=0 x20;if(n)/负温度时最高位显示 -time29=-;if(time210=0)if(n)time210=-;time29=0 x20;elsetime210=0 x20;if(time211=0&time213=0)time211=time212=0 x20;delay1ms(unsigned char time)/ 延时 1msunsigned char i,j;for(i=0;itime;i+)for(j=0;j250;j+);/ 使能 1602EnableLCD()rs=0;rw=0;e=0;delay1ms(3);e=1;写 LCD函数WriteLC

20、D(unsigned char i)P0=i;rs=1;rw=0;e=0;delay1ms(2);e=1;写 LCD内部地址函数WriteLCDRAM(unsigned char data *address,m)unsigned char i,j;for(i=0;im;i+,address+)j=*address;WriteLCD(j);/LCD 显示LCDSHOW()P0=0XC;/ 显示器开、光标关EnableLCD();P0=0 x80;/ 写入显示起始地址EnableLCD();WriteLCDRAM(time1,16);P0=0 xc1;/ 写入显示起始地址EnableLCD();W

21、riteLCDRAM(time2,15);自建字函数库DesignHZ()unsigned char i;P0=0 x40;EnableLCD();for(i=0;i32;i+)WriteLCD(tabi);delay1ms(2);/ 写 DS1302子程序WriteDS1302(unsigned char address)unsigned char i;clk=0;_nop_();rst=1;_nop_();for(i=0;i=1;clk=0;/ 读 DS1302子程序unsigned char ReadDS1302()unsigned char i,j=0;for(i=0;i=1;_nop

22、_();clk=0;_nop_();if(dat)j|=0 x80;_nop_();clk=1;return(j);部分显示数据初始化TimeInit()time11=time113=time28=time29=time210=0 x20,time214=0; time16=1,time19=2,time112=3,time12=2,time13=0;time114=W,time22=time25=:;WriteDS1302(0 xc1);alarm0=ReadDS1302();rst=0;WriteDS1302(0 xc3);alarm1=ReadDS1302();rst=0;WriteDS

23、1302(0 xc5);time10=ReadDS1302();rst=0;读取时间ReadTime()unsigned char i,m,n;WriteDS1302(0 x8d);/ 读取年份m=ReadDS1302();rst=0;time14=m/16+0 x30;time15=m%16+0 x30;WriteDS1302(0 x8b);/ 读取星期m=ReadDS1302();rst=0;time115=m+0 x30;for(i=7,n=0 x89;i11;i+=3,n-=2)/ 读取月份和日期WriteDS1302(n);m=ReadDS1302();rst=0;time1i=m/

24、16+0 x30;time1i+1=m%16+0 x30;for(m=0,i=0,n=0 x85;i7;i+=3,n-=2,m+)/ 读取时 , 分, 秒WriteDS1302(n);timem=ReadDS1302();rst=0;time2i=timem/16+0 x30;time2i+1=timem%16+0 x30;time0() interrupt 1 using 1i-;if(i=0)if(j!=0)j-;i=20;TH0=TIME/256,TL0=TIME%256;闹钟部分intime1() interrupt 3TH1=th1,TL1=tl1;P3_2=!P3_2;显示闹钟设置

25、数据showalarm()unsigned char i,j,a,b,n;ET1=1;for(j=0;j=4;if(a=0)TR1=0;goto D1;D1:a=(-a)1)/2;TH1=th1=table1a/256,TL1=tl1=table1a%256;TR1=1;dob-;for(n=0;n2)i+;j=(time110&0 xf)*10+(time111&0 xf);i+=j;i%=7;if(i=0)i=7;return(i);设置时间settime()unsigned char i=0 x85,year,month,day,n;time26=time27=0 x30,time114

26、=time115=0 x20;LCDSHOW();while(1)P0=0 xe;/ 显示器开、光标开EnableLCD();P0=i;/ 定光标EnableLCD();P2=0 xf7;if(P2!=0XF7)if(P2!=0XF7)j=7;if(P2=0X77)i+=3;if(i=0 x8e)i=0 xc2;else if(i0 xc5)i=0 x85;else if(P2=0 xb7)year=(time14&0 xf)*10+(time15&0 xf);month=(time17&0 xf)*10+(time18&0 xf);day=(time110&0 xf)*10+(time111

27、&0 xf);if(i=0 x85)year+;if(year99)year=0;if(year%4)!=0)if(month=2&day=29)day=28;else if(i=0 x88)month+;if(month12)month=1;if(dayDaymonth-1)day=Daymonth-1;if(month=2&(year%4)=0)day=29;else if(i=0 x8b)day+;if(dayDaymonth-1)if(month=2&(year%4)=0)if(day29)day=1;if(month!=2)day=1;else if(i=0 xc2)n=(time20&0 xf)*10+(time21&0 xf);n+;if(n23)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论