公司动态

DS18B20温度传感器与51单片机应用指南

📅 2026/7/19 11:23:46
DS18B20温度传感器与51单片机应用指南
1. DS18B20温度传感器概述DS18B20是一款由Dallas Semiconductor现为Maxim Integrated生产的数字温度传感器采用单总线1-Wire通信协议。与传统的模拟温度传感器相比它直接将温度转换为数字信号输出省去了模数转换环节大大简化了系统设计。在实际嵌入式项目中我经常使用DS18B20进行温度监测。它的最大特点是每个器件都有唯一的64位ROM编码这使得多个DS18B20可以挂接在同一条总线上而不会产生地址冲突。传感器测量范围为-55°C到125°C在-10°C到85°C范围内精度可达±0.5°C。注意DS18B20有TO-92、SOIC和µSOP三种封装形式其中TO-92封装最常见外形类似普通三极管三个引脚分别为GND、DQ和VDD。2. 硬件连接与电路设计2.1 基本连接方式DS18B20支持标准供电和寄生供电两种模式。在标准供电模式下需要连接VDD引脚3.0V-5.5V在寄生供电模式下VDD引脚接地传感器通过数据线获取工作电能。典型连接电路如下51单片机 DS18B20 P1.0 -------- DQ VCC -------- VDD (可选) GND -------- GND2.2 上拉电阻选择单总线协议要求数据线(DQ)必须有上拉电阻。根据我的实测经验标准供电模式推荐4.7kΩ上拉电阻寄生供电模式建议减小到2.2kΩ长距离传输10米可尝试1kΩ电阻重要提示如果使用51单片机的内部上拉电阻通常约50kΩ可能会导致通信不稳定。建议始终使用外部上拉电阻。3. 单总线通信协议详解3.1 时序基础DS18B20的通信基于严格的时序要求。51单片机需要通过GPIO模拟以下基本时序复位脉冲主机拉低总线480-960μs后释放存在脉冲从机在15-60μs内拉低总线60-240μs写时隙写1时主机拉低1-15μs后释放写0时拉低60-120μs读时隙主机拉低1μs后释放在时隙开始后15μs内采样总线状态3.2 典型通信流程一个完整的温度读取流程包括初始化发送复位脉冲检测存在脉冲ROM命令发送0xCC跳过ROM或0x55匹配ROM功能命令发送0x44开始温度转换等待转换典型延迟750ms12位分辨率再次初始化发送0xBE读取暂存器读取9字节数据温度值CRC4. 51单片机驱动实现4.1 底层驱动函数以下是基于51单片机的典型驱动代码Keil C51// 定义DQ引脚 sbit DQ P1^0; // 微秒级延时函数 void delay_us(unsigned int us) { while(us--) { _nop_(); _nop_(); _nop_(); _nop_(); } } // 复位DS18B20 bit DS18B20_Reset() { bit presence; DQ 0; delay_us(480); // 480-960us DQ 1; delay_us(60); // 等待15-60us presence DQ; // 采样存在脉冲 delay_us(420); // 等待剩余时间 return presence; } // 写入一个字节 void DS18B20_WriteByte(unsigned char dat) { unsigned char i; for(i0; i8; i) { DQ 0; _nop_(); _nop_(); // 延时约2us DQ dat 0x01; delay_us(60); // 保持60-120us DQ 1; dat 1; } } // 读取一个字节 unsigned char DS18B20_ReadByte() { unsigned char i, dat 0; for(i0; i8; i) { DQ 0; _nop_(); _nop_(); // 延时约2us DQ 1; _nop_(); _nop_(); // 延时约2us if(DQ) dat | 0x01i; delay_us(60); // 等待时隙结束 } return dat; }4.2 温度读取实现float DS18B20_ReadTemp() { unsigned char tempL, tempH; int temp; float temperature; DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 开始转换 delay_ms(750); // 等待转换完成 DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0xBE); // 读取暂存器 tempL DS18B20_ReadByte(); // 温度低字节 tempH DS18B20_ReadByte(); // 温度高字节 temp (tempH 8) | tempL; temperature temp * 0.0625; // 转换为实际温度 return temperature; }5. 精度配置与校准技巧5.1 分辨率设置DS18B20支持9-12位分辨率通过配置寄存器设置分辨率转换时间温度增量9位93.75ms0.5°C10位187.5ms0.25°C11位375ms0.125°C12位750ms0.0625°C设置分辨率代码示例void DS18B20_SetResolution(unsigned char resolution) { DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x4E); // 写暂存器 DS18B20_WriteByte(0xFF); // TH报警上限 DS18B20_WriteByte(0x00); // TL报警下限 DS18B20_WriteByte((resolution-9)5 | 0x1F); // 配置寄存器 DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x48); // 复制暂存器到EEPROM }5.2 温度校准方法在实际应用中我发现DS18B20可能存在±2°C的误差。校准方法准备标准温度源如冰水混合物0°C、沸水100°C读取DS18B20测量值计算误差补偿值在代码中添加补偿float calibrated_temp raw_temp offset;6. 多传感器组网实现6.1 ROM搜索算法当总线上挂接多个DS18B20时需要使用ROM搜索算法识别每个器件。基本步骤发送复位脉冲发送搜索ROM命令(0xF0)读取所有器件的ROM位根据冲突位选择路径重复直到识别所有器件6.2 典型应用电路51单片机 | |--[4.7kΩ]-- | | -- DS18B20 #1 -- DS18B20 #2 -- DS18B20 #37. 常见问题与解决方案7.1 通信失败排查检查硬件连接确认VCC/GND/DQ连接正确测量上拉电阻确保4.7kΩ电阻正常检查时序用示波器观察波形是否符合规范验证电源寄生供电时确保电压足够7.2 温度值异常处理返回85°C通常是上电默认值检查转换命令是否执行返回0°C可能是短路或传感器损坏随机跳变检查电源稳定性增加滤波电容8. 实际项目应用案例8.1 智能温控系统设计结合LCD1602显示和继电器控制实现温度监控void main() { float temp; LCD_Init(); while(1) { temp DS18B20_ReadTemp(); LCD_DisplayTemp(temp); if(temp 30.0) RELAY 1; // 开启制冷 else if(temp 25.0) RELAY 0; // 关闭制冷 delay_ms(1000); } }8.2 多点温度监测系统使用多个DS18B20监测不同位置温度float temps[3]; unsigned char i; for(i0; i3; i) { DS18B20_SelectDevice(i); // 选择第i个传感器 temps[i] DS18B20_ReadTemp(); }9. 性能优化技巧降低采样频率非关键应用可延长采样间隔使用中断代替延时提高系统响应速度缓存温度值避免频繁读取电源管理不测量时进入低功耗模式10. 进阶应用温度报警功能DS18B20内置温度报警功能配置方法// 设置报警阈值 void DS18B20_SetAlarm(signed char TH, signed char TL) { DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x4E); // 写暂存器 DS18B20_WriteByte(TH); // 上限 DS18B20_WriteByte(TL); // 下限 DS18B20_WriteByte(0x7F); // 配置寄存器(12位) DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0x48); // 保存到EEPROM } // 检查报警状态 bit DS18B20_CheckAlarm() { unsigned char alarm; DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0xBE); // 读暂存器 DS18B20_ReadByte(); // temp LSB DS18B20_ReadByte(); // temp MSB alarm DS18B20_ReadByte(); // TH alarm DS18B20_ReadByte(); // TL return (alarm 0x01); // 检查报警标志 }在实际项目中我发现DS18B20虽然简单易用但在长距离传输和强干扰环境下稳定性会下降。这种情况下可以考虑增加总线驱动芯片如DS2482或者改用I2C接口的温度传感器如LM75。不过对于大多数51单片机应用场景DS18B20仍然是性价比极高的选择。