温度传感器DS18B20ATC89S51单片机LCD1602液晶显示测温可调时钟系统C程序完整版文档格式.docx
《温度传感器DS18B20ATC89S51单片机LCD1602液晶显示测温可调时钟系统C程序完整版文档格式.docx》由会员分享,可在线阅读,更多相关《温度传感器DS18B20ATC89S51单片机LCD1602液晶显示测温可调时钟系统C程序完整版文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
1>
ROM
只读存储器,用于存放DS18B20ID编码,其前8位是单线系列编码(DS18B20的编码是19H),后面48位是芯片唯一的序列号,最后8位是以上56的位的CRC码(冗余校验)。
数据在出产时设置不由用户更改。
DS18B20共64位ROM。
2>
RAM
数据暂存器,用于内部计算和数据存取,数据在掉电后丢失,DS18B20共9个字节RAM,每个字节为8位。
第1、2个字节是温度转换后的数据值信息,第3、4个字节是用户EEPROM(常用于温度报警值储存)的镜像。
在上电复位时其值将被刷新。
第5个字节则是用户第3个EEPROM的镜像。
第6、7、8个字节为计数寄存器,是为了让用户得到更高的温度分辨率而设计的,同样也是内部温度转换、计算的暂存单元。
第9个字节为前8个字节的CRC码。
EEPROM
非易失性记忆体,用于存放长期需要保存的数据,上下限温度报警值和校验数据,DS18B20共3位EEPROM,并在RAM都存在镜像,以方便用户操作。
C程序(独家专售):
#include<
reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDIOP2
sbitDQ=P3^7;
//ds18b20与单片机连接口
sbitrs=P3^0;
sbitrd=P3^1;
sbitlcden=P3^2;
sbits1=P1^3;
sbits2=P1^4;
sbits3=P1^5;
uchardatadisdata[5];
uinttvalue;
//温度值
uchartflag;
ucharcount,s1num;
charmiao,shi,fen,day=18,mon=11,week=0;
uintyear=2010;
ucharcodetable[]="
2010-11-18THU"
;
ucharcodetable1[]="
00:
00000.0C"
ucharcodetable2[]="
THUFRISATSUNMONTUEWES"
voiddelay(uintz)
{
uintx,y;
for(x=z;
x>
0;
x--)
for(y=110;
y>
y--);
}
voidwrite_com(ucharcom)
rs=0;
rd=0;
lcden=0;
P2=com;
delay(5);
lcden=1;
voidwrite_date(uchardate)
rs=1;
P2=date;
voidinit()
ucharnum;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;
num<
15;
num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
16;
write_date(table1[num]);
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
voidwrite_sfm(ucharadd,uchardate)
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
voidwrite_md(ucharadd,uchardate)
write_com(0x80+add);
voidwrite_year(ucharadd,uintdate)
ucharqian,bai,shi,ge;
qian=date/1000;
bai=date%1000/100;
shi=date%1000%100/10;
ge=date%1000%100%10;
write_date(0x30+qian);
write_date(0x30+bai);
voidwrite_week(ucharadd,uchardate)
3;
{
write_date(table2[date]);
date++;
voiddisplay()
{
mon++;
if(mon==13)
mon=1;
year++;
write_year(1,year);
}
write_md(6,mon);
voidkeyscan()
if(s1==0)
delay(5);
if(s1==0)
{
s1num++;
//全局变量
while(!
s1);
if(s1num==1)//调时间时//
{
TR0=0;
//定时器停止//
write_com(0x80+4);
write_com(0x0f);
//光标闪射//
}
if(s1num==2)//调时间时//
{
write_com(0x80+7);
if(s1num==3)//调时间时//
write_com(0x80+10);
if(s1num==4)//调时间时//
write_com(0x80+14);
if(s1num==5)//调时间时//
write_com(0x80+0x40+1);
if(s1num==6)//调时间分//
write_com(0x80+0x40+4);
if(s1num==7)//调时间秒
{
write_com(0x80+0x40+7);
//光标位置//
if(s1num==8)
s1num=0;
//s1num清零//
write_com(0x0c);
//光标不闪烁//
TR0=1;
//定时器又开始//
if(s1num!
=0)
if(s2==0)
delay(5);
if(s2==0)
{
while(!
s2);
if(s1num==7)
{
miao++;
if(miao==60)
miao=0;
write_sfm(6,miao);
write_com(0x80+0x40+7);
}
if(s1num==6)
fen++;
if(fen==60)
fen=0;
write_sfm(3,fen);
write_com(0x80+0x40+4);
if(s1num==5)
shi++;
if(shi==24)
shi=0;
write_sfm(0,shi);
write_com(0x80+0x40+1);
if(s1num==3)
week=week+3;
if(week==21)
week=0;
day++;
if(((mon==1)||(mon==3)||(mon==5)||(mon==7)||(mon==8)||(mon==10)||(mon==12))&
&
(day==32))
{day=1;
}
if(((mon==4)||(mon==6)||(mon==9)||(mon==11))&
(day==31))
if(((mon==2)&
(((year%4==0)&
(year%100!
=0))||(year%400==0)))&
(day==30))
{day=1;
(!
((year%4==0)&
(day==29))
write_md(9,day);
write_week(12,week);
write_com(0x80+10);
if(s1num==2)
mon++;
if(mon==13)
mon=1;
write_md(6,mon);
write_com(0x80+7);
if(s1num==1)
year++;
write_year(1,year);
write_com(0x80+4);
if(s1num==4)
week+=3;
write_week(12,week);
write_com(0x80+14);
}
if(s3==0)
if(s3==0)
s3);
miao--;
if(miao==-1)
miao=59;
fen--;
if(fen==-1)
fen=59;
shi--;
if(shi==-1)
shi=23;
week=week-3;
if(week==-3)
day--;
(day==0))
{day=31;
{day=30;
{day=29;
{day=28;
mon--;
if(mon==0)
mon=12;
year--;
week-=3;
week=18;
voiddelay_18B20(unsignedinti)//延时1微秒
while(i--);
voidds1820rst()/*ds1820复位*/
{unsignedcharx=0;
DQ=1;
//DQ复位
delay_18B20(4);
//延时
DQ=0;
//DQ拉低
delay_18B20(100);
//精确延时大于480us
//拉高
delay_18B20(40);
}
uchards1820rd()/*读数据*/
{unsignedchari=0;
unsignedchardat=0;
for(i=8;
i>
i--)
{DQ=0;
//给脉冲信号
dat>
>
=1;
DQ=1;
if(DQ)
dat|=0x80;
delay_18B20(10);
return(dat);
voidds1820wr(ucharwdata)/*写数据*/
{unsignedchari=0;
i>
i--)
DQ=wdata&
0x01;
delay_18B20(10);
wdata>
read_temp()/*读取温度值并转换*/
{uchara,b;
ds1820rst();
ds1820wr(0xcc);
//*跳过读序列号*/
ds1820wr(0x44);
//*启动温度转换*/
//*跳过读序列号*/
ds1820wr(0xbe);
//*读取温度*/
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<
<
=8;
tvalue=tvalue|a;
if(tvalue<
0x0fff)
tflag=0;
else
{tvalue=~tvalue+1;
tflag=1;
tvalue=tvalue*(0.625);
//温度值扩大10倍,精确到1位小数
return(tvalue);
voidds1820disp()//温度值显示
{ucharflagdat;
disdata[0]=tvalue/1000+0x30;
//百位数
disdata[1]=tvalue%1000/100+0x30;
//十位数
disdata[2]=tvalue%100/10+0x30;
//个位数
disdata[3]=tvalue%10+0x30;
//小数位
if(tflag==0)
flagdat=0x20;
//正温度不显示符号
flagdat=0x2d;
//负温度显示负号:
-
if(disdata[0]==0x30)
{disdata[0]=0x20;
//如果百位为0,不显示
if(disdata[1]==0x30)
{disdata[1]=0x20;
//如果百位为0,十位为0也不显示
write_com(0xc8);
write_date(flagdat);
//显示符号位
write_com(0xc9);
write_date(disdata[0]);
//显示百位
write_com(0xca);
write_date(disdata[1]);
//显示十位
write_com(0xcb);
write_date(disdata[2]);
//显示个位
write_com(0xcc);
write_date(0x2e);
//显示小数点
write_com(0xcd);
write_date(disdata[3]);
//显示小数位
write_com(0xcf);
write_date('
C'
);
voidmain()
init();
read_temp();
//读取温度
ds1820disp();
//显示
while
(1)
keyscan();
voidtimer0()interrupt1
count++;
if(count==18)
count=0;
miao++;
if(miao==60)
miao=0;
fen++;
if(fen==60)
fen=0;
shi++;
if(shi==24)
shi=0;
display();
write_sfm(0,shi);
write_sf