《DS1302时钟+DS18B20+无线遥控应用程序.pdf》由会员分享,可在线阅读,更多相关《DS1302时钟+DS18B20+无线遥控应用程序.pdf(22页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、DS1302DS1302时钟时钟+DS18B20+DS18B20+无线遥控应用程序无线遥控应用程序#include#include/#include LCD1602.h/#include DS1302.h#define uint unsigned int#define uchar unsigned charsbitDS1302_CLK=P17;/实时时钟时钟线引脚sbitDS1302_IO=P16;/实时时钟数据线引脚sbitDS1302_RST=P15;/实时时钟复位线引脚sbitwireless_1=P30;sbitwireless_2=P31;sbitwireless_3=P32;sbi
2、twireless_4=P33;sbitACC0=ACC0;sbitACC7=ACC7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;/秒,分,时到日,月,年位闪的计数sbit Set=P20;/模式切换键sbit Up=P21;/加法按钮sbit Down=P22;/减法按钮sbit out=P23;/立刻跳出调整模式按钮sbit DQ=P10;/温度传送数据 IO 口char done,count,temp,flag,up_flag,down_flag;uchar temp_value;/温
3、度值ucharTempBuffer5,week_value2;void show_time();/液晶显示程序/*1602液晶显示部分子程序*/Port Definitions*sbit LcdRs=P25;sbit LcdRw=P26;sbit LcdEn=P27;sfrDBPort=0 x80;/P0=0 x80,P1=0 x90,P2=0 xA0,P3=0 xB0.数据端口/内部等待函数*unsigned char LCD_Wait(void)LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_();LcdEn=0;return DBPort;/向 LCD 写入命令
4、或数据*#define LCD_COMMAND0/Command#define LCD_DATA1/Data#define LCD_CLEAR_SCREEN 0 x01/清屏#define LCD_HOMING0 x02/光标返回原点void LCD_Write(bit style,unsigned char input)LcdEn=0;LcdRs=style;LcdRw=0;_nop_();DBPort=input;_nop_();/注意顺序LcdEn=1;_nop_();/注意顺序LcdEn=0;_nop_();LCD_Wait();/设置显示模式*#define LCD_SHOW0 x0
5、4/显示开#define LCD_HIDE0 x00/显示关#define LCD_CURSOR0 x02/显示光标#define LCD_NO_CURSOR0 x00/无光标#define LCD_FLASH0 x01/光标闪动#define LCD_NO_FLASH0 x00/光标不闪动void LCD_SetDisplay(unsigned char DisplayMode)LCD_Write(LCD_COMMAND,0 x08|DisplayMode);/设置输入模式*#define LCD_AC_UP0 x02#define LCD_AC_DOWN0 x00/default#defi
6、ne LCD_MOVE0 x01/画面可平移#define LCD_NO_MOVE0 x00/defaultvoid LCD_SetInput(unsigned char InputMode)LCD_Write(LCD_COMMAND,0 x04|InputMode);/初始化 LCD*void LCD_Initial()LcdEn=0;LCD_Write(LCD_COMMAND,0 x38);/8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0 x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);/开启显示,无光标LCD_Wr
7、ite(LCD_COMMAND,LCD_CLEAR_SCREEN);/清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);/AC 递增,画面不动/液晶字符输入的位置*void GotoXY(unsigned char x,unsigned char y)if(y=0)LCD_Write(LCD_COMMAND,0 x80|x);if(y=1)LCD_Write(LCD_COMMAND,0 x80|(x-0 x40);/将字符输出到液晶显示void Print(unsigned char*str)while(*str!=0)LCD_Write(LCD_DATA,*str)
8、;str+;/*DS1302时钟部分子程序*/typedef struct _SYSTEMTIME_unsigned char Second;unsigned char Minute;unsigned char Hour;unsigned char Week;unsigned char Day;unsigned char Month;unsigned charYear;unsigned char DateString11;unsigned char TimeString9;SYSTEMTIME;/定义的时间类型SYSTEMTIME CurrentTime;#define AM(X)X#defi
9、ne PM(X)(X+12)/转成24小时制#define DS1302_SECOND 0 x80/时钟芯片的寄存器位置,存放时间#define DS1302_MINUTE 0 x82#define DS1302_HOUR0 x84#define DS1302_WEEK0 x8A#define DS1302_DAY0 x86#define DS1302_MONTH 0 x88#define DS1302_YEAR0 x8Cvoid DS1302InputByte(unsigned char d)/实时时钟写入一字节(内部函数)unsigned char i;ACC=d;for(i=8;i0;i
10、-)DS1302_IO=ACC0;/相当于汇编中的 RRCDS1302_CLK=1;DS1302_CLK=0;ACC=ACC 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
11、:要写的数据DS1302_RST=0;DS1302_CLK=0;DS1302_RST=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|0 x01);/地址,命令ucData=DS13
12、02OutputByte();/读1Byte 数据DS1302_CLK=1;DS1302_RST=0;return(ucData);void DS1302_GetTime(SYSTEMTIME*Time)/获取时钟芯片的时钟数据到自定义的结构型数组unsigned char ReadValue;ReadValue=Read1302(DS1302_SECOND);Time-Second=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=Read1302(DS1302_MINUTE);Time-Minute=(ReadValue&0 x70)4)
13、*10+(ReadValue&0 x0F);ReadValue=Read1302(DS1302_HOUR);Time-Hour=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=Read1302(DS1302_DAY);Time-Day=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=Read1302(DS1302_WEEK);Time-Week=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=Read1302(DS1302_MONTH
14、);Time-Month=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=Read1302(DS1302_YEAR);Time-Year=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);void DateToStr(SYSTEMTIME*Time)/将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateStringif(hide_year2)/这里的 if,else 语句都是判断位闪烁,2就不显示,输出字符串为 2007/07/22Time-DateString0=2;Time-DateStri
15、ng1=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-DateString5=;Time-DateString6=;Time-DateString7=/;if
16、(hide_dayDateString8=Time-Day/10+0;Time-DateString9=Time-Day%10+0;elseTime-DateString8=;Time-DateString9=;if(hide_weekWeek%10+0;/星期的数据另外放到 week_value数组里,跟年,月,日的分开存放,因为等一下要在最后显示elseweek_value0=;week_value1=0;Time-DateString10=0;/字符串末尾加 0,判断结束字符void TimeToStr(SYSTEMTIME*Time)/将时,分,秒数据转换成液晶显示字符放到数组 Tim
17、eString;if(hide_hourTimeString0=Time-Hour/10+0;Time-TimeString1=Time-Hour%10+0;elseTime-TimeString0=;Time-TimeString1=;Time-TimeString2=:;if(hide_minTimeString3=Time-Minute/10+0;Time-TimeString4=Time-Minute%10+0;elseTime-TimeString3=;Time-TimeString4=;Time-TimeString5=:;if(hide_secTimeString6=Time-S
18、econd/10+0;Time-TimeString7=Time-Second%10+0;elseTime-TimeString6=;Time-TimeString7=;Time-DateString8=0;void Initial_DS1302(void)/时钟芯片初始化unsigned char Second=Read1302(DS1302_SECOND);if(Second&0 x80)/判断时钟芯片是否关闭Write1302(0 x8e,0 x00);/写入允许Write1302(0 x8c,0 x07);/以下写入初始化时间 日期:07/07/25.星期:3.时间:23:59:55W
19、rite1302(0 x88,0 x07);Write1302(0 x86,0 x25);Write1302(0 x8a,0 x07);Write1302(0 x84,0 x23);Write1302(0 x82,0 x59);Write1302(0 x80,0 x55);Write1302(0 x8e,0 x80);/禁止写入/*ds18b20子程序*/*ds18b20延迟子函数(晶振12MHz)*/void delay_18B20(unsigned int i)while(i-);/*ds18b20初始化函数*/void Init_DS18B20(void)unsigned char x=
20、0;DQ=1;/DQ 复位delay_18B20(8);/稍做延时DQ=0;/单片机将 DQ 拉低delay_18B20(80);/精确延时 大于 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|=0 x80;delay_18B20(4);re
21、turn(dat);/*ds18b20写一个字节*/void WriteOneChar(uchar dat)unsigned char i=0;for(i=8;i0;i-)DQ=0;DQ=dat&0 x01;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(0 xCC);/跳过读序号列号的操作WriteOneChar(0 x44);/启动温度转换delay_
22、18B20(100);/this message is wery importantInit_DS18B20();WriteOneChar(0 xCC);/跳过读序号列号的操作WriteOneChar(0 xBE);/读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(100);a=ReadOneChar();/读取温度值低位b=ReadOneChar();/读取温度值高位temp_value=b4;void temp_to_str()/温度数据转换成液晶字符显示TempBuffer0=temp_value/10+0;/十位TempBuffer1=temp_value%1
23、0+0;/个位TempBuffer2=0 xdf;/温度符号TempBuffer3=C;TempBuffer4=0;void Delay1ms(unsigned int count)unsigned int i,j;for(i=0;icount;i+)for(j=0;j0;delay-)for(i=0;i0 x59)/超过59秒,清零temp=0;break;case 2:temp=Read1302(DS1302_MINUTE);/读取分数temp=temp+1;/分数加1up_flag=1;if(temp0 x59)/超过59分,清零temp=0;break;case 3:temp=Read
24、1302(DS1302_HOUR);/读取小时数temp=temp+1;/小时数加1up_flag=1;if(temp0 x23)/超过23小时,清零temp=0;break;case 4:temp=Read1302(DS1302_WEEK);/读取星期数temp=temp+1;/星期数加1up_flag=1;if(temp0 x7)temp=1;break;case 5:temp=Read1302(DS1302_DAY);/读取日数temp=temp+1;/日数加1up_flag=1;if(temp0 x31)temp=1;break;case 6:temp=Read1302(DS1302_
25、MONTH);/读取月数temp=temp+1;/月数加1up_flag=1;if(temp0 x12)temp=1;break;case 7:temp=Read1302(DS1302_YEAR);/读取年数temp=temp+1;/年数加1up_flag=1;if(temp0 x85)temp=0;break;default:break;while(Up=0);while(wireless_2=1);/void Downkey()/降序按键Down=1;if(Down=0|wireless_3=1)mdelay(8);switch(count)case 1:temp=Read1302(DS1
26、302_SECOND);/读取秒数temp=temp-1;/秒数减1down_flag=1;/数据调整后更新标志if(temp=0 x7f)/小于0秒,返回59秒temp=0 x59;break;case 2:temp=Read1302(DS1302_MINUTE);/读取分数temp=temp-1;/分数减1down_flag=1;if(temp=-1)temp=0 x59;/小于0秒,返回59秒break;case 3:temp=Read1302(DS1302_HOUR);/读取小时数temp=temp-1;/小时数减1down_flag=1;if(temp=-1)temp=0 x23;b
27、reak;case 4:temp=Read1302(DS1302_WEEK);/读取星期数temp=temp-1;/星期数减1down_flag=1;if(temp=0)temp=0 x7;break;case 5:temp=Read1302(DS1302_DAY);/读取日数temp=temp-1;/日数减1down_flag=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=Rea
28、d1302(DS1302_YEAR);/读取年数temp=temp-1;/年数减1down_flag=1;if(temp=-1)temp=0 x85;break;default:break;while(Down=0);while(wireless_3=1);void Setkey()/模式选择按键Set=1;if(Set=0|wireless_4=1)mdelay(8);count=count+1;/Setkey 按一次,count 就加1done=1;/进入调整模式while(Set=0);while(wireless_4=1);void keydone()/按键功能执行uchar Seco
29、nd;if(flag=0)/关闭时钟,停止计时 Write1302(0 x8e,0 x00);/写入允许temp=Read1302(0 x80);Write1302(0 x80,temp|0 x80);Write1302(0 x8e,0 x80);/禁止写入flag=1;Setkey();/扫描模式切换按键switch(count)case 1:do/count=1,调整秒outkey();/扫描跳出按钮Upkey();/扫描加按钮Downkey();/扫描减按钮if(up_flag=1|down_flag=1)/数据更新,重新写入新的数据Write1302(0 x8e,0 x00);/写入允
30、许Write1302(0 x80,temp|0 x80);/写入新的秒数Write1302(0 x8e,0 x80);/禁止写入up_flag=0;down_flag=0;hide_sec+;/位闪计数if(hide_sec3)hide_sec=0;show_time();/液晶显示数据while(count=2);break;case 2:do/count=2,调整分hide_sec=0;outkey();Upkey();Downkey();if(temp0 x60)temp=0;if(up_flag=1|down_flag=1)Write1302(0 x8e,0 x00);/写入允许Wri
31、te1302(0 x82,temp);/写入新的分数Write1302(0 x8e,0 x80);/禁止写入up_flag=0;down_flag=0;hide_min+;if(hide_min3)hide_min=0;show_time();while(count=3);break;case 3:do/count=3,调整小时hide_min=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0 x8e,0 x00);/写入允许Write1302(0 x84,temp);/写入新的小时数Write1302(0 x8
32、e,0 x80);/禁止写入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,调整星期hide_hour=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0 x8e,0 x00);/写入允许Write1302(0 x8a,temp);/写入新的星期数Write1302(0 x8e,0 x80);/禁止写入up_flag=0;down_flag=0;
33、hide_week+;if(hide_week3)hide_week=0;show_time();while(count=5);break;case 5:do/count=5,调整日hide_week=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0 x8e,0 x00);/写入允许Write1302(0 x86,temp);/写入新的日数Write1302(0 x8e,0 x80);/禁止写入up_flag=0;down_flag=0;hide_day+;if(hide_day3)hide_day=0;show
34、_time();while(count=6);break;case 6:do/count=6,调整月hide_day=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0 x8e,0 x00);/写入允许Write1302(0 x88,temp);/写入新的月数Write1302(0 x8e,0 x80);/禁止写入up_flag=0;down_flag=0;hide_month+;if(hide_month3)hide_month=0;show_time();while(count=7);break;case 7:
35、do/count=7,调整年hide_month=0;outkey();Upkey();Downkey();if(up_flag=1|down_flag=1)Write1302(0 x8e,0 x00);/写入允许Write1302(0 x8c,temp);/写入新的年数Write1302(0 x8e,0 x80);/禁止写入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,跳出调整模式,返回
36、默认显示状态Second=Read1302(DS1302_SECOND);Write1302(0 x8e,0 x00);/写入允许Write1302(0 x80,Second&0 x7f);Write1302(0 x8E,0 x80);/禁止写入done=0;break;/count=7,开启中断,标志位置0并退出default:break;void show_time()/液晶显示程序DS1302_GetTime(&CurrentTime);/获取时钟芯片的时间数据TimeToStr(&CurrentTime);/时间数据转换液晶字符DateToStr(&CurrentTime);/日期数据
37、转换液晶字符ReadTemp();/开启温度采集程序temp_to_str();/温度数据转换成液晶字符GotoXY(12,1);/液晶字符显示位置Print(TempBuffer);/显示温度GotoXY(0,1);Print(CurrentTime.TimeString);/显示时间GotoXY(0,0);Print(CurrentTime.DateString);/显示日期GotoXY(15,0);Print(week_value);/显示星期GotoXY(11,0);Print(Week);/在液晶上显示 字母 weekDelay1ms(400);/扫描延时main()flag=1;/时钟停止标志LCD_Initial();/液晶初始化Init_DS18B20();/DS18B20初始化Initial_DS1302();/时钟芯片初始化up_flag=0;down_flag=0;done=0;/进入默认液晶显示wireless_1=0;wireless_2=0;wireless_3=0;wireless_4=0;while(1)while(done=1)keydone();/进入调整模式while(done=0)show_time();/液晶显示数据flag=0;Setkey();/扫描各功能键
限制150内