《DS1302时钟+DS18B20用LCD1602显示系统很简单.pdf》由会员分享,可在线阅读,更多相关《DS1302时钟+DS18B20用LCD1602显示系统很简单.pdf(22页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、.IDS1302DS1302 时钟时钟+DS18B20+DS18B20 用用 LCD1602LCD1602 显示(系统很简单)显示(系统很简单)看仔细点啊 貌似很多这样的图但可不一样喔 最小系统是用 AT89s52 搭建的!记得回去自己用 protues和 Keil 仿真一下,这样有利于进一步了解!故未将仿真好的代码上传,如果真的需要的话可以和我联系!程序代码:#include#include/#include LCD1602.h/#include DS1302.h#define uint unsigned int#define uchar unsigned charsbit DS1302_C
2、LK=P17;/实时时钟时钟线引脚sbit DS1302_IO=P16;/实时时钟数据线引脚.r.Isbit DS1302_RST=P15;/实时时钟复位线引脚sbit wireless_1=P30;sbit wireless_2=P31;sbit wireless_3=P32;sbit wireless_4=P33;sbit ACC0=ACC0;sbit ACC7=ACC7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;/秒,分,时到日,月,年位闪的计数sbit Set=P20;/模式切换键s
3、bit Up=P21;/加法按钮sbit Down=P22;/减法按钮sbit out=P23;/立刻跳出调整模式按钮sbit DQ=P10;/温度传送数据 IO 口char done,count,temp,flag,up_flag,down_flag;uchar temp_value;/温度值uchar TempBuffer5,week_value2;void show_time();/液晶显示程序/*1602 液晶显示部分子程序*/Port Definitions*sbit LcdRs =P25;sbit LcdRw =P26;sbit LcdEn =P27;sfr DBPort =0 x
4、80;/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 写入命令或数据*.r.I#define LCD_COMMAND 0/Command#define LCD_DATA 1/Data#define LCD_CLEAR_SCREEN 0 x01/清屏#define LCD_HOMING 0 x02/光标返回原点void LCD_Write(bit style
5、,unsigned char input)LcdEn=0;LcdRs=style;LcdRw=0;_nop_();DBPort=input;_nop_();/注意顺序 LcdEn=1;_nop_();/注意顺序 LcdEn=0;_nop_();LCD_Wait();/设置显示模式*#define LCD_SHOW 0 x04/显示开#define LCD_HIDE 0 x00/显示关#define LCD_CURSOR 0 x02 /显示光标#define LCD_NO_CURSOR 0 x00/无光标#define LCD_FLASH 0 x01/光标闪动#define LCD_NO_FLA
6、SH 0 x00/光标不闪动void LCD_SetDisplay(unsigned char DisplayMode)LCD_Write(LCD_COMMAND,0 x08|DisplayMode);/设置输入模式*#define LCD_AC_UP 0 x02#define LCD_AC_DOWN 0 x00/default#define LCD_MOVE 0 x01/画面可平移#define LCD_NO_MOVE 0 x00/defaultvoid LCD_SetInput(unsigned char InputMode)LCD_Write(LCD_COMMAND,0 x04|Inpu
7、tMode);.r.I/初始化 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_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);/清屏 LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);/AC 递增,画面不动/液晶字符输入的位置*void GotoXY(unsigned ch
8、ar 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);str+;/*DS1302 时钟部分子程序*/typedef struct _SYSTEMTIME_ unsigned char Second;unsigned char Minute;unsigned char Hour;.r.I
9、unsigned char Week;unsigned char Day;unsigned char Month;unsigned char Year;unsigned char DateString11;unsigned char TimeString9;SYSTEMTIME;/定义的时间类型SYSTEMTIME CurrentTime;#define AM(X)X#define PM(X)(X+12)/转成 24 小时制#define DS1302_SECOND 0 x80/时钟芯片的寄存器位置,存放时间#define DS1302_MINUTE 0 x82#define DS1302_H
10、OUR 0 x84#define DS1302_WEEK 0 x8A#define DS1302_DAY 0 x86#define DS1302_MONTH 0 x88#define DS1302_YEAR 0 x8Cvoid DS1302InputByte(unsigned char d)/实时时钟写入一字节(部函数)unsigned char i;ACC=d;for(i=8;i0;i-)DS1302_IO=ACC0;/相当于汇编中的 RRCDS1302_CLK=1;DS1302_CLK=0;ACC=ACC 1;unsigned char DS1302OutputByte(void)/实时时
11、钟读取一字节(部函数)unsigned char i;for(i=8;i0;i-)ACC=ACC 1;/相当于汇编中的 RRCACC7=DS1302_IO;.r.IDS1302_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);/写 1B
12、yte 数据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=DS1302OutputByte();/读 1Byte 数据DS1302_CLK=1;DS1302_RST=0;return(ucData);void DS1302_GetTime(SYSTEMTIME*Ti
13、me)/获取时钟芯片的时钟数据到自定义的结构型数组 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)*10+(ReadValue&0 x0F);ReadValue=Read1302(DS1302_HOUR);.r.I Time-Hour=(ReadValue&0 x70)4)*10+(ReadV
14、alue&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);Time-Month=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=Read1302(DS1302_YEAR);Time-Ye
15、ar=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);void DateToStr(SYSTEMTIME*Time)/将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里 DateStringif(hide_year2)/这里的if,else 语句都是判断位闪烁,2 就不显示,输出字符串为 2007/07/22Time-DateString0=2;Time-DateString1=0;Time-DateString2=Time-Year/10+0;Time-DateString3=Time-Year%10+0;elseTime-DateString0=;
16、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=;.r.I Time-DateString7=/;if(hide_dayDateString8=Time-Day/10+0;Time-DateString9=Time-Day%10+0;elseTime-DateString8=
17、;Time-DateString9=;if(hide_weekWeek%10+0;/星期的数据另外放到 week_value数组里,跟年,月,日的分开存放,因为等一下要在最后显示 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;elseTim
18、e-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-Second/10+0;Time-TimeString7=Time-Second%10+0;elseTime-TimeString6=;Time-TimeString7=;T
19、ime-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:55 Write1302(0 x88,0 x07);Write1302(0 x86,0 x25);Write1302(0 x8a,0 x07);Write1302(0 x8
20、4,0 x23);Write1302(0 x82,0 x59);Write1302(0 x80,0 x55);Write1302(0 x8e,0 x80);/禁止写入.r.I/*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);/精确延时 大于
21、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);.r.I return(dat);/*ds18b20 写一个字节*/void WriteOneChar(uchar dat)unsigned ch
22、ar 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_18B20(100);/this message is wery important Init_DS18B20();Writ
23、eOneChar(0 xCC);/跳过读序号列号的操作 WriteOneChar(0 xBE);/读取温度寄存器等(共可读 9 个寄存器)delay_18B20(100);a=ReadOneChar();/读取温度值低位 b=ReadOneChar();/读取温度值高位 temp_value=b4;void temp_to_str()/温度数据转换成液晶字符显示.r.前两个就是温度.ITempBuffer0=temp_value/10+0;/十位TempBuffer1=temp_value%10+0;/个位TempBuffer2=0 xdf;/温度符号TempBuffer3=C;TempBuf
24、fer4=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=Read1302(DS1302_HOUR);/读取小时数temp=temp+1;/小时数加 1up_
25、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:.r.Itemp=Read1302(DS1302_DAY);/读取日数temp=temp+1;/日数加 1up_flag=1;if(temp0 x31)temp=1;break;case 6:temp=Read1302(DS1302_MONTH);/读取月数temp=temp+1;/月数加 1up_flag
26、=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(DS1302_SECOND);/读取秒数.r.Itemp=temp-1;/
27、秒数减 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;break;case 4:temp=Re
28、ad1302(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).r.Itemp=12;break;case 7:temp=Read1302(DS1302
29、_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 Second;if(fla
30、g=0)/关闭时钟,停止计时 Write1302(0 x8e,0 x00);/写入允许temp=Read1302(0 x80);Write1302(0 x80,temp|0 x80);Write1302(0 x8e,0 x80);/禁止写入flag=1;.r.ISetkey();/扫描模式切换按键switch(count)case 1:do/count=1,调整秒outkey();/扫描跳出按钮Upkey();/扫描加按钮Downkey();/扫描减按钮if(up_flag=1|down_flag=1)/数据更新,重新写入新的数据Write1302(0 x8e,0 x00);/写入允许Writ
31、e1302(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);/写入允许Write130
32、2(0 x82,temp);/写入新的分数Write1302(0 x8e,0 x80);/禁止写入up_flag=0;down_flag=0;hide_min+;if(hide_min3).r.Ihide_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 x8e
33、,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;h
34、ide_week+;if(hide_week3).r.Ihide_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;s
35、how_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).r.Ihide_month=0;show_time();while(count=7);break;
36、case 7: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,跳出
37、调整模式,返回默认显示状态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);/时间数据转换液晶字符.r.IDateToStr(&Curre
38、ntTime);/日期数据转换液晶字符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;.r.I wireless_4=0;while(1)while(done=1)keydone();/进入调整模式 while(done=0)show_time();/液晶显示数据flag=0;Setkey();/扫描各功能键 .r.