一、DS18B20讀取溫度步驟
一般在使用DS18B20時(shí)會按照以下步驟進(jìn)行溫度轉(zhuǎn)換并讀?。?br> 1、主機(jī)發(fā)送復(fù)位脈沖
2、DS18B20響應(yīng)
3、發(fā)送0xCC命令跳過ROM命令
4、發(fā)送功能命令
5、發(fā)送功能命令0x44啟動溫度轉(zhuǎn)換
6、判斷溫度轉(zhuǎn)換是否完成(為讀取1Bit數(shù)據(jù)為1表示完成)
7、下一個(gè)初始化序列開始讀取溫度
8、然后按照序號1、2、3、4的順序執(zhí)行一遍,發(fā)送功能命令0xBE
9、讀取溫度
二、初始化復(fù)位時(shí)序
/**
* @brief 開始時(shí)序
* @param OneWire_TypeDef *pOneWire
* @retval:
*/
static uint8_t OneWire_StartPulse(OneWire_TypeDef * const pOneWire)
{
HAL_GPIO_SetOutput(&pOneWire->DIO);//產(chǎn)生復(fù)位時(shí)序 >480us
HAL_GPIO_Low(&pOneWire->DIO);
Delay_us(500);
HAL_GPIO_SetInput(&pOneWire->DIO);//等待讀取應(yīng)答信號 等待時(shí)間15us~60us
for (uint8_t i = 0; i <= 60; i++)
{
if (HAL_GPIO_Read(&pOneWire->DIO) == 0)
{
break;
}
if(i == 60)
{
return 1;
}
Delay_us(1);
}
for (uint8_t i = 0; i <= 240; i++)//等待DS18B20釋放總線 應(yīng)答時(shí)間60us~240us
{
if (HAL_GPIO_Read(&pOneWire->DIO) == 1)
{
break;
}
if(i == 240)
{
return 2;
}
Delay_us(1);
}
return 0;
}
2.發(fā)送一個(gè)字節(jié)
從圖中可以看到發(fā)送邏輯0為拉低總線60~120us,邏輯1為拉低總線后拉高總線整個(gè)時(shí)序要大于60us。
/**
* @brief 發(fā)送一個(gè)字節(jié)數(shù)據(jù)
* @param OneWire_TypeDef *pOneWire
* @param uint8_t dat
* @retval:
*/
static void OneWire_SendByte(OneWire_TypeDef * const pOneWire, uint8_t dat)
{
HAL_GPIO_SetOutput(&pOneWire->DIO);
for (uint8_t i = 0; i < 8; i++)
{
HAL_GPIO_Low(&pOneWire->DIO);
Delay_us(10);
if (dat & 0x01)//發(fā)送1 時(shí)序?yàn)槔?us~15us 然后釋放總線,時(shí)序大于60us
{
HAL_GPIO_High(&pOneWire->DIO);
Delay_us(60);
}
else//發(fā)送0 時(shí)序是拉低60us~120us 然后釋放總線要大于1us,時(shí)序大于60us
{
Delay_us(60);
HAL_GPIO_High(&pOneWire->DIO);
Delay_us(5);
}
dat >>= 1;
}
}
二、讀取數(shù)據(jù)
1、讀取一個(gè)Bit
從圖中可以看到主機(jī)拉低總線1~15us后釋放總線,然后主機(jī)讀取總線數(shù)據(jù)。文章來源:http://www.zghlxwxcb.cn/news/detail-400292.html
/**
* @brief 接收一個(gè)位數(shù)據(jù)
* @param OneWire_TypeDef *pOneWire
* @retval:
*/
static uint8_t OneWire_ReadBit(OneWire_TypeDef * const pOneWire)
{
uint8_t Bit = 0;
HAL_GPIO_SetOutput(&pOneWire->DIO);//讀取時(shí)序 主機(jī)將總線拉低1~15us,然后釋放總線,在15us后讀取數(shù)據(jù),時(shí)序大于60us
HAL_GPIO_Low(&pOneWire->DIO);
Delay_us(5);
HAL_GPIO_SetInput(&pOneWire->DIO);
Delay_us(10);
Bit = HAL_GPIO_Read(&pOneWire->DIO);
Delay_us(60);
return Bit;
}
2、讀取一個(gè)字節(jié)
讀取一個(gè)字節(jié)數(shù)據(jù)將讀一個(gè)Bit循環(huán)8次就可以了。文章來源地址http://www.zghlxwxcb.cn/news/detail-400292.html
/**
* @brief 從OneWire讀取一個(gè)字節(jié)
* @param OneWire_TypeDef *pOneWire
* @retval:
*/
static uint8_t OneWire_ReadByte(OneWire_TypeDef * const pOneWire)
{
uint8_t dat = 0;
for (uint8_t i = 0; i < 8; i++)
{
dat >>= 1;
dat |= OneWire_ReadBit(pOneWire);
}
return dat;
}
三、啟動溫度轉(zhuǎn)換
/**
* @brief 啟動一個(gè)溫度轉(zhuǎn)換
* @param DS18B20_TypeDef *pDS18B20
* @retval 0:成功 1:失敗
*/
uint8_t DS18B20_Convert(DS18B20_TypeDef * const pDS18B20)
{
uint8_t result = 0;
result = OneWire_StartPulse(&pDS18B20->DQ);
if (result)
return result;
OneWire_SendByte(&pDS18B20->DQ, 0xCC);//發(fā)送跳過ROM命令
OneWire_SendByte(&pDS18B20->DQ, 0x44);//發(fā)送轉(zhuǎn)換命令
return 0;
}
四、判斷轉(zhuǎn)換完成
/**
* @brief 檢測溫度轉(zhuǎn)換是否完成
* @param DS18B20_TypeDef *pDS18B20
* @retval 0:轉(zhuǎn)換中 1:轉(zhuǎn)換完成
*/
uint8_t DS18B20_IsConvertFinish(DS18B20_TypeDef * const pDS18B20)
{
return OneWire_ReadBit(&pDS18B20->DQ);
}
五、讀取溫度
/**
* @brief 讀取溫度值
* @param DS18B20_TypeDef *pDS18B20
* @param float *temperature 溫度值
* @retval 0:成功 1:失敗
*/
uint8_t DS18B20_ReadTemperature(DS18B20_TypeDef * const pDS18B20, float *temperature)
{
uint8_t result = 0;
uint8_t TL,TM;
result = OneWire_StartPulse(&pDS18B20->DQ);
if (result)
return result;
OneWire_SendByte(&pDS18B20->DQ, 0xCC);//發(fā)送跳過ROM命令
OneWire_SendByte(&pDS18B20->DQ, 0xBE);//發(fā)送讀取命令
TL = OneWire_ReadByte(&pDS18B20->DQ);//讀取溫度高位
TM = OneWire_ReadByte(&pDS18B20->DQ);//讀取溫度低位
if ((TM & 0xF8) == 0)//正數(shù)
{
*temperature = ((int16_t)((TM << 8) | TL)) * 0.0625f;
}
else//負(fù)數(shù)
{
*temperature = -((~(int16_t)((TM << 8) | TL)) + 1) * 0.0625f;
}
return 0;
}
程序地址
到了這里,關(guān)于DS18B20測量溫度的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!