標(biāo)題:
單片機(jī)DS18b20溫度檢測程序
[打印本頁]
作者:
zhangjinyu
時間:
2022-9-21 00:37
標(biāo)題:
單片機(jī)DS18b20溫度檢測程序
#include<reg51.h> //51單片機(jī)的頭文件
#define uchar unsigned char //宏定義,用uchar來代替unsigned char(無符號字符型變量,也即是無符號的8位變量),
//宏定義的原因就是書寫方便,宏定義后,uchar可直接用來定義變量
#define uint unsigned int //原因同上,不過要注意,unsigned int為無符號的整型變量
uint present; // 實際溫度(擴(kuò)大了10倍)
uint setting=30; //設(shè)定值
sbit led=P3^5; //sbit是用來管腳的。此處定義LED燈由P3.5口控制
sbit buzzer=P3^6; //蜂鳴器由P3.6口控制
sbit DS=P3^7; //讀取溫度引腳
sbit NixieTube0_DIG1=P1^2; // 實際溫度顯示十位數(shù)字的數(shù)碼管位選端
sbit NixieTube0_DIG2=P1^3; //// 實際溫度顯示個位數(shù)字的數(shù)碼管位選端
sbit NixieTube1_DIG1=P1^4; //// 設(shè)定溫度顯示十位數(shù)字的數(shù)碼管位選端
sbit NixieTube1_DIG2=P1^5; //// 設(shè)定溫度顯示個位數(shù)字的數(shù)碼管位選端
sbit add=P1^0; //按鍵加
sbit sub=P1^1; //按鍵減
unsigned char code table[]={0x82,0xF3,0x4A,0x62,0x33,0x26,0x06,0xE3,0x02,0x22}; //數(shù)碼管端碼表,相當(dāng)于顯示緩沖區(qū),依次是0——9.
void delay(uint count) //延時函數(shù),用來進(jìn)行延時,應(yīng)該是毫秒級延時
{
uint i;
while(count) // count為函數(shù)的形參,當(dāng)count為0時,跳出此處while循環(huán)
{
i=200;
while(i>0) //
i--; //此i--和while(i>0)可以看成是一個整體,當(dāng)i=0時,就會跳出,執(zhí)行count--。
count--; //count自減一次,i就會由200減到0
}
}
/***********************************************************
void initialize(void)//初始化函數(shù)
溫度傳感器采用的是DS18b20,此傳感器采用的
是“單總線”來傳輸數(shù)據(jù)。
在使用DS18b20時,要對其進(jìn)行初始化操作,其初始化的要求是(根據(jù)DS18b20的時序圖得):
(1)先將數(shù)據(jù)線置1,但是置1的時間要盡可能短(可以直接忽略此操作,因為51單片機(jī)引腳上電默認(rèn)就是高電平。)。
(2)將數(shù)據(jù)線(DS)拉低
(3)延時750us左右
(4)再將數(shù)據(jù)線(DS)拉高
(5)進(jìn)行短暫延時
*****************************************************************/
void initialize(void) //初始化
{
uint i;
DS=0; //將DS(P3.7)引腳拉低。請注意,這里的DS不是變量,而是單片機(jī)的引腳。!
i=103;
while(i>0)i--; //延時
DS=1; //將DS拉高
i=4;
while(i>0)i--; //短暫延時
}
/*************************************************************************************
說明:DS18b20采用的是單總線,一次只能讀取溫度的1個Bit。
函數(shù)作用:bit tmpreadbit(void) //溫度讀取函數(shù),此處讀取的是溫度的1個bit,帶返回值
函數(shù)使用舉例:A=tmpreadbit(); // 變量A保存的只是溫度的一個bit
DS18B20溫度讀取時序用單片機(jī)來實現(xiàn)的步驟如下:
(1) 數(shù)據(jù)線DS拉低
(2) 延時6us左右
(3)將數(shù)據(jù)線DS拉高
(4)延時4us左右
(5) 此時DS便會得到一個狀態(tài)位,即1個Bit的數(shù)據(jù)
(6)延時30us左右
**************************************************************************************/
bit tmpreadbit(void) //溫度讀取函數(shù),此處讀取的是溫度的1個bit.帶返回值
{
uint i;
bit dat;
DS=0;i++; //將數(shù)據(jù)線拉低并延時
DS=1;i++;i++; //將數(shù)據(jù)線拉高并延時
dat=DS; //讀取1個bit數(shù)據(jù),此處注意,DS變成了輸入引腳,DS18b20的數(shù)據(jù)會保存到局部變量dat中
i=8;while(i>0)i--; //延時
return (dat); //將讀取的數(shù)據(jù)返回
}
/***********************************************************************************************
說明:DS18b20采用的是單總線,一次只能讀取溫度的1個Bit。溫度一共8個bit,此函數(shù)共讀了8次
函數(shù)作用:uchar tmpread(void) //溫度讀取函數(shù),此處讀取的是溫度數(shù)據(jù)的原始數(shù)據(jù),帶返回值
函數(shù)使用舉例:A=tmpread(); // 變量A保存的是溫度的原始數(shù)據(jù)
*************************************************************************************************/
uchar tmpread(void)
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++) //采用for 循環(huán),讀取原始溫度數(shù)據(jù)
{
j=tmpreadbit(); //讀取一個位
dat=(j<<7)|(dat>>1);//讀取的溫度最低位在前,這樣剛好一個字節(jié)的溫度在dat中
}
return(dat); //將溫度數(shù)據(jù)返回
}
void tmpwritebyte(uchar dat) // 寫指令函數(shù), dat為形參。
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++) //for循環(huán),8次,剛好寫一個字節(jié)
{
testb=dat&0x01; //將形參的最低位與1相與,1&1=1,0&1=0;
dat=dat>>1; //執(zhí)行完testb=dat&0x01;把傳入的形參右移一位,方便判斷下一位數(shù)據(jù)是0還是1,共移位8次,保證寫入一個字節(jié)
if(testb) //write 1
{
DS=0;
i++;i++;
DS=1; //DS=1的延時比較長,寫入的就是1
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0
i=8;while(i>0)i--; //DS=0的延時比較長,寫入的就是0
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //溫度轉(zhuǎn)換函數(shù),
{
initialize(); //初始
delay(1);
tmpwritebyte(0xcc); //跳過讀ROM指令
tmpwritebyte(0x44); //告訴DS18b20轉(zhuǎn)換溫度
}
uint tmp() //轉(zhuǎn)換函數(shù),將原始數(shù)據(jù)轉(zhuǎn)化成實際的溫度數(shù)據(jù)
{
float tt;
uchar a,b;
initialize(); //初始化
delay(1); //延時
tmpwritebyte(0xcc);//跳過讀ROM指令
tmpwritebyte(0xbe); //讀溫度指令
a=tmpread(); // 低8位數(shù)據(jù),即溫度的小數(shù)部分
b=tmpread(); //高8位,即溫度的整數(shù)部分
present=b;
present<<=8; //將整數(shù)部分右移8位
present=present|a; //將兩個字節(jié)組合成一個字
tt=present*0.0625; //分辨率是0.0625,即原始數(shù)據(jù)*分辨率=實際溫度
present=tt*10+0.5; //乘10表示小數(shù)點后面只取一位,+0.5是表示四舍五入
return present; //返回實際溫度
}
//用的是共陽極數(shù)碼管,顯示原理采用的是動態(tài)顯示
void display0(uint temp) //溫度顯示函數(shù) ,temp 為形參
{
uchar A1,A2,A2t;
////此處注意!因溫度讀取函數(shù)中 present=tt*10+0.5;即將溫度擴(kuò)大了10倍,所以原始溫度的十位變成了百位,
//各位變成了十位,十分位變成了個位,因此我們只需取百位上的數(shù)字和十位上的數(shù)字即可。注意,是數(shù)字,不是數(shù)!
A1=temp/100; //取模,將百位數(shù)字取下,存到變量A1中,
A2t=temp%100; //取余,比如傳進(jìn)來的temp=325,則325%100=25;
A2=A2t/10; //將余數(shù)對10取模,比如 25/10=2;
NixieTube0_DIG1=1; //打開數(shù)碼管位選端
if(A1<=9|A1>=0) //判斷A1是否位一位數(shù)字,實際溫度的十位上的數(shù)字
P2=table[A1]; //送入顯示
delay(1); //延時,待顯示穩(wěn)定
NixieTube0_DIG1=0; // 關(guān)斷數(shù)碼管
NixieTube0_DIG2=1; //打開數(shù)碼管位選端
if(A2<=9|A2>=0) //判斷A2是否位一位數(shù)字,實際溫度的個位上的數(shù)字
P2=table[A2]; //送入顯示
delay(1); //延時,待顯示穩(wěn)定
NixieTube0_DIG2=0; // 關(guān)斷數(shù)碼管
}
void display1(uint spare) //設(shè)定溫度顯示
{
uchar B1,B2;
B1=spare/10; //將設(shè)定溫度對10取模,獲取十位上的數(shù)字
B2=spare%10; //將設(shè)定溫度對10取余,獲取個位上的數(shù)字
NixieTube1_DIG1=1; ////打開數(shù)碼管位選端
P2=table[B1]; //送入十位上的數(shù)字
delay(1); ////延時,待顯示穩(wěn)定
NixieTube1_DIG1=0; //關(guān)斷顯示
NixieTube1_DIG2=1; //打開顯示
P2=table[B2]; //送入個位上的數(shù)字
delay(1); //延時,待顯示穩(wěn)定
NixieTube1_DIG2=0; //關(guān)斷顯示
}
void main() //主函數(shù)
{
uchar a;
uchar b;
uchar c;
P2=0xf7; //對P2口初始化,開機(jī)先不讓數(shù)碼管顯示
NixieTube0_DIG1=1; //初始化,數(shù)碼管位選端拉高
NixieTube0_DIG2=1; //同上
NixieTube1_DIG1=1; //同上
NixieTube1_DIG2=1; //同上
buzzer=0; //蜂鳴器引腳拉低,上電,蜂鳴器響一秒
delay(1000); //延時1S左右
while(1)
{
tmpchange();//向溫度傳感器寫入溫度轉(zhuǎn)換指令
if(add==1) //如果 按鍵加 沒有按下
b=1; //b=1;b的作用相當(dāng)于松手檢測
if(add==0&b==1) //如果按鍵按下
{
if(setting==99)
{}
else
{
setting++;//設(shè)定值自加一次
b=0; //只有按下松手后,再按 按鍵加 才能再次使設(shè)定值自加一次
}
};
if(sub==1) //按鍵減未被按下
c=1; //作用與b相同
if(sub==0&c==1) //如果按鍵減 被按下
{
if(setting==0)
{}
else
{
setting--;//設(shè)定值自減一次
c=0; //作用同上面的b
}
};
if(present<=setting*10) //如果實際溫度小于設(shè)定溫度
{
buzzer=0; //蜂鳴器不響
led=0; //燈亮
}
else
{
buzzer=0; //否則 蜂鳴器響
led=1; //燈不亮
}
for(a=10;a>0;a--)
{
display0(tmp()); //顯示實際溫度
display1(setting); //顯示設(shè)定溫度
}
}
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1