嵌入式——51单片机3

【51单片机学习笔记】DS18B20温度传感器 + 51单片机阶段学习总复盘

📖今日学习:DS18B20数字温度传感器原理、时序、读写操作、代码实现;同时对整个51单片机阶段做学习总结。

🔍文章大纲

  1. DS18B20 基础概念与硬件
  2. DS18B20 核心时序(复位、写时序、读时序)
  3. DS18B20 操作命令
  4. DS18B20 完整代码示例
  5. 📚51单片机整体学习阶段复盘
  6. ✨学习重点汇总
  7. ⚠️易错点&踩坑记录
  8. 📝今日学习小结

1. DS18B20 基础概念与硬件

DS18B20 是单总线数字温度传感器,只需要一根IO引脚就可以完成单片机和传感器之间的通信。

主要特性

  1. 单总线协议:仅使用一根DQ信号线完成读写通信;电源可以采用外部供电或者寄生电源供电。
  2. 测温范围:‑55℃ ~ +125℃
  3. 温度分辨率可配置,默认12位分辨率;12位模式下温度最小精度 0.0625℃。
  4. 多个DS18B20可以挂载在同一根单总线上,依靠ROM序列号区分不同传感器。

硬件接线

  • DQ:接单片机任意GPIO引脚;必须外接4.7K上拉电阻!单总线总线空闲状态必须为高电平。
  • VCC:3.3‑5V供电
  • GND:接系统地

寄生供电模式:VCC引脚接GND,由DQ信号线给传感器供电;稳定性差,实际开发优先使用外部VCC供电。

温度存储格式

DS18B20转换完成之后,温度存在两个字节:TH(高字节)TL(低字节)

  • 12位模式:高字节的高5位是符号位;低11位存放温度数据。
  • 正数:直接把11位数值 ×0.0625 得到实际温度。
  • 负数:需要对11位数据取补码之后再计算温度。

2. DS18B20核心时序

单总线对时序要求极其严格,延时必须精准,晶振一般使用11.0592M或者12M,延时错一点点就会读取失败。

① 复位时序(初始化)

  1. 单片机把DQ拉低,保持至少480us
  2. DQ释放(拉高,依靠上拉电阻),等待15‑60us;
  3. DS18B20会拉低DQ输出存在脉冲(应答脉冲)
  4. 单片机检测DQ,如果出现低电平代表传感器存在;否则传感器未连接/故障。

② 写时序(写0 / 写1)

每一位写周期最少60us,两位之间间隔至少1us。

  • 写0:单片机拉低DQ,整个周期内保持低电平。
  • 写1:单片机拉低DQ很短时间(1‑15us),然后释放DQ变为高电平。

单片机写DS18B20:低位先发送(LSB先行)。

③ 读时序

  1. 单片机把DQ拉低,持续1‑2us,产生读起始信号,然后释放DQ;
  2. 在拉低之后的15us之内读取DQ电平,获取bit数据
  3. 每一个读周期总时长至少60us。>

重点:采样必须在拉低之后15us以内完成,晚了采样数据错误。

3. DS18B20常用命令

ROM命令(匹配传感器序列号,多器件挂载使用)

  1. 0x33:读ROM,读取DS18B20唯一64位序列号(单总线只挂一个传感器时使用)
  2. 0x55:匹配ROM,选中指定序列号传感器
  3. 0xCC:跳过ROM命令,总线上只有一个DS18B20的时候直接跳过ROM匹配,项目最常用

功能命令

  1. 0x44:启动温度转换;传感器开始采集温度,转换需要时间,12位模式最大750ms。
  2. 0xBE:读取暂存器,读取TH、TL温度字节等9个字节数据。

单传感器标准操作流程:

  1. 复位DS18B20
  2. 发送跳过ROM命令 0xCC
  3. 发送转换温度命令 0x44 → 等待转换完成
  4. 再次复位
  5. 发送跳过ROM 0xCC
  6. 发送读暂存器命令 0xBE
  7. 读取TL、TH两个字节,计算温度

4. DS18B20 51代码示例(12M晶振)

复制代码
#include <reg52.h>
typedef unsigned char uchar;
typedef unsigned int  uint;

sbit DQ = P3^7;   //DS18B20单总线引脚

//简单延时
void delay_us(uint t)
{
    while(t--);
}

void delay_ms(uint t)
{
    uint i,j;
    for(i=t;i>0;i--)
        for(j=110;j>0;j--);
}

//DS18B20复位,返回1存在;0不存在
uchar ds18b20_reset(void)
{
    uchar ack;
    DQ = 0;
    delay_us(480);   //拉低至少480us
    DQ = 1;
    delay_us(60);
    ack = DQ;        //读取应答脉冲
    delay_us(420);
    return (!ack);
}

//写一个bit
void ds18b20_write_bit(uchar bit_dat)
{
    DQ = 0;
    delay_us(2);
    if(bit_dat) DQ = 1;
    delay_us(60);
    DQ = 1;
}

//写一个字节
void ds18b20_write_byte(uchar dat)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        ds18b20_write_bit(dat&0x01);
        dat >>= 1;
    }
}

//读一个bit
uchar ds18b20_read_bit(void)
{
    uchar bit_dat;
    DQ = 0;
    delay_us(2);
    DQ = 1;
    delay_us(8);      //必须15us内采样
    bit_dat = DQ;
    delay_us(50);
    return bit_dat;
}

//读一个字节
uchar ds18b20_read_byte(void)
{
    uchar i,dat=0;
    for(i=0;i<8;i++)
    {
        dat >>=1;
        if(ds18b20_read_bit())
            dat |= 0x80;
    }
    return dat;
}

//读取温度,返回整型扩大10倍,如252代表25.2℃
int ds18b20_read_temp(void)
{
    uchar tl,th;
    int temp;
    if(!ds18b20_reset())
        return 0xffff;  //传感器异常

    ds18b20_write_byte(0xCC);  //跳过ROM
    ds18b20_write_byte(0x44);  //启动温度转换
    delay_ms(750);              //12位转换最大750ms

    ds18b20_reset();
    ds18b20_write_byte(0xCC);
    ds18b20_write_byte(0xBE);  //读暂存器

    tl = ds18b20_read_byte();
    th = ds18b20_read_byte();

    temp = (th<<8)|tl;
    //12位分辨率,放大10倍,保留小数点后1位
    temp = temp * 0.0625 *10;
    return temp;
}

void main(void)
{
    int temp;
    while(1)
    {
        temp = ds18b20_read_temp();
        delay_ms(1000);
    }
}

5. 📚51单片机整体学习阶段复盘

从入门到现在学习内容完整梳理:

  1. 基础入门
    最小系统(电源、晶振、复位、单片机芯片);机器周期概念;C51基本语法;sbit位定义。
  2. GPIO输出与输入
    4组IO口特性:P0开漏无上拉;P1/P2/P3准双向口,输入前写1;LED点亮;共阳/共阴数码管静态、动态扫描,消影;按键查询检测,软件消抖。
  3. 中断系统
    中断基本概念;5个中断源;中断号;总中断EA;外部中断边沿/电平触发;定时器0/1,模式1(手动重装)、模式2自动重装。
  4. 外设驱动
    蜂鸣器有源无源区分,三极管驱动;UART异步串口通信;寄存器SCON、TMOD;查询收发、串口中断收发。
  5. 单总线外设 DS18B20
    单总线通信,严格时序;复位、读写bit;ROM命令、功能命令;温度解析。

学习体会:51单片机重点在于硬件特性+时序理解 ,不是单纯写代码;很多bug根源是硬件电路或者延时时序不对。

后续可以学习:I2C、LCD1602、EEPROM;再过渡STM32。

✨学习重点

  1. DS18B20是单总线协议,DQ引脚必须接4.7K上拉电阻,否则通信失败。
  2. 时序是DS18B20重中之重:复位480us低电平;写时序、读时序采样窗口只有十几微秒,延时要匹配晶振。
  3. 单传感器使用0xCC跳过ROM命令简化流程;多传感器不能跳过ROM,必须匹配ROM序列号。
  4. 0x44温度转换命令发送后必须等待转换完成;12位分辨率最长需要750ms。
  5. 温度高低字节TH、TL组合,12位分辨率系数0.0625;区分正负温度处理。
  6. 51 IO口回顾:P0开漏;准双向口做输入必须写1;中断EA总中断;TI/RI硬件置位软件清零。
  7. UART串口:TXD‑P3.1,RXD‑P3.0,交叉接线;优先11.0592M晶振。
  8. 外设驱动思路:看懂硬件电路 → 读懂器件手册时序 → 编写底层时序函数 → 封装业务函数。

⚠️易错点&踩坑记录

  1. ❌DS18B20忘记接4.7K上拉电阻,单总线无法工作,读出来温度乱码。
  2. ❌延时函数和晶振不匹配,时序不对,复位应答收不到,读取全部错误。
  3. ❌发送0x44启动温度转换之后没有等待转换时间,直接读暂存器,读到旧的错误温度。
  4. ❌读时序采样时间太晚,超过15us窗口,bit采样错误,温度乱跳。
  5. ❌多片DS18B20挂载总线上,依然使用0xCC跳过ROM命令,通信冲突。
  6. ❌字节发送顺序搞反,单总线是低位先发送LSB先行
  7. ❌寄生供电模式,供电能力不足,传感器工作不稳定;开发优先外部VCC供电。
  8. ❌51准双向IO,读外部信号前忘记写1,读取电平异常。
  9. ❌串口忘记清零TI、RI标志位;DS18B20时序和串口延时混淆,两套延时不能混用。
  10. ❌温度正负没有做处理,负温度读取出来是巨大的错误数值。

📝今日学习小结

今天学习DS18B20数字温度传感器,理解单总线通信协议,重点掌握复位、写bit、读bit严格时序;掌握ROM命令、转换命令、读取暂存器流程,解析温度数据。

同时对整个51单片机阶段进行复盘,从最小系统、GPIO、数码管按键,中断、定时器,蜂鸣器串口,再到单总线外设DS18B20。

相关推荐
sunoo-2291 小时前
【51单片机实战】温控下位机完整实现:DS18B20采集 + 自定义二进制串口协议 + PWM声光告
笔记·学习·51单片机·串口
傲世仙尊1 小时前
从磁盘硬件到Ext文件系统-Linux磁盘级文件系统学习笔记
linux·运维·服务器·开发语言·c++
星源~1 小时前
Linux - Trae Code Linux 环境嵌入式开发指南
linux·mcu·嵌入式·trae code
曦夜日长1 小时前
Linux系统篇,进程概念(三):进程状态详解、僵尸进程与孤儿进程的深度解析、Slab机制的了解
linux·运维·服务器
FlightYe2 小时前
音视频修炼之编码器(一):AVC、HEVC编码器内部
android·linux·c++·音视频
云栖梦泽2 小时前
网络设备驱动(1)
linux·arm开发·嵌入式硬件
山下梅子酒2252 小时前
洛谷-入门-B2042
c语言
ysu_03142 小时前
08-二叉树遍历:四种方式详解
c语言·数据结构·算法·leetcode
Jia ming2 小时前
从打补丁到一行配置:PREEMPT_RT 主线化之后,实时内核到底该怎么配?
linux