DS18B20测量温度


一、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后释放总线,然后主机读取总线数据。

/** 
 * @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次就可以了。

/** 
 * @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;
}

void DS18B20_Adjusting(DS18B20_TypeDef * const pDS18B20, float *temperature)
{
	*temperature -= pDS18B20->ZeroPoint;
	
}

结构体定义

typedef struct
{
    HAL_GPIO_TypeDef DIO;//数据输入输出端口
} OneWire_TypeDef;


typedef	struct {
	OneWire_TypeDef DQ;//数据输入输出端口
	float ZeroPoint;//归零点,如:如果当前温度室温为20℃,此时18B20测量出温度为21℃,那么需将这个值设置为1
	float Ratio[2];//倍率
	float RatioPoint[2];//倍率计算温度采样点
} DS18B20_TypeDef;

程序地址

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用DS18B20测量温度并用LCD1602显示,需要使用以下材料: - Arduino板 - DS18B20温度传感器 - LCD1602液晶显示屏 - 10K电位器 - 面包板 - 杜邦线 接线步骤如下: 1. 将DS18B20传感器的GND引脚连接到Arduino板的GND引脚上。 2. 将DS18B20传感器的VCC引脚连接到Arduino板的5V引脚上。 3. 将DS18B20传感器的数据线连接到Arduino板的数字引脚2上。 4. 将LCD屏幕的VSS引脚连接到Arduino板的GND引脚上。 5. 将LCD屏幕的VDD引脚连接到Arduino板的5V引脚上。 6. 将LCD屏幕的VO(对比度)引脚连接到10K电位器的中间引脚上,另外两个引脚连接到LCD屏幕的GND和5V引脚上。 7. 将LCD屏幕的RS引脚连接到Arduino板的数字引脚12上。 8. 将LCD屏幕的E引脚连接到Arduino板的数字引脚11上。 9. 将LCD屏幕的D4、D5、D6、D7引脚分别连接到Arduino板的数字引脚5、4、3、2上。 接线完成后,可以使用以下代码进行测试: ``` #include <OneWire.h> #include <DallasTemperature.h> #include <LiquidCrystal.h> #define ONE_WIRE_BUS 2 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { sensors.begin(); lcd.begin(16, 2); } void loop() { sensors.requestTemperatures(); float tempC = sensors.getTempCByIndex(0); lcd.setCursor(0, 0); lcd.print("Temp: "); lcd.print(tempC); lcd.print((char)223); lcd.print("C"); delay(1000); } ``` 此代码使用了OneWire库和DallasTemperature库来读取DS18B20传感器的温度值,然后使用LiquidCrystal库在LCD屏幕上显示温度值,单位为摄氏度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值