单总线协议与DS18B20温度传感器应用详解

发布时间:2026/7/18 3:36:19
单总线协议与DS18B20温度传感器应用详解 1. 单总线协议与DS18B20温度传感器概述单总线协议1-Wire是Maxim Integrated现为ADI开发的一种独特通信协议仅需一根数据线即可实现双向通信。这根线同时承担数据传输和供电双重职责通过外部上拉电阻确保总线空闲时保持高电平状态。这种设计在引脚资源有限的微控制器如51单片机、STM32应用中具有显著优势。DS18B20是单总线协议最具代表性的应用之一这款数字温度传感器将温度传感、ADC转换和单总线接口集成在TO-92或SO-8封装内。其核心特点包括测量范围-55°C至125°C精度±0.5°C-10°C至85°C范围可编程分辨率9至12位对应0.5°C至0.0625°C64位唯一ROM编码实现多点组网寄生供电模式仅需两根连线数据GND在实际项目中DS18B20常与LCD1602显示屏配合使用构成完整的温度监测系统。通过Proteus仿真可以验证硬件设计再移植到实际电路板上实现温度报警等功能。2. 单总线协议工作原理深度解析2.1 物理层特性单总线系统采用开漏结构必须外接4.7kΩ上拉电阻。通信速率通常为15.3kbps标准模式或142kbps过驱模式。总线电容应小于800pF传输距离一般不超过100米。时序控制是单总线通信的核心难点。所有操作都基于精确的时间槽time slot主机通过拉低总线启动通信从机在特定时间窗口内响应位传输通过不同脉宽区分0和12.2 通信流程三阶段初始化序列复位存在脉冲主机拉低总线480µs以上后释放DS18B20等待15-60µs后拉低总线60-240µs主机检测到该脉冲确认设备在线ROM命令阶段0x33读ROM读取64位唯一编码0x55匹配ROM指定目标设备0xCC跳过ROM单设备时简化操作0xF0搜索ROM多点组网时设备发现功能命令阶段0x44启动温度转换0xBE读取暂存器0x4E写入暂存器0x48复制暂存器到EEPROM2.3 数据读写时序详解写时序写0拉低总线60µs以上写1拉低总线1-15µs后释放每个时隙至少需要60µs恢复时间读时序主机拉低总线1µs后释放DS18B20在15µs内输出数据主机在时隙开始后15-60µs采样注意时序精度直接影响通信可靠性建议使用硬件定时器实现微秒级延时。3. DS18B20寄存器结构与温度计算3.1 内部存储结构DS18B20包含9字节暂存器字节0-1温度值LSBMSB字节2-3TH/TL报警阈值字节4配置寄存器字节5-7保留字节8CRC校验温度寄存器格式Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 S S S S S 2^6 2^5 2^4 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4S符号位1表示负温度3.2 温度值转换算法以12位分辨率为例// 读取原始数据 uint16_t temp_raw (temp_msb 8) | temp_lsb; // 处理负温度 if(temp_raw 0x8000){ temp_raw (~temp_raw 1); // 取补码 temperature -temp_raw * 0.0625f; } else { temperature temp_raw * 0.0625f; }分辨率设置配置寄存器9位93.75ms转换时间0.5°C分辨率10位187.5ms0.25°C11位375ms0.125°C12位750ms0.0625°C4. 硬件电路设计与实现4.1 典型连接方式标准供电模式DS18B20 | |-- VDD -- 3.3V/5V |-- DQ -- MCU_IO 4.7kΩ上拉 |-- GND -- 地寄生供电模式DS18B20 | |-- VDD -- 接地 |-- DQ -- MCU_IO 4.7kΩ上拉 |-- GND -- 地注意寄生供电时温度转换期间需强上拉总线提供足够电流4.2 多点组网设计多个DS18B20可并联在单总线上通过唯一ROM ID区分。典型电路多个DS18B20 DQ引脚并联 | |-- 公共4.7kΩ上拉电阻 |-- MCU GPIO4.3 抗干扰设计长距离传输时使用屏蔽双绞线降低上拉电阻值如2.2kΩ增加TVS二极管防护工业环境采用隔离电路如光耦隔离使用专用总线驱动器如DS2480B5. 软件实现与代码解析5.1 底层驱动函数GPIO初始化以STM32为例void DS18B20_GPIO_Init(void){ GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx, ENABLE); GPIO_InitStruct.GPIO_Pin GPIO_Pin_x; GPIO_InitStruct.GPIO_Mode GPIO_Mode_Out_OD; // 开漏输出 GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOx, GPIO_InitStruct); DS18B20_SetHigh(); // 初始状态置高 }复位函数uint8_t DS18B20_Reset(void){ uint8_t presence 0; DS18B20_SetOutput(); DS18B20_SetLow(); Delay_us(480); // 保持480µs低电平 DS18B20_SetInput(); // 释放总线 Delay_us(70); // 等待15-60µs if(!DS18B20_ReadPin()){ presence 1; // 检测到存在脉冲 } Delay_us(410); // 等待剩余时间 return presence; }5.2 完整温度读取流程float DS18B20_ReadTemp(void){ uint8_t temp_lsb, temp_msb; int16_t temp_raw; float temperature; // 1. 初始化序列 if(!DS18B20_Reset()) return 85.0f; // 错误返回默认值 // 2. 跳过ROM单设备 DS18B20_WriteByte(0xCC); // 3. 启动温度转换 DS18B20_WriteByte(0x44); while(!DS18B20_ReadPin()); // 等待转换完成 // 4. 再次初始化 DS18B20_Reset(); // 5. 跳过ROM DS18B20_WriteByte(0xCC); // 6. 读取暂存器 DS18B20_WriteByte(0xBE); // 7. 读取温度值 temp_lsb DS18B20_ReadByte(); temp_msb DS18B20_ReadByte(); // 8. 数据转换 temp_raw (temp_msb 8) | temp_lsb; temperature temp_raw * 0.0625f; return temperature; }5.3 多点温度监测实现ROM搜索算法void DS18B20_SearchRom(uint8_t *rom_list, uint8_t *dev_count){ uint8_t last_zero 0; uint8_t rom[8] {0}; *dev_count 0; while(DS18B20_FindNext(rom, last_zero)){ memcpy(rom_list[*dev_count * 8], rom, 8); (*dev_count); if(*dev_count MAX_DEVICES) break; } }指定设备温度读取float DS18B20_ReadTempByRom(uint8_t *rom){ // 发送匹配ROM命令 DS18B20_Reset(); DS18B20_WriteByte(0x55); for(int i0; i8; i){ DS18B20_WriteByte(rom[i]); } // 后续流程与单设备相同 DS18B20_WriteByte(0x44); // ...省略转换等待... return temperature; }6. 实际应用案例与优化技巧6.1 51单片机LCD1602温度显示系统硬件连接P1.0连接DS18B20 DQP0口连接LCD1602数据线P2.0-P2.2连接LCD1602控制线主程序逻辑void main(){ LCD_Init(); DS18B20_Init(); while(1){ float temp DS18B20_ReadTemp(); LCD_DisplayTemp(temp); Delay_ms(1000); // 1秒更新一次 } }6.2 温度报警系统实现#define TEMP_HIGH_ALARM 30.0f #define TEMP_LOW_ALARM 10.0f void CheckTempAlert(float temp){ static uint8_t buzzer_on 0; if(temp TEMP_HIGH_ALARM || temp TEMP_LOW_ALARM){ if(!buzzer_on){ Buzzer_On(); buzzer_on 1; LCD_ShowAlert(); } } else { if(buzzer_on){ Buzzer_Off(); buzzer_on 0; LCD_ClearAlert(); } } }6.3 低功耗优化策略间隔采样void LowPower_TempMonitoring(void){ while(1){ DS18B20_Wakeup(); float temp DS18B20_ReadTemp(); ProcessTempData(temp); Enter_SleepMode(600); // 休眠10分钟 } }降低分辨率void SetResolution(uint8_t res){ DS18B20_WriteScratchpad(0, 0, (res-9)5); DS18B20_CopyScratchpad(); // 保存到EEPROM }7. 常见问题与调试技巧7.1 典型故障排查表现象可能原因解决方案读取值固定85°C初始化失败检查复位脉冲时序、上拉电阻温度值跳变电源不稳增加去耦电容改用独立供电通信超时总线电容过大缩短线长降低上拉电阻值多点系统异常ROM冲突重新搜索ROM码检查线路连接7.2 Proteus仿真注意事项使用DALLAS库中的DS18B20模型设置正确的时钟频率与代码延时匹配添加4.7kΩ上拉电阻调试时启用虚拟终端监控总线数据7.3 实际项目经验分享长线驱动 在超过30米的线路中建议使用低阻值上拉1kΩ每20米增加一个中继节点采用RS-485转1-Wire桥接器抗干扰设计双绞线传输磁珠滤波在MCU端增加100Ω串联电阻软件容错float SafeReadTemp(void){ float temp; uint8_t retry 3; while(retry--){ temp DS18B20_ReadTemp(); if(temp ! 85.0f) break; // 85°C是默认错误值 Delay_ms(100); } return temp; }多任务系统优化将温度转换放在低优先级任务使用信号量保护单总线资源DMA定时器实现精确时序控制单总线协议虽然简单但在实际应用中需要特别注意时序精度和抗干扰设计。通过合理的硬件布局和软件容错机制可以构建稳定可靠的温度监测系统。对于需要更高实时性的应用可以考虑将DS18B20与RTOS结合或者采用硬件单总线控制器方案。