基于ESP-IDF开发环境使用ESP32读取DS18B20温度

一、原理

        在只有一个DS18B20的时候,仅需三个部分就能完成读取温度的操作。

        (1)先初始化

        (2)写数据操作

        (3)读数据操作

二、代码

​​​​​​DS18B20参考代码链接,此链接有完整的基于ESP-IDF环境的ds18b20程序,有兴趣的可以去看看。

笔者的代码是参考以上链接的代码进行编写

以下代码仅供参考,代码仅为简单的读取温度操作,并未做出超出温度范围的限制。需要注意的是,此示例用的是4号引脚能正常读取数据,笔者的2、5号暂时不能读取,具体原因并未寻找,有能力的可以参照此示例去试试查看是何种问题导致的。(本文使用ESP32 DEVKIT V1开发板)

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"

#define DS18_PIN 4    //定义引脚
#define ESP_HIGH gpio_set_level(DS18_PIN, 1)    //设置高电平
#define ESP_LOW gpio_set_level(DS18_PIN, 0)    //设置低电平
#define ESP_GET gpio_get_level(DS18_PIN)    //读取电平
#define ESP_OUT_MODE gpio_set_direction(DS18_PIN, GPIO_MODE_OUTPUT)    //设置输出模式
#define ESP_INPUT_MODE gpio_set_direction(DS18_PIN, GPIO_MODE_INPUT)    //设置输入模式

#define SKIP_ROM 0xCC    //跳过ROM操作
#define TRANSFORMATION_TEMP 0x44    //转换温度操作
#define READ_TEMP 0xBE    //读数据操作

/*************************初始化操作*************************/
unsigned char init_DS18(void)
{
    unsigned int init_state = 0;
    ESP_OUT_MODE;
    ESP_LOW;
    ets_delay_us(480);
    ESP_HIGH;

    ESP_INPUT_MODE;//设置输入模式,就是高阻态,此时上拉电阻提供高电平
    ets_delay_us(70);
    init_state = (gpio_get_level(DS18_PIN) == 0);

    ets_delay_us(410);
    printf("初始化状态:%d", init_state);
    return init_state;
}
/*************************写位操作*************************/
void DS18_Write_bit(char bit)
{
/*******写1操作********/
    if (bit & 1)
    {
        ESP_OUT_MODE;
        ESP_LOW;
        ets_delay_us(6);
        ESP_INPUT_MODE;//设置输入模式,就是高阻态,此时上拉电阻提供高电平
        ets_delay_us(64);
    }
/*******写0操作********/
    else
    {
        ESP_OUT_MODE;
        ESP_LOW;
        ets_delay_us(60);
        ESP_INPUT_MODE;//设置输入模式,就是高阻态,此时上拉电阻提供高电平
        ets_delay_us(10);
    }
}
/*************************读位操作*************************/
unsigned char DS18_Read_bit(void)
{
    unsigned char bit = 0;
    ESP_OUT_MODE;
/*******拉低电平,开始读取数据********/
    ESP_LOW;
    ets_delay_us(6);
    ESP_INPUT_MODE;//设置输入数据
    ets_delay_us(9);
    bit = ESP_GET;
    ets_delay_us(55);

    return bit;
}
/*************************写数据操作*************************/
void DS18_Write_byte(unsigned char data)
{
    unsigned char i;
    unsigned char a_data;
/*******写8次,一次为一位********/
    for (i = 0; i < 8; i++)
    {
        a_data = data >> i;//每写一位数据,就向右移一位,保证8位数据都能写入
        a_data &= 0x01;//与操作,只留刚刚右移的一位数据
        DS18_Write_bit(a_data);//写入一位数据
    }
    ets_delay_us(100);
}
/*************************读数据操作*************************/
unsigned char DS18_Read_byte(void)
{
    unsigned char i;
    unsigned char data = 0;
/*******读取8次,一次为一位********/
    for (i = 0; i < 8; i++)
    {
        if (DS18_Read_bit())
            data |= 0x01 << i;//读取到1就会向左移相应的位数
        ets_delay_us(15);
    }
    return data;
}

void app_main(void)
{
    gpio_pad_select_gpio(DS18_PIN);
    while (1)
    {
        unsigned char TEMP_LOW, TEMP_HIGH;
        float TEMP = 0;
/*************************温度转换过程*************************/
        while(!init_DS18())
        {
            printf("正在尝试初始化...");
        }
        DS18_Write_byte(SKIP_ROM);
        DS18_Write_byte(TRANSFORMATION_TEMP);

        vTaskDelay(750 / portTICK_PERIOD_MS);
/*************************读取温度过程*************************/
        while(!init_DS18())
        {
            printf("正在尝试初始化...");
        }
        DS18_Write_byte(SKIP_ROM);
        DS18_Write_byte(READ_TEMP);
        TEMP_LOW = DS18_Read_byte();
        TEMP_HIGH = DS18_Read_byte();

/*************************把数据转换成十进制*************************/
        TEMP = (float)(TEMP_LOW + (TEMP_HIGH * 256)) / 16;

        printf("温度=%f", TEMP);
        vTaskDelay(2000 / portTICK_PERIOD_MS);
    }
}

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楂蓝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值