第十六章 DS18B20温度传感器
1. 导入
在前面章节中,我们学习了EEPROM、I²C通信等数据存储技术。本章将引入一种重要的传感器------DS18B20数字温度传感器 ,它采用单总线(1-Wire)协议 ,仅需一根I/O线即可完成供电与通信(支持寄生供电),具有测温精度高、抗干扰能力强、支持多点组网等特点。
DS18B20测温范围为 -55°C ~ +125°C ,精度可达 ±0.5°C,广泛应用于环境监测、恒温控制、智能家电等领域。
本章目标:
- 理解DS18B20的单总线通信原理;
- 掌握复位、读写时序;
- 实现温度的读取与解析;
- 将温度值通过数码管或串口显示;
- 为后续构建温控系统、数据采集网络打下基础。
2. 硬件设计
2.1 DS18B20引脚说明(TO-92封装)
| 引脚 | 名称 | 连接方式 |
|---|---|---|
| 1 | GND | 接地 |
| 2 | DQ | 数据线(接单片机I/O) |
| 3 | VDD | 接VCC(推荐外部供电) |
有两种供电方式:
- 外部供电:VDD接VCC,DQ接I/O;
- 寄生供电:VDD接地,靠总线供电(对时序要求高)。
本章采用外部供电方式,更稳定。
2.2 电路连接
| DS18B20 | 连接 |
|---|---|
| GND | 单片机GND |
| DQ | P1.7(单总线数据线) |
| VDD | VCC(+5V) |
- 必须在DQ与VCC之间接一个4.7kΩ上拉电阻,确保空闲时为高电平。
单总线为开漏结构,需上拉。
3. 软件设计
3.1 单总线通信原理
DS18B20使用单线双向通信,所有操作都由主机(单片机)发起。通信流程:
- 复位:主机发送复位脉冲,DS18B20回应存在脉冲;
- 发送命令:如启动测温(0x44)、读取温度(0xBE);
- 读取温度数据:16位有符号数,包含整数与小数部分。
3.2 基本时序函数
c
#include <reg52.h>
sbit DQ = P1^7;
void delay_us(unsigned int us) {
while(us--) _nop_();
}
// DS18B20复位
unsigned char ds18b20_reset() {
unsigned char presence;
DQ = 0;
delay_us(480); // 至少480μs
DQ = 1;
delay_us(60); // 主机释放总线
presence = DQ; // 从机拉低表示存在
delay_us(420); // 等待周期结束
return presence; // 0: 存在,1: 无设备
}
3.3 单总线读写函数
c
// 写一个字节
void ds18b20_write_byte(unsigned char dat) {
unsigned char i;
for (i = 0; i < 8; i++) {
DQ = 0;
_nop_();
DQ = dat & 0x01; // 先写低位
delay_us(60);
DQ = 1;
dat >>= 1;
}
}
// 读一个字节
unsigned char ds18b20_read_byte() {
unsigned char i, dat = 0;
for (i = 0; i < 8; i++) {
DQ = 0;
_nop_();
DQ = 1; // 释放总线
delay_us(2);
dat >>= 1;
if (DQ) dat |= 0x80;
delay_us(60);
}
return dat;
}
3.4 启动温度转换
c
void ds18b20_start_convert() {
ds18b20_reset();
ds18b20_write_byte(0xCC); // 跳过ROM命令(单设备)
ds18b20_write_byte(0x44); // 启动温度转换
}
3.5 读取温度值
c
int ds18b20_read_temperature() {
unsigned char TL, TH;
int temp;
ds18b20_reset();
ds18b20_write_byte(0xCC); // 跳过ROM
ds18b20_write_byte(0xBE); // 读温度寄存器
TL = ds18b20_read_byte(); // 低8位
TH = ds18b20_read_byte(); // 高8位
temp = (TH << 8) | TL; // 合成16位数据
// 转换为实际温度(默认12位精度,0.0625°C/LSB)
if (TH & 0x80) { // 负数(补码)
temp = ~temp + 1;
return -((temp * 625) / 10000.0); // 转为摄氏度(保留两位小数)
}
return (temp * 625) / 10000; // 正数
}
温度单位为0.0625°C,所以实际温度 = 读数 × 0.0625
3.6 简化温度读取(整数部分)
若只需整数温度:
c
unsigned char get_temp() {
int temp = ds18b20_read_temperature();
return temp / 1000; // 返回整数部分(单位m°C)
}
3.7 主程序示例:读取并显示温度
c
#include <reg52.h>
// 数码管段码表(共阴)
unsigned char code seg_code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 125; j++);
}
void display_digit(unsigned char pos, unsigned char num) {
P0 = seg_code[num];
P2 = (P2 & 0xF0) | (0x0F & ~(1 << pos));
delay_ms(1);
}
void main() {
int temp;
unsigned char t_display[4];
while(1) {
ds18b20_start_convert();
delay_ms(750); // 最长转换时间(12位精度)
temp = ds18b20_read_temperature(); // 单位:0.001°C
// 分离各位数字(假设温度0~99.9°C)
t_display[0] = (temp / 1000) / 10; // 十位
t_display[1] = (temp / 1000) % 10; // 个位
t_display[2] = (temp % 1000) / 100; // 小数第一位
t_display[3] = 0x80 | seg_code[t_display[2]]; // 带小数点
// 动态扫描显示
unsigned char i;
for (i = 0; i < 100; i++) {
display_digit(0, t_display[0]);
display_digit(1, t_display[1]);
display_digit(2, seg_code[t_display[2]]);
delay_ms(5);
}
}
}
3.8 通过串口发送温度
c
void uart_send_byte(unsigned char dat) {
SBUF = dat;
while(TI == 0);
TI = 0;
}
void send_temp_serial() {
int temp = ds18b20_read_temperature();
uart_send_string("Temp: ");
if (temp < 0) {
uart_send_byte('-');
temp = -temp;
}
uart_send_byte('0' + temp / 10000);
uart_send_byte('0' + (temp / 1000) % 10);
uart_send_byte('.');
uart_send_byte('0' + (temp % 1000) / 100);
uart_send_string("°C\r\n");
}
3.9 编译与下载
- Keil中创建工程;
- 确保DQ接P1.7,上拉电阻为4.7kΩ;
- 编译生成HEX;
- 下载至单片机;
- 观察数码管或串口是否显示合理温度。
若读数为85°C(默认值):
- 未成功启动转换;
- 检查复位和写命令流程。
4. 小结
本章通过驱动DS18B20温度传感器,掌握了单总线通信与传感器数据采集技术,主要内容包括:
- 硬件连接:学会使用外部供电与上拉电阻;
- 通信时序:掌握复位、读写、存在脉冲等单总线机制;
- 温度解析:从16位数据提取实际温度值;
- 应用扩展:通过数码管或串口显示温度;
- 系统能力:为构建温控系统、环境监测设备奠定基础。
4.1 常见问题与解决
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 读数85°C | 未成功通信,返回默认值 | 检查复位和上拉电阻 |
| 读数异常 | 时序不准 | 优化delay_us,避免编译器优化 |
| 多设备冲突 | 未使用ROM匹配 | 单设备用0xCC跳过,多设备需读ROM |
| 转换慢 | 精度设为12位 | 可设置为9位加快速度 |
4.2 下一步学习建议
- 学习 多DS18B20组网,实现多点测温;
- 结合 继电器 实现恒温控制;
- 使用 LCD1602 显示更丰富信息;
- 构建 无线温湿度监控系统(加nRF24L01)。
本章标志着你已掌握单总线传感器驱动能力,具备了数据采集系统的核心技能