ImageVerifierCode 换一换
格式:DOCX , 页数:36 ,大小:536.63KB ,
资源ID:8117308      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8117308.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(万年历课程设计完整版.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

万年历课程设计完整版.docx

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

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

3、流的充电的能力,在能满足精度要求的同时价格也比较便宜,性价比较高。 所以采用方案二。2.2 显示模块的方案设计与论证 方案一:采用LED数码管动态扫描。LED数码管价格适中,但只能显示数字和简单的 字符,且其的接口线少。方案二: 采用点阵式数码管显示。点阵式数码管是由八行八列的发光二极管组成,并不太适合于对数字跟字母进行显示,其主要用于汉字的显示。 方案三: 采用LED液晶显示屏。液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见,虽然价格稍微贵了点,但其接口线多。 所以采用方案三。 2.3 温度采集的方案设计与论证 方案一: 使用PT铂电阻采集。PT铂电阻根据温度变化的只是其

4、电阻值,在实际使用过程,需要额外的辅助器件将其转化为电压信号,并且通过调整后送到模/数字转换器件才能让51单片机进行处理。 方案二:使用数字温度传感器采集。温度传感器虽然、精度采样速度等性能比不上PT铂电阻,但是其没有额外的附加器件,且能满足系统对采集精度的要求。 所以采用数字温度传感器。 3 硬件设计 3.1 万年历的硬件模块 显示模 声音报警模块51 单 片 机用户输入模块 时钟日历模块 温度传感器模块 图3-1 万年历的硬件模块 3.2 万年历的电路 图3-2 万年历的电路 3.3硬件基础 DS1302的硬件基础: (1) 时钟芯片DS1302的工作原理: DS1302在每次进行读、写程

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

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

7、,数据输入从低位即位0开始。同样,在紧跟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位的字节,其命令控制字为C0HFDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。 1602液晶的硬件基础 : 1602通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,引脚定义如表3-3所示: 的引脚及其对应的功能3-3 1602表 1602支持的一系列指令: (1)清屏指令: 清屏指令3-4 表 (2)归零指令: 表3-5 归零指令

9、(3)输入方式选择指令: 表3-6 输入方式选择指令 (4)显示开关控制指令: 表3-7显示开关控制指令 (5) 光标和画面移动指令: 表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读数据指令 4 软件设计 系统初始化 初始化时钟芯片和液晶显示 读取DS1302的时钟数据 读取DS18B20数据并且 进行相应的处理 显示

10、当前的数据和温度数驱动蜂鸣器报闹钟信息按键被按设置闹4-1万年历的工作流 5 总结 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=

12、ACC7; /全局变量及常量定义 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

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

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

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

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

17、返回 return; /Write1Byte18B20(0xCC); / Skip ROM /Write1Byte18B20(0x44); / 发转换命令 /delay(70); Write1Byte18B20(0xCC); /发Skip ROM命令 Write1Byte18B20(0xBE); /发读命令 temp_data0=Read1Byte18B20(); /温度低8位 temp_data1=Read1Byte18B20(); /温度高8位 RST18B20(); Write1Byte18B20(0xCC); / Skip ROM Write1Byte18B20(0x44); / 发转

18、换命令 /*温度数据处理函数*/ DealTempData() unsigned char n=0,m; if(temp_data1127)/负温度求补码 temp_data1=(256-temp_data1); temp_data0=(256-temp_data0); n=1; time213=ditabtemp_data0&0x0f+0; time212=.; m=(temp_data0&0xf0)4)|(temp_data1&0x0f)4);/ if(n) m-=16; time29=m/100+0; time211=m_x0010_0; time210=time211/10+0; ti

19、me211=time211_x0010_+0; 时都不显示0最高位为if(time29=0)/ time29=0x20; if(n)/负温度时最高位显示- time29=-; if(time210=0) if(n) time210=-; time29=0x20; else time210=0x20; if(time211=0&time213=0) time211=time212=0x20; delay1ms(unsigned char time) /延时1ms unsigned char i,j; for(i=0;itime;i+) for(j=0;j250;j+); /使能1602 Enab

20、leLCD() rs=0; rw=0; e=0; delay1ms(3); e=1; /写LCD函数 WriteLCD(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=0x80; /写

21、入显示起始地址 EnableLCD(); WriteLCDRAM(time1,16); P0=0xc1; /写入显示起始地址 EnableLCD(); WriteLCDRAM(time2,15); /自建字函数库 DesignHZ() unsigned char i; P0=0x40; EnableLCD(); for(i=0;i32;i+) WriteLCD(tabi); delay1ms(2); /写DS1302子程序 WriteDS1302(unsigned char address) unsigned char i; clk=0; _nop_(); rst=1; _nop_(); fo

22、r(i=0;i=1; clk=0; /读DS1302子程序 unsigned char ReadDS1302() unsigned char i,j=0; for(i=0;i=1; _nop_(); clk=0; _nop_(); if(dat) j|=0x80; _nop_(); clk=1; return(j); /部分显示数据初始化 TimeInit() time11=time113=time28=time29=time210=0x20,time214=0; time16=1,time19=2,time112=3,time12=2,time13=0; time114=W,time22=t

23、ime25=:; WriteDS1302(0xc1); alarm0=ReadDS1302(); rst=0; WriteDS1302(0xc3); alarm1=ReadDS1302(); rst=0; WriteDS1302(0xc5); time10=ReadDS1302(); rst=0; /读取时间 ReadTime() unsigned char i,m,n; WriteDS1302(0x8d); /读取年份 m=ReadDS1302(); rst=0; time14=m/16+0x30; time15=m_x0016_+0x30; WriteDS1302(0x8b); /读取星期

24、 m=ReadDS1302(); rst=0; time115=m+0x30; for(i=7,n=0x89;i11;i+=3,n-=2) /读取月份和日期 WriteDS1302(n); m=ReadDS1302(); rst=0; time1i=m/16+0x30; time1i+1=m_x0016_+0x30; for(m=0,i=0,n=0x85;i7;i+=3,n-=2,m+) /读取时,分,秒 WriteDS1302(n); timem=ReadDS1302(); rst=0; time2i=timem/16+0x30; time2i+1=timem_x0016_+0x30; ti

25、me0() interrupt 1 using 1 i-; if(i=0) if(j!=0) j-; i=20; TH0=TIME/256,TL0=TIME%6; /闹钟部分 intime1() interrupt 3 TH1=th1,TL1=tl1; P3_2=!P3_2; /显示闹钟设置数据 showalarm() unsigned char i,j,a,b,n; ET1=1; for(j=0;j=4; if(a=0) TR1=0; goto D1; a=(-a)1)/2; TH1=th1=table1a/256,TL1=tl1=table1a%6; TR1=1; D1: do b-; for(n=0;n3;n+) ReadTime(); LCDSHOW(); P2=0xf7; if(P2=0xe7) delay1m

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1