?? digthermo.c
字號:
/*此程序?qū)崿F(xiàn)了ds18b20溫度傳感器的單線數(shù)據(jù)采集,并且通過LED顯示小數(shù)和整數(shù)部分*/
#include "DigThermo.h"
/* 延時t*11us */
void delay(uint t)
{
for(;t>0;t--);
}
/* 產(chǎn)生復(fù)位脈沖初始化DS18B20 */
void TxReset(void)
{ char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();//從高拉倒低
DQ=0;
delay(50); //550 us
DQ=1;
delay(6); //66 us
presence=DQ; //presence=0 復(fù)位成功,繼續(xù)下一步
}
delay(45); //延時500 us
presence=~DQ;
}
DQ=1; //拉高電平
}
/* 讀取數(shù)據(jù)的一個字節(jié) */
uchar RdByte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us
DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us
if(DQ)value|=0x80;
delay(6); //66 us
}
DQ=1;
return(value);
}
/* 寫數(shù)據(jù)的一個字節(jié) */
void WrByte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_(); //從高拉倒低
DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us
DQ=val&0x01; //最低位移出
delay(6); //66 us
val=val/2; //右移1位
}
DQ=1;
delay(1);
}
/*功能匹配*/
bit match_rom(uchar *rom)
{
uchar i;
TxReset();
WrByte(0x55);
for(i=8;i>0;i--)
{
WrByte(*(rom+i-1));
}
return 1;
}
/* 讀取溫度值 */
void RdTemp(uchar *serial)
{
TxReset(); // 產(chǎn)生復(fù)位脈沖,初始化DS18B20
delay(200); // 延時
WrByte(0xcc); // skip rom 命令
WrByte(0x44); // read scratchpad 命令
delay(1); // 延時
match_rom(serial); //匹配
WrByte(0xbe); // convert T 命令
tplsb = RdByte(); // 溫度值低位字節(jié)(其中低4位為二進制的“小數(shù)”部分)
tpmsb = RdByte(); // 高位值高位字節(jié)(其中高5位為符號位)
}
/*對采集到的數(shù)據(jù)進行處理*/
void DataChange()
{
uint tem;
uchar temp,flag;
uchar low,j;
if(tpmsb>7)
{
flag=1;
tem=tpmsb;
tem<<=8;
tem=tem|tplsb; // 兩字節(jié)合成一個整型變量。
tem=(tem^0xffff);//異或
tem=tem+1; //取反加1
tplsb=tem&0xff;
tpmsb=tem>>8;
}
temp=tpmsb<<4&0x70;
temp=temp|(tplsb>>4);
display[6]=temp/100; // 取百位數(shù)據(jù)暫存
display[5]=temp%100/10; // 取十位數(shù)據(jù)暫存
display[4]=temp%100%10;; // 取個位數(shù)據(jù)暫存
low=tplsb&0x0f;
switch(low) //處理小數(shù)部分,對于12位的分辨率,以0.625和對應(yīng)的數(shù)據(jù)相乘可以得出16種情況0000~1111
{
case 0:
display[3]=0;
break;
case 1:
display[3]=0;
display[2]=6;
display[1]=2;
display[0]=5;
break;
case 2:
display[3]=1;
display[2]=2;
display[1]=5;
break;
case 3:
display[3]=1;
display[2]=8;
display[1]=7;
display[0]=5;
break;
case 4:
display[3]=2;
display[2]=5;
break;
case 5:
display[3]=3;
display[2]=1;
display[1]=2;
display[0]=5;
break;
case 6:
display[3]=3;
display[2]=7;
display[1]=5;
break;
case 7:
display[3]=4;
display[2]=3;
display[1]=7;
display[0]=5;
break;
case 8:
display[3]=5;
break;
case 9:
display[3]=5;
display[2]=6;
display[1]=2;
display[0]=5;
break;
case 10:
display[3]=6;
display[2]=2;
display[1]=5;
break;
case 11:
display[3]=6;
display[2]=8;
display[1]=7;
display[0]=5;
break;
case 12:
display[3]=7;
display[2]=5;
break;
case 13:
display[3]=8;
display[2]=1;
display[1]=2;
display[0]=5;
break;
case 14:
display[3]=8;
display[2]=7;
display[1]=5;
break;
case 15:
display[3]=9;
display[2]=3;
display[1]=7;
display[0]=5;
break;
default:break;
}
if(flag) //把負(fù)號標(biāo)志放在整數(shù)最高位不是0的前一位
{
if(display[6]==0&display[5]!=0) display[6]=16;
if(display[6]==0&display[5]==0&display[4]!=0) display[5]=16;
if(display[6]==0&display[5]==0&display[4]==0) display[5]=16;
flag=0;
}
for(j=6;j>3;j--)
{
if(display[j]!=0)
break;
if(j==4) break; //當(dāng)?shù)谝粋€整數(shù)位為0時,此位的0顯示;
display[j]=17; // 使為0的數(shù)據(jù)不顯示
}
}
/*uchar * read_rom(void)
{
uchar rom[8],i;
TxReset();
WrByte(0x33);
for(i=7;i>=0;i--)
{
rom[i]=RdByte();
}
return &rom[0];
} */
/*定時中斷,顯示采集的溫度*/
void t0(void) interrupt 1 using 0
{
uchar i,tr;
P2=0xff;
if(i==4)//使第四位帶有小數(shù)點
tr=0x80;
else //其他位小數(shù)點不顯示
tr=0x00;
P0=(tr|dispcode[display[i]]);
P2=dispbitcode[7-i];
i++;
if(i==8) i=0;
TH0=(65536-2200)/256;
TL0=(65536-2200)%256;
}
/*主函數(shù)*/
void main(void)
{
uchar i;
TMOD=0x01;
TH0=(65536-2200)/256;
TL0=(65536-2200)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
delay(130);
RdTemp(get_serial+i*8); // 讀取溫度
display[7]=i+10; //顯示當(dāng)前傳感器的編號
DataChange(); //數(shù)據(jù)處理
i++ ;
if(i==3) i=0;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -