深入解析:51单片机基础-DS18B20温度传感器

第十六章 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封装)

引脚名称连接方式
1GND接地
2DQ数据线(接单片机I/O)
3VDD接VCC(推荐外部供电)

有两种供电方式:

  • 外部供电:VDD接VCC,DQ接I/O;
  • 寄生供电:VDD接地,靠总线供电(对时序要求高)。

本章采用外部供电方式,更稳定。


2.2 电路连接

DS18B20连接
GND单片机GND
DQP1.7(单总线数据线)
VDDVCC(+5V)
  • 必须在DQ与VCC之间接一个4.7kΩ上拉电阻,确保空闲时为高电平。

单总线为开漏结构,需上拉。


3. 软件设计

3.1 单总线通信原理

DS18B20使用单线双向通信,所有操作都由主机(单片机)发起。通信流程:

  1. 复位:主机发送复位脉冲,DS18B20回应存在脉冲;
  2. 发送命令:如启动测温(0x44)、读取温度(0xBE);
  3. 读取温度数据:16位有符号数,包含整数与小数部分。

3.2 基本时序函数

#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 单总线读写函数

// 写一个字节
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 启动温度转换

void ds18b20_start_convert() {
ds18b20_reset();
ds18b20_write_byte(0xCC);  // 跳过ROM命令(单设备)
ds18b20_write_byte(0x44);  // 启动温度转换
}

3.5 读取温度值

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 简化温度读取(整数部分)

若只需整数温度:

unsigned char get_temp() {
int temp = ds18b20_read_temperature();
return temp / 1000;  // 返回整数部分(单位m°C)
}

3.7 主程序示例:读取并显示温度

#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 通过串口发送温度

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)。

本章标志着你已掌握单总线传感器驱动能力,具备了数据采集系统的核心技能


posted @ 2025-11-25 16:49  yangykaifa  阅读(2)  评论(0)    收藏  举报