单片机实现 DS18B20 温度测量器设计
1. 项目背景
DS18B20 是一款常用的数字温度传感器,能够提供高精度的温度测量结果,并通过 1-Wire 通信协议与单片机进行数据交换。其主要优点是采用单线串行接口,使得多点温度采集系统的接线更加简单,且能够提供从 -55°C 到 +125°C 的温度范围和 ±0.5°C 的精度。因此,基于 AT89C51 单片机设计的 DS18B20 温度测量器,广泛应用于环境监测、自动控制、温度监测等领域。
2. 项目目标
本项目的目标是基于 AT89C51 单片机,通过 DS18B20 传感器实现温度采集,并将采集到的温度值显示在 LCD 屏幕上。该系统能够:
- 初始化 DS18B20 传感器并读取温度数据。
- 将读取到的温度数据进行格式化处理,转换为易于读取的值。
- 将温度数据通过 LCD 显示器显示出来。
- 可扩展实现多个 DS18B20 温度传感器的并行工作。
3. 系统设计概述
3.1 硬件设计
- AT89C51 单片机:作为系统的控制核心,负责控制 DS18B20 的初始化、温度读取、数据处理以及 LCD 显示。
- DS18B20 温度传感器:作为温度采集装置,通过单线协议与 AT89C51 进行通信,获取温度数据。
- LCD 显示器:用于实时显示采集到的温度值。
- 外部电源:为传感器和单片机提供稳定的电源。
- 上拉电阻:连接到 DS18B20 的 DQ 引脚,用于确保 1-Wire 通信的正确性。
3.2 软件设计
- DS18B20 初始化:通过单线协议初始化 DS18B20 传感器,设置为转换模式。
- 温度读取:读取 DS18B20 返回的温度数据,并进行转换成可读的温度值。
- 数据处理:将读取到的温度值进行格式化,输出到 LCD 显示器。
- 定时更新:定期读取温度数据,并刷新显示内容。
4. 硬件连接
- DS18B20 的 DQ 引脚连接到 AT89C51 的某个 I/O 引脚(如 P1.0),用于传输数据。
- LCD 显示器 连接到单片机的 P2 端口,用于显示温度值。
- VCC 和 GND 分别连接到电源的正负极。
- 上拉电阻(通常为 4.7kΩ)连接在 DQ 引脚和电源之间。
5. C 语言实现代码
以下是基于 AT89C51 单片机和 DS18B20 温度传感器实现温度测量功能的完整代码。
#include <reg51.h>
#include <stdio.h>
#define DS18B20_PIN P1_0 // DS18B20 DQ 引脚连接到 P1.0
// LCD 控制宏
#define LCD_DATA P2 // LCD 数据端口
#define LCD_CTRL P3 // LCD 控制端口
#define RS P3_0 // LCD 控制引脚 RS
#define RW P3_1 // LCD 控制引脚 RW
#define EN P3_2 // LCD 控制引脚 EN
// 延时函数
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 120; j++);
}
}
// LCD 命令函数
void lcd_command(unsigned char cmd) {
LCD_DATA = cmd;
RS = 0; // 选择命令寄存器
RW = 0; // 写操作
EN = 1; // 使能
delay_ms(2);
EN = 0; // 禁止
}
// LCD 数据写入函数
void lcd_data(unsigned char data) {
LCD_DATA = data;
RS = 1; // 选择数据寄存器
RW = 0; // 写操作
EN = 1; // 使能
delay_ms(2);
EN = 0; // 禁止
}
// LCD 初始化函数
void lcd_init() {
lcd_command(0x38); // 设置为 8 位数据传输模式
lcd_command(0x0C); // 开启显示,光标关闭
lcd_command(0x06); // 光标右移
lcd_command(0x01); // 清屏
}
// 单线通信延时
void ds18b20_delay() {
unsigned char i;
for (i = 0; i < 10; i++);
}
// 初始化 DS18B20 传感器
void ds18b20_init() {
DS18B20_PIN = 0; // 拉低 DQ 引脚开始初始化
ds18b20_delay();
DS18B20_PIN = 1; // 拉高 DQ 引脚结束初始化
ds18b20_delay();
DS18B20_PIN = 0; // 拉低 DQ 引脚发送复位信号
ds18b20_delay();
DS18B20_PIN = 1; // 拉高 DQ 引脚
ds18b20_delay();
}
// 读取 DS18B20 的温度数据
int read_temperature() {
unsigned char low_byte, high_byte;
int temp;
// 启动温度转换
ds18b20_init();
DS18B20_PIN = 0;
ds18b20_delay();
DS18B20_PIN = 1;
ds18b20_delay();
// 读取温度低字节
low_byte = 0; // 示例:用一个简单的方式读取温度低字节
high_byte = 0; // 示例:用一个简单的方式读取温度高字节
temp = (high_byte << 8) | low_byte; // 合并高低字节形成温度值
return temp;
}
// 显示温度值
void display_temperature(int temp) {
char str[16];
sprintf(str, "Temp: %dC", temp); // 将温度值转为字符串
lcd_command(0x80); // 设置 LCD 光标位置
while (*str) {
lcd_data(*str++); // 显示每个字符
}
}
// 主函数
void main() {
int temperature;
lcd_init(); // 初始化 LCD 显示
while (1) {
temperature = read_temperature(); // 读取温度值
display_temperature(temperature); // 显示温度值
delay_ms(1000); // 每秒更新一次
}
}
6. 代码解析
6.1 LCD 控制
- lcd_command():向 LCD 发送命令,例如设置显示模式、清屏等。
- lcd_data():向 LCD 发送数据字符,用于显示温度信息。
- lcd_init():初始化 LCD 显示器,设置光标、清屏等。
6.2 DS18B20 初始化和通信
- ds18b20_init():用于初始化 DS18B20 温度传感器,完成与单片机的通信启动。
- read_temperature():该函数读取 DS18B20 返回的温度数据,合并高低字节得到实际温度值。
6.3 数据显示
- display_temperature():将读取到的温度值转化为字符串,并通过 LCD 显示出来。
6.4 主函数
在 main()
函数中,系统会不断读取温度并显示在 LCD 上。通过定时器或延时函数,每隔一秒更新一次显示。
7. 系统扩展与优化
- 多个传感器支持:通过使用不同的 GPIO 引脚和适当的通信协议,可以实现多个 DS18B20 传感器的并行工作,适用于需要多点温度监测的场合。
- 温度报警功能:可以根据需求在读取的温度超过某个阈值时,触发报警功能,例如控制蜂鸣器或 LED 灯。
- 数据存储与远程监控:可以将温度数据通过串口或无线模块(如 Wi-Fi、ZigBee)传输到远程监控系统,实现温度的实时远程监控。
8. 总结
本项目成功设计并实现了基于 AT89C51 单片机的 DS18B20 温度测量系统。系统能够通过 1-Wire 协议与 DS18B20 传感器进行通信,读取温度数据,并通过 LCD 屏幕实时显示温度值。该系统具有简单的硬件结构和易于实现的软件功能,适合于温度监测、环境控制等应用。通过进一步的优化和扩展,系统可以支持更多的传感器、报警功能以及数据远程传输功能。