新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > DS18B20匹配ROM地址單總線多點測溫(STC89C52)

DS18B20匹配ROM地址單總線多點測溫(STC89C52)

作者: 時間:2016-11-26 來源:網(wǎng)絡 收藏
DS18B20總線多點測溫,程序通過匹配64位ROM地址的方法,實現(xiàn)單總線兩點測溫并1602顯示。該程序要先知道DS18B20的64位ROM地址才可以,ROM地址的讀取方法可參考上一篇的介紹。

本文引用地址:http://m.butianyuan.cn/article/201611/321813.htm

程序代碼:

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitlcdrw=P1^1;//LCD1602讀/寫選擇H/L

sbitlcdrs=P1^0;//LCD1602數(shù)據(jù)/命令選擇H/L

sbitlcden=P2^5;//LCD1602使能

sbitds=P2^2;//溫度傳感器信號線

ucharcodetable[]="";

ucharcodetable1[]="LOADINGWENDU";

//uchardatafCode[8];

ucharcoderom1[]={0x28,0x3b,0x08,0x32,0x04,0x00,0x00,0xe4};//ds18b20ROM地址

ucharcoderom2[]={0x28,0xf8,0x19,0x0d,0x03,0x00,0x00,0x3b};//ds18b20rom地址

inttemp;//整型溫度數(shù)據(jù)

floatf_temp;//浮點型溫度數(shù)據(jù)

uchartflag;//溫度正負標志

//*****************LCD1602*******************************

voiddelay(uintz)//延時函數(shù)延時z毫秒

{

uintx,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

voidwrite_com(ucharcom)//lcd1602寫指令

{

lcdrs=0;

P0=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}//lcd1602寫數(shù)據(jù)

voidwrite_date(uchardate)

{

lcdrs=1;

P0=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

voidinit1602()//開機初始化LCD1602

{

uchari;

lcdrw=0;

lcden=0;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

write_com(0x80);

for(i=0;i<16;i++)

{

write_date(table1[i]);

delay(5);

}

write_com(0x80+0x41);

for(i=0;i<14;i++)

{

write_date(0x2d);

delay(100);

}

write_com(0x80);

for(i=0;i<16;i++)

{

write_date(table[i]);

delay(5);

}

write_com(0x80+0x40);

for(i=0;i<16;i++)

{

write_date(table[i]);

delay(5);

}

}

//*******************DS18B20****************************

voiddsreset()//DS18B20復位,初始化函數(shù)

{

uinti;

ds=0;

i=103;

while(i>0)

i--;

ds=1;

i=4;

while(i>0)

i--;

}

bittempreadbit()//讀一位數(shù)據(jù)函數(shù)

{

uinti;

bitdat;

ds=0;

i++;

ds=1;

i++;

i++;

dat=ds;

i=8;

while(i>0)

i--;

returndat;

}

uchartempread()//讀一字節(jié)數(shù)據(jù)函數(shù)

{

uchari,j,dat;

dat=0;

for(i=1;i<=8;i++)

{

j=tempreadbit();

dat=(j<<7)|(dat>>1);

}

returndat;

}

voidtempwrite(uchardat)//向DS18B20寫一字節(jié)數(shù)據(jù)函數(shù)

{

uinti;

ucharj;

bittestb;

for(j=1;j<=8;j++)

{

testb=dat&0x01;

dat=dat>>1;

if(testb)//寫1

{

ds=0;

i++;i++;

ds=1;

i=8;

while(i>0)

i--;

}

else//寫0

{

ds=0;

i=8;

while(i>0)

i--;

ds=1;

i++;i++;

}

}

}

voidmatchrom(uchara)//匹配ROM

{

charj;

tempwrite(0x55);//發(fā)送匹配ROM命令

if(a==1)

{

for(j=0;j<8;j++)

tempwrite(rom1[j]);//發(fā)送18B20的序列號,先發(fā)送低字節(jié)

}

if(a==2)

{

for(j=0;j<8;j++)

tempwrite(rom2[j]);//發(fā)送18B20的序列號,先發(fā)送低字節(jié)

}

}

uinttempchange(ucharz)//DS18B20開始獲取溫度并轉(zhuǎn)換

{

uchara,b;

dsreset();

delay(1);

//tempwrite(0xcc);//寫跳過讀ROM指令

//tempwrite(0xcc);

//dsreset();

if(z==1)

matchrom(1);//匹配rom1

if(z==2)

matchrom(2);//匹配rom2

tempwrite(0x44);//寫溫度轉(zhuǎn)換指令

delay(5);

dsreset();

delay(1);

//tempwrite(0xcc);//寫“跳過讀ROM”指令

//tempwrite(0xcc);

//dsreset();

if(z==1)

matchrom(1);//匹配rom1

if(z==2)

matchrom(2);//匹配rom2

tempwrite(0xbe);//寫“讀內(nèi)部RAM中9字節(jié)的溫度數(shù)據(jù)”指令

a=tempread();//讀高8位

b=tempread();//讀低8位

temp=b;

temp<<=8;

temp=temp|a;//兩個字節(jié)合為一個字節(jié)

if(temp<0x0fff)

tflag=0;//正值標識符

else

{

temp=~temp+1;

tflag=1;//負值標識符

}

f_temp=temp*0.0625;//溫度在寄存器中為12位,分辨路為0.0625

temp=f_temp*10+0.5;//乘以10表示小數(shù)點后面只取一位,加0.5是四舍五入

f_temp=f_temp+0.05;

returntemp;//temp是整型

}

voidwrite_wendu(ucharaddress,uchardate)//寫溫度1602顯示

{

write_com(address);

write_date(date);

}

voidinit_1602wendu()

{

write_wendu(0x80,N);

write_wendu(0x81,O);

write_wendu(0x82,.);

write_wendu(0x84,:);

write_wendu(0x89,.);

write_wendu(0x8b,0xdf);

write_wendu(0x8c,C);

write_wendu(0x80+0x40,N);

write_wendu(0x81+0x40,O);

write_wendu(0x82+0x40,.);

write_wendu(0x84+0x40,:);

write_wendu(0x89+0x40,.);

write_wendu(0x8b+0x40,0xdf);

write_wendu(0x8c+0x40,C);

}

voiddisplay_wendu(ucharz)//顯示函數(shù)

{

uintw1,w2,w3,w4,addr;

w1=temp/1000;//百位

w2=temp00/100;//十位

w3=temp0/10;//個位

w4=temp;//小數(shù)點位

if(z==1)

{

addr=0;

write_com(0x80+3);

write_date(0x30+1);

}

if(z==2)

{

addr=0x40;

write_com(0x80+0x40+3);

write_date(0x30+2);

}

if(tflag==0)

write_wendu(0x80+addr+5,0x20);//不顯示正號

else

write_wendu(0x80+addr+5,0x2d);//顯示負號

if(w1==0)

{

write_wendu(0x80+addr+6,0x20);//百位為0,不顯示

if((w1==0)&&(w2==0))

write_wendu(0x80+addr+7,0x20);//百位,十位都為0,不顯示

else

write_wendu(0x80+addr+7,0x30+w2);

write_wendu(0x80+addr+8,0x30+w3);

write_wendu(0x80+addr+10,0x30+w4);

}

else

{

write_wendu(0x80+addr+6,0x30+w1);

write_wendu(0x80+addr+7,0x30+w2);

write_wendu(0x80+addr+8,0x30+w3);

write_wendu(0x80+addr+10,0x30+w4);

}

}

//************************************************

voidmain()//主函數(shù)

{

init1602();//啟動屏幕初始化

while(1)

{

init_1602wendu();//顯示溫度屏幕初始化

tempchange(1);//獲取溫度并轉(zhuǎn)化

display_wendu(1);//顯示溫度

tempchange(2);

display_wendu(2);

}

}



評論


技術專區(qū)

關閉