1. DS18B20温度传感器与51汇编语言概述
DS18B20是一款经典的数字化温度传感器,采用单总线协议进行通信。在51单片机系统中,通过汇编语言直接操作DS18B20进行温度采集,是嵌入式开发中非常典型的硬件接口应用场景。这种组合在工业控制、环境监测等领域有着广泛应用,比如冷链物流中的温度监控、农业大棚的温控系统等。
选择51汇编语言操作DS18B20有几个显著优势:首先,汇编语言可以直接控制硬件时序,满足单总线协议严格的时序要求;其次,51单片机资源有限,汇编程序体积小、执行效率高;最后,这种底层操作方式有助于深入理解硬件工作原理。我在工业现场就遇到过C语言程序无法满足时序要求,最终改用汇编解决问题的案例。
2. 硬件连接与初始化配置
2.1 典型电路连接方案
DS18B20与51单片机的标准连接方式采用寄生供电模式,仅需连接DQ数据线到单片机的任意I/O口(如P1.0),加上一个4.7kΩ的上拉电阻即可。实际布线时要注意:总线长度不宜超过30米,在电磁干扰较强的环境中建议使用屏蔽线。
重要提示:上拉电阻必须接在靠近单片机一侧,若距离传感器过远会导致信号上升沿不达标。我曾调试过一个系统,就因为电阻位置不当导致通信失败。
2.2 单片机端口初始化
在汇编中需要先配置端口工作模式。以STC89C52为例,相关代码如下:
assembly复制ORG 0000H
MOV P1M0, #00H ; 设置P1口为准双向模式
MOV P1M1, #00H
对于某些增强型51单片机,可能还需要禁用数字输入缓冲:
assembly复制ANL P1M1, #0FEH ; P1.0关闭数字输入
3. 单总线协议底层驱动实现
3.1 复位脉冲与存在检测
单总线通信始于主机发出的复位脉冲(480μs低电平),随后释放总线等待传感器响应。DS18B20会在15-60μs内拉低总线作为应答。具体实现:
assembly复制RESET_18B20:
CLR P1.0 ; 拉低DQ
ACALL DELAY_480US
SETB P1.0 ; 释放总线
ACALL DELAY_60US
MOV C, P1.0 ; 检测应答
JC NO_DEVICE ; 无设备响应
ACALL DELAY_420US ; 等待时序完成
RET
调试技巧:用示波器观察复位时序时,若发现应答脉冲幅度不足,通常是上拉电阻值偏大导致,可尝试减小到3.3kΩ。
3.2 读写时序精准控制
单总线协议对时序要求极为严格,写0需要维持60μs低电平,写1则在15μs内拉低后立即释放。读时序则需在主机拉低1μs后采样总线状态:
assembly复制WRITE_BIT:
CLR P1.0 ; 拉低总线起始
RRC A ; 待写位移至C
JC WRITE_1
ACALL DELAY_60US ; 写0时序
SJMP WRITE_END
WRITE_1:
ACALL DELAY_6US ; 写1时序
SETB P1.0
ACALL DELAY_54US
WRITE_END:
SETB P1.0
RET
READ_BIT:
CLR P1.0 ; 拉低总线1μs
NOP
NOP
SETB P1.0 ; 释放总线
NOP ; 等待15μs采样
MOV C, P1.0 ; 读取数据位
ACALL DELAY_45US
RET
实际项目中,我发现不同批次的DS18B20对时序敏感度不同。建议在代码中预留调整空间,比如通过变量控制延时参数。
4. DS18B20温度采集全流程
4.1 传感器指令序列
完整的温度采集包含以下步骤:
- 复位总线
- 发送跳过ROM命令(0xCC)
- 发送启动转换命令(0x44)
- 等待转换完成(典型750ms@12位分辨率)
- 再次复位
- 发送读暂存器命令(0xBE)
- 连续读取9字节数据(含CRC校验)
关键代码片段:
assembly复制GET_TEMP:
ACALL RESET_18B20
MOV A, #0CCH ; 跳过ROM
ACALL SEND_BYTE
MOV A, #44H ; 启动转换
ACALL SEND_BYTE
ACALL DELAY_750MS
; ...后续读取流程
4.2 温度数据处理
读取的温度值以16位补码形式存储,需进行转换处理。当bit4=1时为负温度,需要取反加1后计算绝对值。具体算法:
assembly复制PROCESS_TEMP:
MOV A, TEMP_L ; 低字节
MOV B, TEMP_H ; 高字节
ANL B, #0F8H ; 保留符号位和整数部分
JNB B.3, POSITIVE
CPL A ; 负温度处理
ADD A, #1
CPL B
ADDC B, #0
POSITIVE:
; 此处B为整数部分,A为小数部分*0.0625
在液晶显示时,我通常将小数部分预先乘以625,再通过查表转换为ASCII码,避免浮点运算。
5. 抗干扰设计与性能优化
5.1 通信可靠性增强
工业环境中单总线易受干扰,建议采取以下措施:
- 在总线两端并联100pF电容滤波
- 关键操作前加入3次重试机制
- 对读取的9字节数据进行CRC校验(生成多项式x^8 + x^5 + x^4 + 1)
CRC校验代码示例:
assembly复制CRC_CHECK:
MOV R0, #SCRATCHPAD ; 暂存器首址
MOV R1, #8 ; 8字节数据
MOV A, #0 ; CRC初始值
CRC_LOOP:
XRL A, @R0
MOV R2, #8
CRC_BIT:
RRC A
JNC CRC_NEXT
XRL A, #18H ; 多项式系数
CRC_NEXT:
DJNZ R2, CRC_BIT
INC R0
DJNZ R1, CRC_LOOP
CJNE A, @R0, CRC_ERROR ; 与第9字节比较
RET
5.2 低功耗优化技巧
对于电池供电设备,可以:
- 在两次采集之间将DQ引脚设为高阻态
- 使用12位分辨率替代9位(减少采集频次)
- 利用DS18B20的报警搜索功能,仅当温度超限时才唤醒MCU
相关配置命令:
assembly复制SET_RESOLUTION:
ACALL RESET_18B20
MOV A, #0CCH ; 跳过ROM
ACALL SEND_BYTE
MOV A, #4EH ; 写暂存器
ACALL SEND_BYTE
MOV A, #00H ; TH报警上限
ACALL SEND_BYTE
MOV A, #00H ; TL报警下限
ACALL SEND_BYTE
MOV A, #7FH ; 12位分辨率(0x7F)
ACALL SEND_BYTE
6. 典型问题排查指南
6.1 常见故障现象与对策
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 读取温度恒为85℃ | 电源上电复位值 | 确保完成完整的温度转换周期 |
| 数据位随机错误 | 时序不精确或干扰 | 用示波器校准延时,增加重试机制 |
| 多设备无法区分 | 未使用ROM匹配命令 | 先执行搜索ROM算法(0xF0) |
| 长距离通信不稳定 | 信号衰减 | 改用DS18B20-PAR(寄生供电增强版) |
6.2 调试工具的使用技巧
- 逻辑分析仪配置:设置采样率≥4MHz,触发条件为下降沿
- 在关键代码段插入IO翻转指令,用示波器测量实际耗时:
assembly复制 SETB P3.0 ; 调试标记
ACALL DELAY_60US
CLR P3.0
- 建立测试框架:通过串口输出原始数据字节,验证每个通信环节
我在实际项目中总结出一个经验:当遇到难以解释的通信故障时,先将通信速率降低到标准值的1/2,逐步排查是硬件问题还是时序问题。