数字温度计是一种用于测量和显示环境温度的设备。本文章介绍基于STC89C52主控芯片的数字温度计的设计过程和实现原理。该设计采用DS18B20温度传感器进行温度采集,使用LCD1602显示屏进行温度显示,通过按键设置温度的上限和下限阀值,并通过蜂鸣器进行报警。
数字温度计的系统架构如下所示:
(1)硬件部分:主控芯片STC89C52、DS18B20温度传感器、LCD1602显示屏、按键、蜂鸣器;
(2)软件部分:嵌入式C语言程序。
【1】温度采集:通过DS18B20温度传感器采集环境温度;
【2】温度显示:使用LCD1602显示屏显示当前环境温度;
【3】阈值设置:通过按键设置温度的上限和下限阀值;
【4】报警功能:当温度超出阀值时,蜂鸣器发出报警信号。
【1】主控芯片选择:STC89C52,具有较好的性能和丰富的外设资源,适合作为数字温度计的核心处理器;
【2】温度传感器:采用DS18B20温度传感器,利用其一线通信功能实现温度采集;
【3】显示屏:使用LCD1602显示屏,通过并口连接到主控芯片,实时显示温度信息;
【4】按键:通过按键设置温度阀值,包括上限和下限;
【5】蜂鸣器:当温度超出阀值时,蜂鸣器发出报警信号。
【1】GPIO配置:配置主控芯片的GPIO引脚,包括DS18B20温度传感器的引脚、LCD1602显示屏的引脚、按键的引脚和蜂鸣器的引脚;
【2】DS18B20通信:利用主控芯片的IO口实现与DS18B20温度传感器的一线通信,获取温度数据;
【3】LCD显示:通过并口通信协议,将温度数据发送给LCD1602显示屏进行显示;
【4】按键检测:使用外部中断方式监听按键引脚的状态变化,当按键被按下时,进入设置模式,并根据按键次数调整温度阀值;
【5】温度比较和报警:在主循环中,不断比较当前温度与设置的阀值,当温度超出阈值时,触发蜂鸣器报警。
- #include <reg52.h>
-
- // 定义IO口
- sbit DQ = P2^0;
- sbit RS = P2^1;
- sbit RW = P2^2;
- sbit E = P2^3;
- sbit K1 = P2^4;
- sbit K2 = P2^5;
- sbit Buzzer = P2^6;
-
- // 定义全局变量
- unsigned int highTemp = 30; // 温度上限
- unsigned int lowTemp = 20; // 温度下限
- unsigned int currentTemp = 0; // 当前温度
-
- // 延时函数
- void delay(unsigned int ms) {
- unsigned int i, j;
- for (i = ms; i > 0; i--)
- for (j = 110; j > 0; j--);
- }
-
- // DS18B20初始化
- bit Init_DS18B20() {
- bit presence;
-
- DQ = 1; // 设置DQ为输出
- delay(1);
- DQ = 0; // 主机拉低DQ线
- delay(75);
- DQ = 1; // 主机释放DQ线
- delay(4);
- presence = DQ; // 从机检测到的应答信号
-
- delay(20);
-
- return presence;
- }
-
- // DS18B20写字节
- void Write_DS18B20(unsigned char dat) {
- unsigned char i;
-
- for (i = 0; i < 8; i++) {
- DQ = 0; // 主机拉低DQ线
- _nop_();
- DQ = dat & 0x01; // 写数据位
- delay(5);
- DQ = 1; // 主机释放DQ线
- dat >>= 1;
- }
- }
-
- // DS18B20读字节
- unsigned char Read_DS18B20() {
- unsigned char i, dat;
-
- for (i = 0; i < 8; i++) {
- DQ = 0; // 主机拉低DQ线
- _nop_();
- DQ = 1; // 主机释放DQ线
- _nop_();
- dat >>= 1;
- if (DQ)
- dat |= 0x80; // 读数据位
- delay(5);
- }
-
- return dat;
- }
-
- // 读取温度
- unsigned char ReadTemperature() {
- unsigned char temp_h, temp_l;
-
- Init_DS18B20();
- Write_DS18B20(0xCC); // 跳过ROM指令
- Write_DS18B20(0xBE); // 发送读温度命令
-
- temp_l = Read_DS18B20(); // 读低字节
- temp_h = Read_DS18B20(); // 读高字节
-
- currentTemp = temp_h;
-
- return temp_l;
- }
-
- // LCD初始化
- void LCD_Init() {
- delay(15);
- Write_Command(0x38); // 设置8位数据总线,2行显示,5x7点阵
- Write_Command(0x0C); // 显示器打开,光标关闭
- Write_Command(0x06); // 光标右移,显示器不移动
- Write_Command(0x01); // 显示清屏
- }
-
- // LCD写命令
- void Write_Command(unsigned char com) {
- RS = 0;
- RW = 0;
- E = 1;
- P0 = com;
- delay(1);
- E = 0;
- }
-
- // LCD写数据
- void Write_Data(unsigned char dat) {
- RS = 1;
- RW = 0;
- E = 1;
- P0 = dat;
- delay(1);
- E = 0;
- }
-
- // LCD显示温度
- void Display_Temperature(unsigned char temp) {
- unsigned char temp_str[5];
-
- temp_str[0] = temp / 10 + '0';
- temp_str[1] = temp % 10 + '0';
- temp_str[2] = '.';
- temp_str[3] = ReadTemperature() / 10 + '0';
- temp_str[4] = ReadTemperature() % 10 + '0';
-
- Write_Command(0x80); // 第一行第一个字符位置
- Write_String("Temp: ");
- Write_Command(0x86); // 第一行第七个字符位置
- Write_String(temp_str);
- Write_Command(0xC0); // 第二行第一个字符位置
- Write_String("High: ");
- Write_Command(0xC6); // 第二行第七个字符位置
- Write_Char(highTemp / 10 + '0');
- Write_Char(highTemp % 10 + '0');
- Write_Command(0xCB); // 第二行第十个字符位置
- Write_String("Low: ");
- Write_Command(0xCF); // 第二行第十四个字符位置
- Write_Char(lowTemp / 10 + '0');
- Write_Char(lowTemp % 10 + '0');
- }
-
- // LCD写字符串
- void Write_String(unsigned char *str) {
- while (*str != '\0') {
- Write_Data(*str);
- str++;
- }
- }
-
- // LCD写字符
- void Write_Char(unsigned char dat) {
- Write_Data(dat);
- }
-
- // 蜂鸣器报警
- void Alarm() {
- Buzzer = 0;
- delay(500);
- Buzzer = 1;
- delay(500);
- }
-
- // 按键扫描
- void Key_Scan() {
- if (K1 == 0) { // K1按下,设置高温
- delay(5);
- if (K1 == 0) {
- highTemp++;
- Write_Command(0xCB); // 第二行第十个字符位置
- Write_Char(highTemp / 10 + '0');
- Write_Char(highTemp % 10 + '0');
- while (!K1);
- }
- }
-
- if (K2 == 0) { // K2按下,设置低温
- delay(5);
- if (K2 == 0) {
- lowTemp--;
- Write_Command(0xCF); // 第二行第十四个字符位置
- Write_Char(lowTemp / 10 + '0');
- Write_Char(lowTemp % 10 + '0');
- while (!K2);
- }
- }
- }
-
- // 主函数
- void main() {
- LCD_Init();
-
- while (1) {
- ReadTemperature(); // 读取温度
- Display_Temperature(currentTemp); // 显示温度
-
- if (currentTemp > highTemp || currentTemp < lowTemp) { // 温度超出阈值,触发报警
- Alarm();
- }
-
- Key_Scan(); // 按键扫描
- }
- }
-
-
代码最开始定义了一些用于控制硬件的IO口,如DQ用于连接温度传感器、RS、RW、E用于连接LCD显示屏、K1、K2用于连接按键、Buzzer用于连接蜂鸣器。接下来定义了一些全局变量,包括高温上限、低温下限以及当前温度。然后是一些函数的定义和实现,包括延时函数、DS18B20温度传感器初始化函数、写字节函数、读字节函数等。
ReadTemperature() 函数用于读取温度传感器的温度值,并将其保存到 currentTemp 变量中。
LCD_Init() 函数用于初始化LCD显示屏。
Write_Command() 和 Write_Data() 函数用于向LCD显示屏写入命令和数据。
Display_Temperature() 函数用于在LCD显示屏上显示当前温度、高温上限和低温下限。
Alarm() 函数用于触发蜂鸣器报警。
Key_Scan() 函数用于扫描按键状态,根据按键状态来修改高温上限和低温下限。
主函数 main() 中的逻辑:
本文章详细介绍了基于STC89C52主控芯片的数字温度计的设计过程和实现原理。通过集成DS18B20温度传感器、LCD1602显示屏、按键和蜂鸣器等功能,实现了温度的采集、显示和报警功能。通过按键设置温度的上限和下限阀值,用户可以根据需要进行调整,并在超出阀值时触发报警,提醒用户注意环境温度的变化。该设计可以广泛应用于家庭、办公室和实验室等场景,为用户提供了方便、准确和实用的温度监测工具。