1、52+ds1302+LCD1602+DS18B20万年历/* 能实现年月日、时分秒、星期的显示及温度的采集,其 * 中设置了三个按钮用于修改时间 */#include #include intrins.h#define uchar unsigned char#define uint unsigned intuchar code nyr=20 - - ;uchar code hms= : : . ;uchar code set1302=0x00,0x00,0x12,0x09,0x08,0x02,0x12;uchar nian,yue,ri,shi,fen,miao,week,s1num=0,fl
2、ag=0;int temper;sbit DQ = P37; sbit ds1302_rst = P25;sbit ds1302_io = P27;sbit ds1302_sclk= P26;sbit lcd1602_rs = P20; sbit lcd1602_rw = P21; sbit lcd1602_e = P22;sbit s1=P30;sbit s2=P31;sbit s3=P32; /LCD延时void delay(uchar z) uchar x,y; for(x=z;z0;z-) for(y=110;y0;y-);/温度延时void delay2(uint temp) uin
3、t i,j; for(i=0;itemp;i+) for(j=0;j1;j+);/*DS1302*/DS1302写操作命令void write_byte(uchar dat) uchar i; for(i=0;i1; ds1302_sclk=1; /向DS1302的某个地址写入数据void ds1302_write(uchar add,uchar date) ds1302_rst=0; ds1302_sclk=0; ds1302_rst=1; write_byte(add); write_byte(date); ds1302_sclk=1; ds1302_rst=0;/读取DS1302的某地址
4、的数据uchar ds1302_read(uchar add) uchar i,value; ds1302_rst=0; _nop_(); ds1302_sclk=0; _nop_(); ds1302_rst=1; _nop_(); write_byte(add); for(i=0;i1; ds1302_sclk=0; if(ds1302_io) value=value|0x80; ds1302_sclk=1; ds1302_rst=0; _nop_(); ds1302_sclk=0; _nop_(); ds1302_sclk=1; ds1302_io=1; return value; /初始
5、化ds1302的时间void write_set1302() uchar i ; uchar addr=0x80; ds1302_write(0x8e,0x00); /控制命令WP=0,写操作 for(i=0;i7;i+) ds1302_write(addr,set1302i); /写入数据 addr+=2; ds1302_write(0x8e,0x80);/ 控制命令 WP=1 , 写保护/DS1302的初始化void ds1302_init() ds1302_rst=0; ds1302_sclk=1; ds1302_write(0x8e,0x80); /写保护/*LCD1602*/LCD1
6、602写命令函数void lcd_write_com(uchar com) lcd1602_rw=0; _nop_(); lcd1602_rs=0; _nop_(); P0=com; _nop_(); lcd1602_e=1; _nop_(); lcd1602_e=0; _nop_(); lcd1602_rw=1; delay(5); /LCD1602写数据函数void lcd_write_date(uchar date) lcd1602_rw=0; _nop_(); lcd1602_rs=1; _nop_(); lcd1602_e=1; _nop_(); P0=date; _nop_();
7、lcd1602_e=0; _nop_(); lcd1602_rw=1; delay(5);/设定LCD显示位置void lcd_pos(uchar y,uchar x) uchar a; if(y=1) a=0x80+x; /第一行位码 if(y=2) a=0xc0+x; /第二行位码 lcd_write_com(a); /写入数据/LCD固定字符的显示void lcd1602_set()uchar i;lcd_pos(1,0); for(i=0;i8;i+) lcd_write_date(nyri); delay(2); lcd_pos(2,0); for(i=0;i14;i+) lcd_w
8、rite_date(hmsi); delay(2); lcd_pos(2,14); for(i=14;i16;i+) lcd_write_date(0xdf); lcd_write_date(C); delay(5); /LCD1602初始化void lcd1602_init() lcd_write_com(0x38); /8位数据,双列,5*7字形 lcd_write_com(0x0c); /开启显示屏,显示光标,光标不闪烁 lcd_write_com(0x06); /写一个数据后,显示位置(光标)右移一位,显示屏不移动 lcd_write_com(0x01); /清屏/*DS18B20*/
9、DS18B20初始化uchar reset() uchar presence; DQ=0; delay2(29); DQ=1; delay2(3); presence=DQ; delay2(25); return(presence);/读DS18B20一位数据uchar read_bit() uchar i; DQ=0; DQ=1; for(i=0;i3;i+); return(DQ);/写DS18B20一位数据void write_bit(uchar date) DQ=0; if(date=1) DQ=1; delay2(5); DQ=1;/读DS18B20一字节数据uchar read_b
10、yte1() uchar date=0; uchar i; for(i=0;i8;i+) if(read_bit() date|=0x01i; delay2(1); return(date);/写DS18B20一字节数据void write_byte1(uchar date) uchar i,j; for(i=0;ii)&0x01); write_bit(j); delay2(1); /读取温度int read_temp() uchar templ,temph; int temp; reset(); write_byte1(0xcc); write_byte1(0x44); delay2(10
11、000); reset(); write_byte1(0xcc); write_byte1(0xbe); templ=read_byte1(); temph=read_byte1(); temp=temph; temp4)*10+(bcd&0x0f); return(c); /十进制转化成BCDuchar DectoBCD(uchar dec) uchar i; i=dec/10; dec=dec%10; dec=i*16+dec; return(dec);/显示星期的子函数void write_week(uchar we) switch(we) case 1: lcd_write_date(
12、M); lcd_write_date(o); lcd_write_date(n); break; case 2: lcd_write_date(T); lcd_write_date(u); lcd_write_date(e); break; case 3: lcd_write_date(W); lcd_write_date(e); lcd_write_date(d); break; case 4: lcd_write_date(T); lcd_write_date(h); lcd_write_date(u); break; case 5: lcd_write_date(F); lcd_writ
13、e_date(r); lcd_write_date(t); break; case 6: lcd_write_date(S); lcd_write_date(a); lcd_write_date(t); break; case 7: lcd_write_date(S); lcd_write_date(u); lcd_write_date(n); break; /*按键设置*/void keyscan() if(s1=0) delay(5); if(s1=0) flag=1; s1num+; while(!s1); /检测按键是否放开 if(s1num=1) lcd_pos(1,3); lcd_
14、write_com(0x0f); if(s1num=2) lcd_pos(1,6); if(s1num=3) lcd_pos(1,9); if(s1num=4) lcd_pos(1,14); if(s1num=5) lcd_pos(2,1); if(s1num=6) lcd_pos(2,4); if(s1num=7) lcd_pos(2,7); if(s1num=8) s1num=0; lcd_write_com(0x0c); flag=0; ds1302_write(0x8e,0x00); /写允许 ds1302_write(0x80,DectoBCD(miao); /初始秒 ds1302_
15、write(0x82,DectoBCD(fen); /初始分 ds1302_write(0x84,DectoBCD(shi); /初始时 ds1302_write(0x86,DectoBCD(ri); /初始日 ds1302_write(0x88,DectoBCD(yue); /初始月 ds1302_write(0x8a,DectoBCD(week); /初始周 ds1302_write(0x8c,DectoBCD(nian); /初始年 ds1302_write(0x8e,0x80); /写保护 if(s1num!=0) if(s2=0) delay(5); if(s2=0) while(!
16、s2); if(s1num=7) miao+; if(miao=60) miao=0; lcd_pos(2,6); write_display(miao); lcd_pos(2,7); if(s1num=6) fen+; if(fen=60) fen=0; lcd_pos(2,3); write_display(fen); lcd_pos(2,4); if(s1num=5) shi+; if(shi=24) shi=0; lcd_pos(2,0); write_display(shi); lcd_pos(2,1); if(s1num=4) week+; if(week=8) week=1; l
17、cd_pos(1,12); write_week(week); lcd_pos(1,14); if(s1num=3) ri+; if(ri=32) ri=0; lcd_pos(1,8); write_display(ri); lcd_pos(1,9); if(s1num=2) yue+; if(yue=13) yue=1; lcd_pos(1,5); write_display(yue); lcd_pos(1,6); if(s1num=1) nian+; if(nian=100) nian=0; lcd_pos(1,2); write_display(nian); lcd_pos(1,3);
18、if(s1num!=0) if(s3=0) delay(5); if(s3=0) while(!s3); if(s1num=7) miao-; if(miao=-1) miao=59; lcd_pos(2,6); write_display(miao); lcd_pos(2,7); if(s1num=6) fen-; if(fen=-1) fen=59; lcd_pos(2,3); write_display(fen); lcd_pos(2,4); if(s1num=5) shi-; if(shi=-1) shi=23; lcd_pos(2,0); write_display(shi); lc
19、d_pos(2,1); if(s1num=4) week-; if(week=0) week=7; lcd_pos(1,12); write_week(week); lcd_pos(1,14); if(s1num=3) ri-; if(ri=0) ri=31; lcd_pos(1,8); write_display(ri); lcd_pos(1,9); if(s1num=2) yue-; if(yue=0) yue=12; lcd_pos(1,5); write_display(yue); lcd_pos(1,6); if(s1num=1) nian-; if(nian=-1) nian=99
20、; lcd_pos(1,2); write_display(nian); lcd_pos(1,3); /液晶显示内容void LCD1602display() if(flag=0) /判断无按键按下 /读取秒分时,日月年,星 miao=BCDtoDec(ds1302_read(0x81); fen=BCDtoDec(ds1302_read(0x83); shi=BCDtoDec(ds1302_read(0x85); ri=BCDtoDec(ds1302_read(0x87); yue=BCDtoDec(ds1302_read(0x89); nian=BCDtoDec(ds1302_read(0
21、x8d); week=BCDtoDec(ds1302_read(0x8b); /液晶显示秒分时,日月年,星 lcd_pos(2,6); write_display(miao); lcd_pos(2,3); write_display(fen); lcd_pos(2,0); write_display(shi); lcd_pos(1,8); write_display(ri); lcd_pos(1,5); write_display(yue); lcd_pos(1,2); write_display(nian); lcd_pos(1,12); write_week(week); /显示温度 lc
22、d_pos(2,10); temper=read_temp(); if(temper0) lcd_pos(2,9); lcd_write_date(-); temper=0-temper; else lcd_pos(2,9); lcd_write_date( ); lcd_pos(2,10);lcd_write_date(temper/100+0x30); lcd_pos(2,11);lcd_write_date(temper%100/10+0x30); lcd_pos(2,13);lcd_write_date(temper%100%10+0x30); /*主函数*/void main() lcd1602_init(); /LCD1602初始化 lcd1602_set(); /LCD固定字符的显示 ds1302_init(); /DS1302的初始化 / write_set1302(); /初始化ds1302的时间,不初始化就是系统的时间 while(1) keyscan(); LCD1602display();
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1