单片机课程设计报告-带温度显示的电子钟_第1页
单片机课程设计报告-带温度显示的电子钟_第2页
单片机课程设计报告-带温度显示的电子钟_第3页
单片机课程设计报告-带温度显示的电子钟_第4页
单片机课程设计报告-带温度显示的电子钟_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

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

文档简介

1、一、 方案该作品是个性化电子钟设计,技术上主要用单片机(AT89c51)主控,16脚的液晶显示,有DS1302芯片制作电子时钟,用DS18B20芯片来完成温度的测控。二、电路特色 此次设计的带温度显示的电子钟,具有万年历(调节),整点报时,闹钟,蜂鸣器播放音乐(生日快乐歌)等功能。三、流程图四、程序#include #include /#include LCD1602.h/#include DS1302.h#define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P17; /实时时钟时钟线引脚sbit DS130

2、2_IO = P16; /实时时钟数据线引脚sbit DS1302_RST = P15; /实时时钟复位线引脚sbit beep=P34;sbit ACC0 = ACC0;sbit ACC7 = ACC7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year,hide_m,hide_f,hide_h;sbit Set = P20; /模式切换键sbit Up = P21; /加法按钮sbit Down = P22; /减法按钮sbit out = P23; /立刻跳出调整模式按钮sbit DQ = P1

3、0; /温度传送数据IO口sbit dd=P24;char done,count,temp,flag,up_flag,down_flag,key;uchar temp_value; /温度值uchar m,f,h,mo,d,y,w,kaiguan,h=12,f=30;uchar TempBuffer5,week_value2,nao8;void naotime();uchar code tone=212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,159,169,190,119,119,126,159,142,159,

4、0;uchar code lon=9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0;void delay(uint z)uint x,y;for(x=z;x0;x-)for(y=110;y0;y-);void music()uint i,j,k=0,m;for(m=0;m26;m+)for(i=0;ilonk*20;i+)beep=beep;for(j=0;j0; i-)DS1302_IO = ACC0; /相当于汇编中的 RRCDS1302_CLK = 1;DS1302_CLK = 0;ACC = ACC

5、 1;unsigned char DS1302OutputByte(void) /实时时钟读取一字节(内部函数)unsigned char i;for(i=8; i0; i-)ACC = ACC 1; /相当于汇编中的 RRCACC7 = 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

6、 = 1;DS1302InputByte(ucAddr); / 地址,命令DS1302InputByte(ucDa); / 写1Byte数据DS1302_CLK = 1;DS1302_RST = 0;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数

7、据DS1302_CLK = 1;DS1302_RST = 0;return(ucData);void DS1302_GetTime(SYSTEMTIME *Time) /获取时钟芯片的时钟数据到自定义的结构型数组unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);Time-Second = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MINUTE);Time-Minute = (ReadValue&0x70)4)*10 + (Read

8、Value&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(DS1302_M

9、ONTH);Time-Month = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_YEAR);Time-Year = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);void DateToStr(SYSTEMTIME *Time) /将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString if(hide_year2) /这里的if,else语句都是判断位闪烁,2就不显示,输出字符串为 2007/07/22Time-DateString0 = 2

10、;Time-DateString1 = 0;Time-DateString2 = Time-Year/10 + 0;Time-DateString3 = Time-Year%10 + 0;elseTime-DateString0 = ;Time-DateString1 = ;Time-DateString2 = ;Time-DateString3 = ;Time-DateString4 = /;if(hide_monthDateString5 = Time-Month/10 + 0;Time-DateString6 = Time-Month%10 + 0;elseTime-DateString

11、5 = ;Time-DateString6 = ;Time-DateString7 = /;if(hide_dayDateString8 = Time-Day/10 + 0;Time-DateString9 = Time-Day%10 + 0;Time-DateString10 = ;Time-DateString11 = ;elseTime-DateString8 = ;Time-DateString9 = ;Time-DateString10 = ;Time-DateString11 = ;if(hide_weekWeek%10 + 0; /星期的数据另外放到 week_value数组里,

12、跟年,月,日的分开存放,因为等一下要在最后显示elseweek_value0 = ;week_value1 = 0;Time-DateString10 = 0; /字符串末尾加 0 ,判断结束字符void TimeToStr(SYSTEMTIME *Time) /将时,分,秒数据转换成液晶显示字符放到数组 TimeString;if(hide_hourTimeString0 = Time-Hour/10 + 0;Time-TimeString1 = Time-Hour%10 + 0;elseTime-TimeString0 = ;Time-TimeString1 = ;Time-TimeStr

13、ing2 = :;if(hide_minTimeString3 = Time-Minute/10 + 0;Time-TimeString4 = Time-Minute%10 + 0;elseTime-TimeString3 = ;Time-TimeString4 = ;Time-TimeString5 = :;if(hide_secTimeString6 = Time-Second/10 + 0;Time-TimeString7 = Time-Second%10 + 0;Time-TimeString8 = ;elseTime-TimeString6 = ;Time-TimeString7 =

14、 ;Time-TimeString8 = ;Time-DateString9 = 0;void baoshi(SYSTEMTIME *Time)if(Time-HourHour8&Time-Minute/10=0&Time-Minute%10=0&Time-Second/10=0&Time-Second%10=0)music();void naozhong(SYSTEMTIME *Time) if(Time-Minute%10=(f%10)&Time-Minute/10=(f/10)&Time-Hour%10=(h%10)&Time-Hour/10=(h/10)&Time-Second%10=

15、(m%10)&Time-Second/10=(m/10) music();void Initial_DS1302(void) /时钟芯片初始化unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) /判断时钟芯片是否关闭Write1302(0x8e,0x00); /写入允许Write1302(0x8c,0x07); /以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55Write1302(0x88,0x07);Write1302(0x86,0x25);Write1302(0x8a,0x07);Wri

16、te1302(0x84,0x23);Write1302(0x82,0x59);Write1302(0x80,0x55);Write1302(0x8e,0x80); /禁止写入/*ds18b20子程序*/*ds18b20延迟子函数(晶振12MHz )*/void delay_18B20(unsigned int i)while(i-);/*ds18b20初始化函数*/void Init_DS18B20(void)unsigned char x=0;DQ = 1; /DQ复位delay_18B20(8); /稍做延时DQ = 0; /单片机将DQ拉低delay_18B20(80); /精确延时 大

17、于 480usDQ = 1; /拉高总线delay_18B20(14);x=DQ; /稍做延时后 如果x=0则初始化成功 x=1则初始化失败delay_18B20(20);/*ds18b20读一个字节*/unsigned char ReadOneChar(void)uchar i=0;uchar dat = 0;for (i=8;i0;i-)DQ = 0; / 给脉冲信号dat=1;DQ = 1; / 给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);return(dat);/*ds18b20写一个字节*/void WriteOneChar(uchar dat)unsig

18、ned char i=0;for (i=8; i0; i-)DQ = 0;DQ = dat&0x01;delay_18B20(5);DQ = 1;dat=1;/*读取ds18b20当前温度*/void ReadTemp(void)unsigned char a=0;unsigned char b=0;unsigned char t=0;Init_DS18B20();WriteOneChar(0xCC); / 跳过读序号列号的操作WriteOneChar(0x44); / 启动温度转换delay_18B20(100); / this message is wery importantInit_D

19、S18B20();WriteOneChar(0xCC); /跳过读序号列号的操作WriteOneChar(0xBE); /读取温度寄存器等(共可读9个寄存器) 前两个就是温度delay_18B20(100);a=ReadOneChar(); /读取温度值低位b=ReadOneChar(); /读取温度值高位temp_value=b4;void temp_to_str() /温度数据转换成液晶字符显示TempBuffer0=temp_value/10+0; /十位TempBuffer1=temp_value%10+0; /个位TempBuffer2=0xdf; /温度符号TempBuffer3=

20、C;TempBuffer4=0;void naoz() if(hide_h2) nao0=h/10+0; nao1=h%10+0;elsenao0= ; nao1= ; nao2=:;if(hide_f2) nao3=f/10+0; nao4=f%10+0;elsenao3= ;nao4= ; nao5=:;if(hide_m2) nao6=m/10+0; nao7=m%10+0;else nao6= ; nao7= ; nao8=0;void Delay1ms(unsigned int count)unsigned int i,j;for(i=0;icount;i+)for(j=0;j0;d

21、elay-)for(i=0;i0x59) /超过59秒,清零temp=0;break;case 2:temp=Read1302(DS1302_MINUTE); /读取分数temp=temp+1; /分数加1up_flag=1;if(temp=0)music();delay(2);if(temp0x59) /超过59分,清零temp=0;break;case 3:temp=Read1302(DS1302_HOUR); /读取小时数temp=temp+1; /小时数加1up_flag=1;if(temp0x23) /超过23小时,清零temp=0;break;case 4:temp=Read130

22、2(DS1302_WEEK); /读取星期数temp=temp+1; /星期数加1up_flag=1;if(temp0x7)temp=1;break;case 5:temp=Read1302(DS1302_DAY); /读取日数temp=temp+1; /日数加1up_flag=1;if(temp0x31)temp=1;break;case 6:temp=Read1302(DS1302_MONTH); /读取月数temp=temp+1; /月数加1up_flag=1;if(temp0x12)temp=1;break;case 7:temp=Read1302(DS1302_YEAR); /读取年

23、数temp=temp+1; /年数加1up_flag=1;if(temp0x85)temp=0;break;default:break;while(Up=0);void Upkey1()/升序按键Up=1;if(Up=0)mdelay(8);switch(count)case 1:m=m+1; /秒数加1up_flag=1; /数据调整后更新标志if(m59) /超过59秒,清零m=0;break;case 2:f=f+1; /分数加1up_flag=1;if(f59) /超过59分,清零f=0;break;case 3:h=h+1; /小时数加1up_flag=1;if(h23) /超过23

24、小时,清零h=0;break;default:break;while(Up=0);/ void Downkey()/降序按键Down=1;if(Down=0)mdelay(8);switch(count)case 1:temp=Read1302(DS1302_SECOND); /读取秒数temp=temp-1; /秒数减1down_flag=1; /数据调整后更新标志if(temp=0x7f) /小于0秒,返回59秒temp=0x59;break;case 2:temp=Read1302(DS1302_MINUTE); /读取分数temp=temp-1; /分数减1down_flag=1;if

25、(temp=-1)temp=0x59; /小于0秒,返回59秒break;case 3:temp=Read1302(DS1302_HOUR); /读取小时数temp=temp-1; /小时数减1down_flag=1;if(temp=-1)temp=0x23;break;case 4:temp=Read1302(DS1302_WEEK); /读取星期数temp=temp-1; /星期数减1down_flag=1;if(temp=0)temp=0x7;break;case 5:temp=Read1302(DS1302_DAY); /读取日数temp=temp-1; /日数减1down_flag=

26、1;if(temp=0)temp=31;break;case 6:temp=Read1302(DS1302_MONTH); /读取月数temp=temp-1; /月数减1down_flag=1;if(temp=0)temp=12;break;case 7:temp=Read1302(DS1302_YEAR); /读取年数temp=temp-1; /年数减1down_flag=1;if(temp=-1)temp=0x85;break;default:break;while(Down=0);void Downkey1()/降序按键Down=1;if(Down=0)mdelay(8);switch(

27、count)case 1:m=m-1; /秒数减1down_flag=1; /数据调整后更新标志if(m=0) /小于0秒,返回59秒m=59;break;case 2:f=f-1; /分数减1down_flag=1;if(f=-1)f=59; /小于0秒,返回59秒break;case 3:h=h-1; /小时数减1down_flag=1;if(h=-1)h=23;break;default:break;while(Down=0);void Setkey()/模式选择按键Set=1;if(Set=0)mdelay(8);count=count+1; /Setkey按一次,count就加1do

28、ne=1; /进入调整模式while(Set=0);void setkey1()dd=1;if(dd=0)mdelay(8);kaiguan=1; /naotime();count=count+1; /Setkey按一次,count就加1key=1; /进入调整模式while(dd=0);void keydone()/按键功能执行 uchar Second;if(flag=0) /关闭时钟,停止计时 Write1302(0x8e,0x00); /写入允许temp=Read1302(0x80);Write1302(0x80,temp|0x80);Write1302(0x8e,0x80); /禁止

29、写入flag=1;Setkey(); /扫描模式切换按键switch(count)case 1:do /count=1,调整秒outkey(); /扫描跳出按钮Upkey(); /扫描加按钮Downkey(); /扫描减按钮if(up_flag=1|down_flag=1) /数据更新,重新写入新的数据Write1302(0x8e,0x00); /写入允许Write1302(0x80,temp|0x80); /写入新的秒数Write1302(0x8e,0x80); /禁止写入up_flag=0;down_flag=0;hide_sec+; /位闪计数if(hide_sec3)hide_sec=

30、0;show_time(); /液晶显示数据while(count=2);break;case 2:do /count=2,调整分hide_sec=0;outkey();Upkey();Downkey();if(temp0x60)temp=0;if(up_flag=1|down_flag=1)Write1302(0x8e,0x00); /写入允许Write1302(0x82,temp); /写入新的分数Write1302(0x8e,0x80); /禁止写入up_flag=0;down_flag=0;hide_min+;if(hide_min3)hide_min=0;show_time();wh

31、ile(count=3);break;case 3:do /count=3,调整小时hide_min=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0x8e,0x00); /写入允许Write1302(0x84,temp); /写入新的小时数Write1302(0x8e,0x80); /禁止写入up_flag=0;down_flag=0;hide_hour+;if(hide_hour3)hide_hour=0;show_time();while(count=4);break;case 4:do /count=4,

32、调整星期hide_hour=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0x8e,0x00); /写入允许Write1302(0x8a,temp); /写入新的星期数Write1302(0x8e,0x80); /禁止写入up_flag=0;down_flag=0;hide_week+;if(hide_week3)hide_week=0;show_time();while(count=5);break;case 5:do /count=5,调整日hide_week=0;outkey();Upkey();Downk

33、ey();if(up_flag=1|down_flag=1)Write1302(0x8e,0x00); /写入允许Write1302(0x86,temp); /写入新的日数Write1302(0x8e,0x80); /禁止写入up_flag=0;down_flag=0;hide_day+;if(hide_day3)hide_day=0;show_time();while(count=6);break;case 6:do /count=6,调整月hide_day=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0x8

34、e,0x00); /写入允许Write1302(0x88,temp); /写入新的月数Write1302(0x8e,0x80); /禁止写入up_flag=0;down_flag=0;hide_month+;if(hide_month3)hide_month=0;show_time();while(count=7);break;case 7:do /count=7,调整年hide_month=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0x8e,0x00); /写入允许Write1302(0x8c,temp);

35、 /写入新的年数Write1302(0x8e,0x80); /禁止写入up_flag=0;down_flag=0;hide_year+;if(hide_year3)hide_year=0;show_time();while(count=8);break;case 8: count=0;hide_year=0; /count8, 跳出调整模式,返回默认显示状态Second=Read1302(DS1302_SECOND);Write1302(0x8e,0x00); /写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); /禁止写入done=0;break; /count=7,开启中断,标志位置0并退出default:break;void keydone1()/按键功能执行 uchar Second;setkey1(); /扫描模式切换按键switch(count)case 1:do /count=1,调整秒outkey1(); /扫描跳出按钮Upkey1(); /扫描加按钮Downkey1(); /扫描减按钮hide_m+; /位闪计数if(hide_m3)hide_m=0;naoti

温馨提示

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

评论

0/150

提交评论