1、STM32CubeMx配置IO口
因?yàn)镈S18B20是單總線,數(shù)據(jù)接收發(fā)送都是這根線,所以單片機(jī)配置為開(kāi)漏上拉輸出。
2、定時(shí)器配置
因?yàn)镈S18B20對(duì)時(shí)序要求比較嚴(yán)格,建議用定時(shí)器延時(shí)獲得微秒延時(shí)函數(shù)。
總線為48M,分頻48,獲得1us定時(shí)時(shí)基。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-726390.html
3、頭文件
#ifndef __DS18B20_H
#define __DS18B20_H
#include "main.h"
// 定義DS18B20相關(guān)命令
#define DS18B20_CMD_SKIP_ROM 0xCC
#define DS18B20_CMD_CONVERT_T 0x44
#define DS18B20_CMD_READ_SCRATCHPAD 0xBE
void DS18B20_Init(void);
uint8_t DS18B20_Reset(void);
void DS18B20_StartConv(void);
float DS18B20_GetTemp(void);
#endif
4、C文件
#include "ds18b20.h"
#include "tim.h"
#define DS18B20_Set(x) HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, (GPIO_PinState)(x))
#define DS18B20_Get() HAL_GPIO_ReadPin(DS18B20_GPIO_Port, DS18B20_Pin)
void DS18B20_WriteByte(uint8_t byte);
uint8_t DS18B20_ReadByte(void);
/*****************************************************************************
* 說(shuō)明:DS18B20的微秒延時(shí)函數(shù)
* 輸入:_usTime時(shí)間
* 輸出:無(wú)
*****************************************************************************/
static void DS18B20_DelayUs(uint16_t _usTime)
{
__HAL_TIM_SetCounter(&htim1,0);
__HAL_TIM_ENABLE(&htim1);
while(__HAL_TIM_GetCounter(&htim1) < _usTime);
__HAL_TIM_DISABLE(&htim1);
}
/*****************************************************************************
* 說(shuō)明:復(fù)位并檢測(cè)DS18B20的存在
* 主機(jī)和DS18B20做任何通訊前都需要對(duì)其初始化。
* 初始化期間,總線控制器拉低總線并保持480us以上掛在總線上的器件將被復(fù)位,
* 然后釋放總線,等到15-60us,此時(shí)18B20將返回一個(gè)60-240us之間的低電平存在信號(hào)。
* 輸入:無(wú)
* 輸出:1=存在,0=不存在
*****************************************************************************/
uint8_t DS18B20_Reset(void)
{
uint8_t presence = 0;
// 拉低總線
DS18B20_Set(0);
DS18B20_DelayUs(600);
// 釋放總線
DS18B20_Set(1);
DS18B20_DelayUs(60);
// 檢測(cè)DS18B20響應(yīng)
presence = DS18B20_Get();
DS18B20_DelayUs(240);
return !presence;
}
/*****************************************************************************
* 說(shuō)明:復(fù)位DS18B20
* 輸入:無(wú)
* 輸出:無(wú)
*****************************************************************************/
void DS18B20_Init(void)
{
// 復(fù)位DS18B20
DS18B20_Reset();
// 發(fā)送跳過(guò)ROM命令
DS18B20_WriteByte(DS18B20_CMD_SKIP_ROM);
}
/*****************************************************************************
* 說(shuō)明:發(fā)送一個(gè)字節(jié)給DS18B20
* 1.總線控制器要產(chǎn)生一個(gè)寫時(shí)序,必須將總線拉低最少1us,
* 2.產(chǎn)生寫0時(shí)序時(shí)總線必須保持低電平60~120us之間,然后釋放總線,
* 3.產(chǎn)生寫1時(shí)序時(shí)在總線產(chǎn)生寫時(shí)序后的15us內(nèi)允許把總線拉高。
* 4.注意:2次寫周期之間至少間隔1us
* 輸入:無(wú)
* 輸出:無(wú)
*****************************************************************************/
void DS18B20_WriteByte(uint8_t byte)
{
for (uint8_t i = 0; i < 8; i++)
{
// 發(fā)送低位
DS18B20_Set(0);
DS18B20_DelayUs(2);
// 發(fā)送高位,根據(jù)byte的第i位來(lái)決定
if (byte & (1 << i))
{
DS18B20_Set(1);
}
DS18B20_DelayUs(60);
// 釋放總線
DS18B20_Set(1);
}
}
/*****************************************************************************
* 說(shuō)明:從DS18B20讀取一個(gè)字節(jié)
* 1.總線控制器要產(chǎn)生一個(gè)讀時(shí)序,必須將總線拉低至少1us,
* 2.然后釋放總線,在讀信號(hào)開(kāi)始后15us內(nèi)總線控制器采樣總線數(shù)據(jù),讀一位數(shù)據(jù)至少保持在60us以上。
* 3.注意:2次讀周期之間至少間隔1us
* 輸入:無(wú)
* 輸出:無(wú)
*****************************************************************************/
uint8_t DS18B20_ReadByte(void)
{
uint8_t byte = 0;
for (uint8_t i = 0; i < 8; i++)
{
// 發(fā)送低位
DS18B20_Set(0);
DS18B20_DelayUs(2);
// 釋放總線
DS18B20_Set(1);
DS18B20_DelayUs(8);
// 讀取高位數(shù)據(jù)
if (DS18B20_Get())
{
byte |= (1 << i);
}
DS18B20_DelayUs(50);
}
return byte;
}
/*****************************************************************************
* 說(shuō)明:?jiǎn)?dòng)DS18B20轉(zhuǎn)換
* 輸入:無(wú)
* 輸出:無(wú)
*****************************************************************************/
void DS18B20_StartConv(void)
{
DS18B20_Init();
// 發(fā)送溫度轉(zhuǎn)換命令
DS18B20_WriteByte(DS18B20_CMD_CONVERT_T);
}
/*****************************************************************************
* 說(shuō)明:讀取DS18B20溫度
* 1.溫度精度及轉(zhuǎn)換時(shí)間表
--------------------------------------
R1 R0 精度 最大轉(zhuǎn)換時(shí)間 溫度LSB
--------------------------------------
0 0 9bit 93.75ms 0.5℃
0 1 10bit 187.5ms 0.25℃
1 0 11bit 375ms 0.125℃
1 1 12bit 750ms 0.0625℃
--------------------------------------
* 輸入:無(wú)
* 輸出:浮點(diǎn)型溫度數(shù)據(jù)
*****************************************************************************/
float DS18B20_GetTemp(void)
{
// 復(fù)位DS18B20并跳過(guò)ROM
DS18B20_Init();
// 發(fā)送讀取寄存器命令
DS18B20_WriteByte(DS18B20_CMD_READ_SCRATCHPAD);
// 讀取溫度數(shù)據(jù)
uint8_t tempLow = DS18B20_ReadByte();
uint8_t tempHigh = DS18B20_ReadByte();
// 計(jì)算溫度值
int16_t temp = (tempHigh << 8) | tempLow;
float temperature = (float)temp / 16.0f;/*0.0625℃*/
return temperature;
}
5、使用方法
使用“void DS18B20_StartConv(void)”函數(shù)啟動(dòng)轉(zhuǎn)換,因?yàn)檗D(zhuǎn)換時(shí)間需要750ms(12Bit精度),所以隔1秒后,使用“float DS18B20_GetTemp(void)”函數(shù)獲取溫度。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-726390.html
到了這里,關(guān)于STM32使用HAL庫(kù)驅(qū)動(dòng)DS18B20的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!