|
#include <reg52.h>
#include <intrins.h>
sbit IO_18B20 = P3^2; //DS18B20通信引腳
/* 軟件延時(shí)函數(shù),延時(shí)時(shí)間(t*10)us */
void DelayX10us(unsigned char t)
{
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
/* 復(fù)位總線(xiàn),獲取存在脈沖,以啟動(dòng)一次讀寫(xiě)操作 */
bit Get18B20Ack()
{
bit ack;
EA = 0; //禁止總中斷
IO_18B20 = 0; //產(chǎn)生500us復(fù)位脈沖
DelayX10us(50);
IO_18B20 = 1;
DelayX10us(6); //延時(shí)60us
ack = IO_18B20; //讀取存在脈沖
while(!IO_18B20); //等待存在脈沖結(jié)束
EA = 1; //重新使能總中斷
return ack;
}
/* 向DS18B20寫(xiě)入一個(gè)字節(jié),dat-待寫(xiě)入字節(jié) */
void Write18B20(unsigned char dat)
{
unsigned char mask;
EA = 0; //禁止總中斷
for (mask=0x01; mask!=0; mask<<=1) //低位在先,依次移出8個(gè)bit
{
IO_18B20 = 0; //產(chǎn)生2us低電平脈沖
_nop_();
_nop_();
if ((mask&dat) == 0) //輸出該bit值
IO_18B20 = 0;
else
IO_18B20 = 1;
DelayX10us(6); //延時(shí)60us
IO_18B20 = 1; //拉高通信引腳
}
EA = 1; //重新使能總中斷
}
/* 從DS18B20讀取一個(gè)字節(jié),返回值-讀到的字節(jié) */
unsigned char Read18B20()
{
unsigned char dat;
unsigned char mask;
EA = 0; //禁止總中斷
for (mask=0x01; mask!=0; mask<<=1) //低位在先,依次采集8個(gè)bit
{
IO_18B20 = 0; //產(chǎn)生2us低電平脈沖
_nop_();
_nop_();
IO_18B20 = 1; //結(jié)束低電平脈沖,等待18B20輸出數(shù)據(jù)
_nop_(); //延時(shí)2us
_nop_();
if (!IO_18B20) //讀取通信引腳上的值
dat &= ~mask;
else
dat |= mask;
DelayX10us(6); //再延時(shí)60us
}
EA = 1; //重新使能總中斷
return dat;
}
/* 啟動(dòng)一次18B20溫度轉(zhuǎn)換,返回值-表示是否啟動(dòng)成功 */
bit Start18B20()
{
bit ack;
ack = Get18B20Ack(); //執(zhí)行總線(xiàn)復(fù)位,并獲取18B20應(yīng)答
if (ack == 0) //如18B20正確應(yīng)答,則啟動(dòng)一次轉(zhuǎn)換
{
Write18B20(0xCC); //跳過(guò)ROM操作
Write18B20(0x44); //啟動(dòng)一次溫度轉(zhuǎn)換
}
return ~ack; //ack==0表示操作成功,所以返回值對(duì)其取反
}
/* 讀取DS18B20轉(zhuǎn)換的溫度值,返回值-表示是否讀取成功 */
bit Get18B20Temp(int *temp)
{
bit ack;
unsigned char LSB, MSB; //16bit溫度值的低字節(jié)和高字節(jié)
ack = Get18B20Ack(); //執(zhí)行總線(xiàn)復(fù)位,并獲取18B20應(yīng)答
if (ack == 0) //如18B20正確應(yīng)答,則讀取溫度值
{
Write18B20(0xCC); //跳過(guò)ROM操作
Write18B20(0xBE); //發(fā)送讀命令
LSB = Read18B20(); //讀溫度值的低字節(jié)
MSB = Read18B20(); //讀溫度值的高字節(jié)
*temp = ((int)MSB << 8) + LSB; //合成為16bit整型數(shù)
}
return ~ack; //ack==0表示操作應(yīng)答,所以返回值為其取反值
}
|
|