一、DS18B20读取温度步骤
一般在使用DS18B20时会按照以下步骤进行温度转换并读取:
1、主机发送复位脉冲
2、DS18B20响应
3、发送0xCC命令跳过ROM命令
4、发送功能命令
5、发送功能命令0x44启动温度转换
6、判断温度转换是否完成(为读取1Bit数据为1表示完成)
7、下一个初始化序列开始读取温度
8、然后按照序号1、2、3、4的顺序执行一遍,发送功能命令0xBE
9、读取温度
二、初始化复位时序
/**
* @brief 开始时序
* @param OneWire_TypeDef *pOneWire
* @retval:
*/
static uint8_t OneWire_StartPulse(OneWire_TypeDef * const pOneWire)
{
HAL_GPIO_SetOutput(&pOneWire->DIO);//产生复位时序 >480us
HAL_GPIO_Low(&pOneWire->DIO);
Delay_us(500);
HAL_GPIO_SetInput(&pOneWire->DIO);//等待读取应答信号 等待时间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释放总线 应答时间60us~240us
{
if (HAL_GPIO_Read(&pOneWire->DIO) == 1)
{
break;
}
if(i == 240)
{
return 2;
}
Delay_us(1);
}
return 0;
}
2.发送一个字节
从图中可以看到发送逻辑0为拉低总线60~120us,逻辑1为拉低总线后拉高总线整个时序要大于60us。
/**
* @brief 发送一个字节数据
* @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)//发送1 时序为拉低1us~15us 然后释放总线,时序大于60us
{
HAL_GPIO_High(&pOneWire->DIO);
Delay_us(60);
}
else//发送0 时序是拉低60us~120us 然后释放总线要大于1us,时序大于60us
{
Delay_us(60);
HAL_GPIO_High(&pOneWire->DIO);
Delay_us(5);
}
dat >>= 1;
}
}
二、读取数据
1、读取一个Bit
从图中可以看到主机拉低总线1~15us后释放总线,然后主机读取总线数据。文章来源:https://www.toymoban.com/news/detail-400292.html
/**
* @brief 接收一个位数据
* @param OneWire_TypeDef *pOneWire
* @retval:
*/
static uint8_t OneWire_ReadBit(OneWire_TypeDef * const pOneWire)
{
uint8_t Bit = 0;
HAL_GPIO_SetOutput(&pOneWire->DIO);//读取时序 主机将总线拉低1~15us,然后释放总线,在15us后读取数据,时序大于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、读取一个字节
读取一个字节数据将读一个Bit循环8次就可以了。文章来源地址https://www.toymoban.com/news/detail-400292.html
/**
* @brief 从OneWire读取一个字节
* @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;
}
三、启动温度转换
/**
* @brief 启动一个温度转换
* @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);//发送跳过ROM命令
OneWire_SendByte(&pDS18B20->DQ, 0x44);//发送转换命令
return 0;
}
四、判断转换完成
/**
* @brief 检测温度转换是否完成
* @param DS18B20_TypeDef *pDS18B20
* @retval 0:转换中 1:转换完成
*/
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);//发送跳过ROM命令
OneWire_SendByte(&pDS18B20->DQ, 0xBE);//发送读取命令
TL = OneWire_ReadByte(&pDS18B20->DQ);//读取温度高位
TM = OneWire_ReadByte(&pDS18B20->DQ);//读取温度低位
if ((TM & 0xF8) == 0)//正数
{
*temperature = ((int16_t)((TM << 8) | TL)) * 0.0625f;
}
else//负数
{
*temperature = -((~(int16_t)((TM << 8) | TL)) + 1) * 0.0625f;
}
return 0;
}
程序地址
到了这里,关于DS18B20测量温度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!