1-Wire协议详解:用DS18B20温度传感器讲透单总线
假设你在做一个温室温度监控系统需要测3个点的温度土壤、空气、水温。3个传感器用I2C的话要3组线或带地址切换用SPI要12根线。DS18B20用1-Wire协议3个传感器共用1根数据线就够了接线极其简单。这篇从单总线时序讲到DS18B20完整驱动代码可以直接用。一、1-Wire是什么1-Wire是Dallas现Maxim开发的单总线通信协议只用一根数据线GND就能通信和供电。特点只需1根数据线GND支持寄生供电数据线兼电源下面解释每个器件有唯一64位ROM编码下面解释一根总线可挂多个器件速率较低标准15.4kbps寄生供电是什么正常用法是VCC和GND两根线供电。寄生供电模式下DS18B20不接VCC只接数据线和GND从数据线上偷电数据线高电平时给内部电容充电低电平时靠电容维持。好处是少接一根线坏处是温度转换时电流不够需要主设备强行拉高数据线供电。新手建议先接VCC正常供电稳定后再试寄生供电。64位ROM编码是什么每个DS18B20出厂时都烧录了一个全球唯一的64位编码包含8位家族码DS18B20是0x28 48位序列号 8位CRC校验。这就像每个传感器的身份证号一根线上挂多个DS18B20时靠这个编码区分我在跟谁说话。对比协议线数速率供电I2C2线100k-3.4M独立供电SPI4线几十M独立供电1-Wire1线15.4k可寄生供电二、DS18B20简介参数值测温范围-55~125°C精度±0.5°C-10~85°C分辨率9-12位可配接口1-Wire供电3.0-5.5V或寄生供电封装TO-92像三极管DS18B20便宜2元左右、防水型号多是测温首选。三、1-Wire时序1-Wire通信的关键是严格的时间控制所有操作都是主设备拉低总线等待采样。前置准备底层宏和微秒延时新手必看下面的代码用到了ONEWIRE_LOW()、ONEWIRE_HIGH()、ONEWIRE_READ()和delay_us()这些底层操作这里先给出它们的实现/* 假设DS18B20接在PA0引脚需要在CubeMX里把PA0配成GPIO_Output开漏模式 */#defineONEWIRE_PINGPIO_PIN_0#defineONEWIRE_PORTGPIOA/* 拉低数据线 */#defineONEWIRE_LOW()HAL_GPIO_WritePin(ONEWIRE_PORT,ONEWIRE_PIN,GPIO_PIN_RESET)/* 释放数据线拉高实际上是设为输入模式让上拉电阻拉高 */#defineONEWIRE_HIGH()HAL_GPIO_WritePin(ONEWIRE_PORT,ONEWIRE_PIN,GPIO_PIN_SET)/* 读取数据线电平 */#defineONEWIRE_READ()HAL_GPIO_ReadPin(ONEWIRE_PORT,ONEWIRE_PIN)/* 微秒延时——用DWT计数器实现最精确 *//* DWTData Watchpoint and Trace是Cortex-M3/M4内核的调试单元 * 里面有一个32位循环计数器CYCCNT每个时钟周期1可以用来精确计时 */#defineDWT_INIT()do{\CoreDebug-DEMCR|(124);\DWT-CYCCNT0;\DWT-CTRL|1;\}while(0)#definedelay_us(us)do{\uint32_tstartDWT-CYCCNT;\uint32_tticks(SystemCoreClock/1000000)*(us);\while((DWT-CYCCNT-start)ticks);\}while(0)DWT是什么DWTData Watchpoint and Trace数据监视和跟踪是ARM Cortex-M3/M4内核里的一个硬件调试模块里面有个CYCCNT计数器每过一个时钟周期就1。我们用它来精确计时精度达到1个时钟周期72MHz下约14纳秒。比用定时器更方便不占用定时器资源。硬件接线VCC接3.3VGND接GND数据线(DQ)接PA0数据线和VCC之间必须接一个4.7kΩ上拉电阻。因为1-Wire是开漏输出芯片只能把线拉低拉高靠外部上拉电阻。3.1 复位脉冲初始化主设备拉低总线 ≥480μs ↓ 释放总线拉高 ↓ 等待15-60μs ↓ DS18B20拉低总线60-240μs存在脉冲 ↓ 主设备检测到低电平 → 说明器件存在uint8_tds18b20_reset(void){uint8_tpresence0;/* 拉低480μs */ONEWIRE_LOW();delay_us(480);/* 释放总线等待 */ONEWIRE_HIGH();delay_us(70);/* 检测存在脉冲低存在 */if(ONEWIRE_READ()0)presence1;delay_us(410);/* 等待结束 */returnpresence;/* 1检测到器件 */}3.2 写0和写1写0拉低60-120μs释放 写1拉低1-15μs释放保持高电平到60μs结束 主设备在写时隙的前15μs内决定是0还是1。voidds18b20_write_bit(uint8_tbit){if(bit){/* 写1拉低1μs释放69μs */ONEWIRE_LOW();delay_us(2);ONEWIRE_HIGH();delay_us(68);}else{/* 写0拉低60μs释放8μs */ONEWIRE_LOW();delay_us(60);ONEWIRE_HIGH();delay_us(8);}}voidds18b20_write_byte(uint8_tdata){for(uint8_ti0;i8;i){ds18b20_write_bit(data0x01);/* 低位先行 */data1;}}3.3 读0和读1主设备拉低1μs → 释放 → 在15μs内采样 采样到低 读到0DS18B20保持拉低 采样到高 读到1DS18B20释放总线uint8_tds18b20_read_bit(void){uint8_tbit;/* 拉低1μs */ONEWIRE_LOW();delay_us(2);/* 释放 */ONEWIRE_HIGH();/* 等待后采样 */delay_us(10);bitONEWIRE_READ();/* 等待时隙结束 */delay_us(50);returnbit;}uint8_tds18b20_read_byte(void){uint8_tdata0;for(uint8_ti0;i8;i){data1;if(ds18b20_read_bit())data|0x80;}returndata;}四、DS18B20常用命令命令代码功能Skip ROM0xCC跳过ROM寻址单器件Convert T0x44启动温度转换Read Scratchpad0xBE读暂存器含温度数据Match ROM0x55指定ROM地址多器件Read ROM0x33读ROM编码单器件五、完整温度读取流程floatds18b20_read_temp(void){uint8_ttemp_l,temp_h;int16_ttemp_raw;/* 1. 复位 */if(!ds18b20_reset())return-999.0f;/* 2. 跳过ROM 启动转换 */ds18b20_write_byte(0xCC);/* Skip ROM */ds18b20_write_byte(0x44);/* Convert T *//* 3. 等待转换12位约750ms */HAL_Delay(750);/* 4. 复位 */ds18b20_reset();/* 5. 跳过ROM 读暂存器 */ds18b20_write_byte(0xCC);/* Skip ROM */ds18b20_write_byte(0xBE);/* Read Scratchpad *//* 6. 读温度低字节先读 */temp_lds18b20_read_byte();temp_hds18b20_read_byte();/* 7. 转换12位分辨率0.0625°C/LSB */temp_raw(temp_h8)|temp_l;returntemp_raw*0.0625f;}六、多器件挂载ROM搜索一根总线挂多个DS18B20时需要用ROM地址区分/* 读取单个器件ROM */ds18b20_reset();ds18b20_write_byte(0x33);/* Read ROM */for(inti0;i8;i){rom[i]ds18b20_read_byte();}/* 指定器件操作 */ds18b20_reset();ds18b20_write_byte(0x55);/* Match ROM */for(inti0;i8;i){ds18b20_write_byte(rom[i]);/* 发送64位ROM地址 */}ds18b20_write_byte(0x44);/* 启动该器件转换 */七、常见踩坑坑1时序不准通信失败1-Wire对时间要求严格delay_us必须精准。HAL_Delay精度毫秒级不够用定时器或DWT计数器实现微秒延时。坑2上拉电阻数据线必须接4.7kΩ上拉电阻到VCC。1-Wire是开漏输出没上拉拉不高。坑3多器件读取到相同温度忘了用Match ROM指定器件所有器件同时响应导致冲突。必须先读ROM再指定。坑4寄生供电转换失败寄生供电模式下温度转换需要较强电流。转换时主设备要拉高总线提供电力强上拉。八、总结要点内容1-Wire单总线寄生供电复位拉低480μs存在脉冲写时序写0拉低60μs写1拉低2μs读时序拉低2μs15μs内采样DS18B20流程复位→0xCC→0x44→等750ms→读温度转换raw × 0.0625一句话总结1-Wire的核心是复位脉冲检测器件严格时隙控制读写ROM地址区分多器件。下一篇预告《Git版本管理嵌入式工程师必备技能》作者嵌入式阿蔡