1. DS18B20温度传感器实验详解
在嵌入式开发中,温度测量是一个基础但非常重要的功能。STM32F1系列芯片虽然内置了温度传感器,但由于芯片工作时自身会产生温升,导致测量环境温度时误差较大。因此,我们需要借助外部高精度温度传感器来实现更准确的温度测量。DS18B20就是这样一个理想的数字温度传感器解决方案。
1.1 DS18B20核心特性解析
DS18B20是DALLAS半导体公司推出的单总线数字温度传感器,相比传统热敏电阻具有显著优势:
- 单总线接口:仅需一根数据线即可实现双向通信,极大简化了硬件连接
- 宽电压范围:3.0V-5.5V工作电压,支持寄生电源模式
- 高精度测量:
- 测量范围:-55℃~+125℃
- 在-10℃~+85℃范围内精度可达±0.5℃
- 可编程分辨率:9-12位(对应0.5℃-0.0625℃)
- 多点组网能力:多个DS18B20可并联在同一总线上,实现分布式测温
- 数字输出:直接输出数字温度信号,抗干扰能力强
实际应用中,12位分辨率(0.0625℃)是最常用的设置,虽然转换时间较长(750ms),但能提供最精确的温度数据。
1.2 硬件连接与注意事项
1.2.1 硬件电路设计
普中开发板的DS18B20接口电路设计如下:
- 接口位置:PG11引脚(可配置为单总线接口)
- 上拉电阻:10KΩ上拉电阻确保总线稳定
- 兼容设计:接口同时支持DS18B20和DHT11传感器
硬件连接时需要特别注意:
- 传感器方向:DS18B20有明确的引脚顺序(切面朝上时,从左到右依次为GND、DQ、VDD)
- 防反接保护:虽然DS18B20具有电源反接保护,但长时间反接仍可能损坏器件
- 总线长度:单总线长度不宜超过20米,长距离传输需适当降低上拉电阻值
1.2.2 开发板实物连接
实际操作时:
- 找到开发板上标有"温度传感器"的3针接口
- 将DS18B20的凸起标记与接口标记对齐插入
- 确保接触良好,必要时可以用万用表检查VCC与GND间电压(3.3V或5V)
1.3 软件实现深度解析
1.3.1 单总线时序模拟
DS18B20通信完全依赖精确的时序控制,STM32需要软件模拟以下关键时序:
- 复位时序:
- 主机拉低总线480-960μs
- 释放总线后等待15-60μs
- 检测DS18B20的应答脉冲(60-240μs低电平)
c复制void DS18B20_Reset(void) {
DS18B20_IO_OUT(); // 配置为输出模式
DS18B20_DQ_OUT = 0; // 拉低总线
delay_us(750); // 保持低电平750μs
DS18B20_DQ_OUT = 1; // 释放总线
delay_us(15); // 等待15μs
}
- 写时序:
- 写0:拉低总线至少60μs
- 写1:拉低总线2μs后释放
c复制void DS18B20_Write_Byte(u8 dat) {
u8 i;
for(i=0; i<8; i++) {
DS18B20_DQ_OUT = 0; // 拉低开始写时序
delay_us(2); // 保持2μs
DS18B20_DQ_OUT = dat & 0x01; // 写入位数据
delay_us(60); // 保持60μs
DS18B20_DQ_OUT = 1; // 释放总线
dat >>= 1; // 准备下一位
}
}
- 读时序:
- 主机拉低总线1μs后释放
- 在15μs内采样总线状态
c复制u8 DS18B20_Read_Byte(void) {
u8 i, dat = 0;
for(i=0; i<8; i++) {
dat >>= 1;
DS18B20_DQ_OUT = 0; // 拉低开始读时序
delay_us(2); // 保持2μs
DS18B20_DQ_OUT = 1; // 释放总线
delay_us(12); // 等待12μs
if(DS18B20_DQ_IN) dat |= 0x80; // 读取数据位
delay_us(50); // 等待时序完成
}
return dat;
}
1.3.2 温度读取流程
完整的温度读取过程遵循以下步骤:
- 初始化复位
- 发送跳过ROM命令(0xCC)
- 发送温度转换命令(0x44)
- 等待转换完成(750ms@12位)
- 再次初始化复位
- 发送跳过ROM命令(0xCC)
- 发送读暂存器命令(0xBE)
- 连续读取两个字节的温度数据
- 计算实际温度值
c复制float DS18B20_GetTemperture(void) {
u16 temp;
u8 a, b;
float value;
DS18B20_Start(); // 启动温度转换
DS18B20_Reset();
DS18B20_Check();
DS18B20_Write_Byte(0xCC); // 跳过ROM
DS18B20_Write_Byte(0xBE); // 读暂存器
a = DS18B20_Read_Byte(); // 读取LSB
b = DS18B20_Read_Byte(); // 读取MSB
temp = b;
temp = (temp << 8) + a; // 合并两个字节
// 判断温度符号
if((temp & 0xF800) == 0xF800) { // 负温度
temp = (~temp) + 1;
value = temp * (-0.0625);
} else { // 正温度
value = temp * 0.0625;
}
return value;
}
1.3.3 主程序逻辑
主程序实现了周期性温度读取和系统状态指示:
c复制int main() {
u8 i = 0;
float temper;
// 初始化各外设
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
USART1_Init(115200);
// DS18B20初始化检测
while(DS18B20_Init()) {
printf("DS18B20检测失败,请插好!\r\n");
delay_ms(500);
}
printf("DS18B20检测成功!\r\n");
// 主循环
while(1) {
i++;
if(i % 20 == 0) { // 每200ms切换LED状态
LED1 = !LED1;
}
if(i % 50 == 0) { // 每500ms读取一次温度
temper = DS18B20_GetTemperture();
if(temper < 0) {
printf("检测的温度为:-");
} else {
printf("检测的温度为: ");
}
printf("%.2f°C\r\n", temper);
}
delay_ms(10);
}
}
1.4 常见问题与调试技巧
1.4.1 硬件连接问题排查
-
传感器无响应:
- 检查电源电压是否正常(3-5V)
- 确认传感器方向是否正确
- 测量DQ线是否有上拉电阻
- 尝试更换传感器排除硬件故障
-
温度读数异常:
- 确保转换等待时间足够(750ms@12位)
- 检查时序延时是否准确,特别是读/写时序
- 避免总线受到强电磁干扰
1.4.2 软件调试技巧
-
时序优化:
- 使用示波器观察实际时序波形
- 根据实际情况微调延时参数
- 在关键位置添加调试输出
-
精度提升:
- 采用多次测量取平均的方法
- 在温度稳定场合可适当降低分辨率以提高响应速度
- 实现温度补偿算法校正误差
-
低功耗优化:
- 在不需测量时将总线置为高电平
- 采用寄生电源模式时可控制VCC供电时间
- 适当延长测量间隔降低功耗
1.5 进阶应用建议
基于DS18B20的温度测量系统可以进一步扩展:
-
多点温度监测:
- 利用DS18B20的多点组网特性
- 通过ROM编码识别不同传感器
- 实现分布式温度监测网络
-
温度控制系统:
- 结合PID算法实现精确温控
- 设置温度上下限报警功能
- 通过PWM控制加热/制冷设备
-
低功耗设计:
- 采用间断工作模式
- 合理设置温度转换频率
- 利用STM32的低功耗模式
-
数据记录与分析:
- 添加SD卡存储历史数据
- 实现温度变化趋势分析
- 设置异常温度报警阈值
在实际项目中,我曾遇到DS18B20在工业环境中受干扰导致数据异常的情况。通过增加软件滤波算法(如滑动平均)和硬件滤波电路(在DQ线上添加100nF电容),有效提高了系统的稳定性。这也提醒我们,在复杂环境中,单纯的读取温度数据可能不够,还需要考虑数据的可靠性和系统的鲁棒性。
