|
你的需要把結(jié)果校驗(yàn)一下,有時(shí)候讀出來的值有問題的
//=========================DS18B20溫度傳感器=========================//
#define DS18B20_DQ_IN PIND & (1 << PD6)
/*******************************************************************************
* 函 數(shù) 名 : DS18B20_Reset
* 函數(shù)功能 : 復(fù)位DS18B20
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void DS18B20_Reset(void)
{
DDRD &= ~(1 << PD6); // 端口輸入
PORTD &= ~(1 << PD6); // 高阻態(tài)
delay_ms(1);
DDRD |= (1 << PD6); // 端口輸出,因?yàn)槭禽斎敫咦钁B(tài),設(shè)置成輸出時(shí)直接就會(huì)輸出低電平,拉低DQ
delay_us(500);
DDRD &= ~(1 << PD6); // 拉高DQ,釋放總線
delay_us(10);
}
/**
* @brief 單總線初始化
* @param 無
* @retval 從機(jī)響應(yīng)位,0為響應(yīng),1為未響應(yīng)
*/
uchar DS18B20_Check(void)
{
uchar i;
uchar AckBit = 1;
uchar TIMEOUT_MS = 500; // 進(jìn)行超時(shí)判斷
DS18B20_Reset();
while (DS18B20_DQ_IN && TIMEOUT_MS > 0)
{
TIMEOUT_MS--;
AckBit = DS18B20_DQ_IN;
}
delay_ms(1);
return AckBit;//如何DS18B20存在返回0,否則返回1
}
/*******************************************************************************
* 函 數(shù) 名 : DS18B20_Init
* 函數(shù)功能 : 初始化DS18B20的IO口 DQ 同時(shí)檢測(cè)DS的存在
* 輸 入 : 無
* 輸 出 : 1:不存在,0:存在
*******************************************************************************/
uchar DS18B20_Init(void)
{
uchar a;
a = DS18B20_Check();
return a;
}
/*******************************************************************************
* 函 數(shù) 名 : DS18B20_Write_Byte
* 函數(shù)功能 : 寫一個(gè)字節(jié)到DS18B20
* 輸 入 : dat:要寫入的字節(jié)
* 輸 出 : 無
*******************************************************************************/
void DS18B20_Write_Byte(uchar dat)
{
uchar j;
uchar testb;
for (j = 1; j <= 8; j++)
{
testb = dat & 0x01;
dat = dat >> 1;
if (testb)
{
DDRD |= (1 << PD6); // 拉低DQ
delay_us(2);
DDRD &= ~(1 << PD6); //輸入高阻態(tài),拉高DQ
delay_us(60);
}
else // Write 0
{
DDRD |= (1 << PD6); // 拉低DQ
delay_us(60);
DDRD &= ~(1 << PD6); //輸入高阻態(tài),拉高DQ
delay_us(2);
}
}
}
/*******************************************************************************
* 函 數(shù) 名 : DS18B20_Read_Bit
* 函數(shù)功能 : 從DS18B20讀取一個(gè)位
* 輸 入 : 無
* 輸 出 : 1/0 1001 0000
*******************************************************************************/
uchar DS18B20_Read_Bit(void) // read one bit
{
uchar data;
DDRD |= (1 << PD6); // 拉低DQ
delay_us(2);
DDRD &= ~(1 << PD6); //輸入高阻態(tài),拉高DQ
delay_us(2);
if (DS18B20_DQ_IN)
{
data = 1;
}
else
{
data = 0;
}
delay_us(50);
return data;
}
/*******************************************************************************
* 函 數(shù) 名 : DS18B20_Read_Byte
* 函數(shù)功能 : 從DS18B20讀取一個(gè)字節(jié)
* 輸 入 : 無
* 輸 出 : 一個(gè)字節(jié)數(shù)據(jù)
*******************************************************************************/
uchar DS18B20_Read_Byte(void) // read one byte
{
uchar i,j,dat;
dat=0;
for (i=0;i<8;i++)
{
j=DS18B20_Read_Bit();
if(j==1)
{
dat|=(0x01<<i);
}
}
return dat;
}
// 0xCC進(jìn)行設(shè)備尋址(只有一個(gè)從機(jī)時(shí)使用)
// 0x44溫度變換(讀取溫度前要執(zhí)行溫度變換,將溫度值放到暫存器里)
// 0xBE溫度讀。▽捍嫫骼锏臏囟茸x出)
//DS18B20指令
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE
/*******************************************************************************
* 函 數(shù) 名 : DS18B20_Start
* 函數(shù)功能 : 開始溫度轉(zhuǎn)換
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void DS18B20_Start(void)// ds1820 start convert
{
DS18B20_Check();
DS18B20_Write_Byte(DS18B20_SKIP_ROM);// skip rom
DS18B20_Write_Byte(DS18B20_CONVERT_T);// convert
}
/*******************************************************************************
* 函 數(shù) 名 : DS18B20_GetTemperture
* 函數(shù)功能 : 從ds18b20得到溫度值
* 輸 入 : 無
* 輸 出 : 溫度數(shù)據(jù)
*******************************************************************************/
uchar DS18B20_Crc(uchar *addr, uchar len)
{
uchar crc = 0, inbyte, i, mix;
while (len--)
{
// inbyte 存儲(chǔ)當(dāng)前參與計(jì)算的新字節(jié)
inbyte = *addr++;
for (i = 8; i; i--)
{
// 將新字節(jié)與CRC從低位到高位, 依次做異或運(yùn)算, 每次運(yùn)算完CRC右移一位
// 如果運(yùn)算結(jié)果值為1, 則將CRC與 1000 1100 作異或
// 第3,4位代表異或運(yùn)算, 第7位其實(shí)就是運(yùn)算結(jié)果移入的1
mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if (mix)
{
crc ^= 0x8C;
}
inbyte >>= 1;
}
}
return crc;
}
float DS18B20_GetTemperture(void)
{
uint temp;
uchar a, b;
static float value;
uchar tab[9], CRC8;
DS18B20_Start(); // ds1820 start convert
DS18B20_Check();
DS18B20_Write_Byte(DS18B20_SKIP_ROM); // skip rom
DS18B20_Write_Byte(DS18B20_READ_SCRATCHPAD); // convert
tab[0] = a = DS18B20_Read_Byte(); // LSB
tab[1] = b = DS18B20_Read_Byte(); // MSB
tab[2] = DS18B20_Read_Byte(); //
tab[3] = DS18B20_Read_Byte(); //
tab[4] = DS18B20_Read_Byte(); //
tab[5] = DS18B20_Read_Byte(); //
tab[6] = DS18B20_Read_Byte(); //
tab[7] = DS18B20_Read_Byte(); //
tab[8] = DS18B20_Read_Byte(); // CRC
CRC8 = DS18B20_Crc(tab,8);
if (CRC8 != tab[8]) // CRC校驗(yàn)
{
return value;
}
temp = (b << 8) | a;
if ((temp & 0xf800) == 0xf800)
{
temp = (~temp) + 1;
value = temp * (-0.0625);
}
else
{
value = temp * 0.0625;
}
return value;
}
//=========================DS18B20溫度傳感器=========================// |
|