这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STM32F103ZET6】11:读取DS18B20数字温度传感器

共2条 1/1 1 跳转至

【STM32F103ZET6】11:读取DS18B20数字温度传感器

高工
2025-11-03 19:10:11   被打赏 20 分(兑奖)     打赏

一:DS18B20知识分享:

    DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。

二:工作原理介绍:

    DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。 DS18B20测温原理:低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。

三:程序控制方法:

3.1 温度转换 44H 启动DS18B20进行温度转换

3.2 读暂存器 BEH 读暂存器9字节二进制数字

3.3 写暂存器 4EH 将数据写入暂存器的TH、TL字节

3.4 复制暂存器 48H 把暂存器的TH、TL字节写到E2PROM中

3.5 重新调E2PROM B8H 把E2PROM中的TH、TL字节写到暂存器TH、TL字节

3.6 读电源供电方式 B4H 启动DS18B20发送电源供电方式的信号给主CPU

四:软件代码如下所示:

4.1 先将数据线置高电平“1”。

4.2 延时(该时间要求的不是很严格,但是尽可能的短一点)

4.3  数据线拉到低电平“0”。

4.4 延时750微秒(该时间的时间范围可以从480到960微秒)。

4.5  数据线拉到高电平“1”。

4.6 延时等待

4.7 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。

4.8 将数据线再次拉高到高电平“1”后结束。

五:程序代码:

5.1 初始化DS18B20

static void ds18b20_reset(void)
{
    DS18B20_DQ_OUT(0);  /* 拉低DQ,复位 */
    delay_us(750);      /* 拉低750us */
    DS18B20_DQ_OUT(1);  /* DQ=1, 释放复位 */
    delay_us(15);       /* 延迟15US */
}

5.2 等待DSB20返回数据:

uint8_t ds18b20_check(void)
{
    uint8_t retry = 0;
    uint8_t rval = 0;

    while (DS18B20_DQ_IN && retry < 200)    /* 等待DQ变低, 等待200us */
    {
        retry++;
        delay_us(1);
    }
    if (retry >= 200)
    {
        rval = 1;
    }
    else
    {
        retry = 0;

        while (!DS18B20_DQ_IN && retry < 240)   /* 等待DQ变高, 等待240us */
        {
            retry++;
            delay_us(1);
        }

        if (retry >= 240) rval = 1;
    }
    return rval;
}

5.3 读取DS18B20的数据位

static uint8_t ds18b20_read_bit(void)
{
    uint8_t data = 0;
    DS18B20_DQ_OUT(0);
    delay_us(2);
    DS18B20_DQ_OUT(1);
    delay_us(12);

    if (DS18B20_DQ_IN)
    {
        data = 1;
    }

    delay_us(50);
    return data;
}

5.4 从DS18B20返回一个字节

static uint8_t ds18b20_read_byte(void)
{
    uint8_t i, b, data = 0;

    for (i = 0; i < 8; i++)
    {
        b = ds18b20_read_bit(); /* DS18B20先输出低位数据 ,高位数据后输出 */
        
        data |= b << i;         /* 填充data的每一位 */ 
    }
    return data;
}

5.5 写入一个字节:

static void ds18b20_write_byte(uint8_t data)
{
    uint8_t j;

    for (j = 1; j <= 8; j++)
    {
        if (data & 0x01)
        {
            DS18B20_DQ_OUT(0);  /*  Write 1 */
            delay_us(2);
            DS18B20_DQ_OUT(1);
            delay_us(60);
        }
        else
        {
            DS18B20_DQ_OUT(0);  /*  Write 0 */
            delay_us(60);
            DS18B20_DQ_OUT(1);
            delay_us(2);
        }

        data >>= 1;             /* 右移,获取高一位数据 */
    }
}

5.6 开启温度转换:

static void ds18b20_start(void)
{
    ds18b20_reset();
    ds18b20_check();
    ds18b20_write_byte(0xcc);   /*  skip rom */
    ds18b20_write_byte(0x44);   /*  convert */
}

5.7 :对读取到的DS18B20数据进行转换:

short ds18b20_get_temperature(void)
{
    uint8_t flag = 1;           /* 默认温度为正数 */
    uint8_t TL, TH;
    short temp;
    
    ds18b20_start();            /*  ds1820 start convert */
    ds18b20_reset();
    ds18b20_check();
    ds18b20_write_byte(0xcc);   /*  skip rom */
    ds18b20_write_byte(0xbe);   /*  convert */
    TL = ds18b20_read_byte();   /*  LSB */
    TH = ds18b20_read_byte();   /*  MSB */

    if (TH > 7)
    {
        TH = ~TH; 
        TL = ~TL;
        flag = 0;   /* 温度为负 */
    }

    temp = TH;      /* 获得高八位 */
    temp <<= 8;
    temp += TL;     /* 获得底八位 */
    
    /* 转换成实际温度 */
    if (flag == 0)
    {  
        temp = (double)(temp+1) * 0.625;
        temp = -temp;   
    }
    else
    {
        temp = (double)temp * 0.625;
    }
    
    return temp;
}

六:实物效果如下所示:

初始化好所使用的DS18B20所使用的IO口,直接调用读取函数就可以。

10-3.jpg

10-3.png





关键词: STM32F103ZET6     DS18B20    

院士
2025-11-04 10:25:27     打赏
2楼

挺好的文章。

可以实现DS18B20的温度读取,只不是使用了延时的处理方式。方法简单,建议下一篇使用更高级的方法实现,以提高系统的性能。



共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]