基于单片机的数字温度计设计

news2025/1/23 17:45:53

一、项目背景

数字温度计是一种用于测量和显示环境温度的设备。本文章介绍基于STC89C52主控芯片的数字温度计的设计过程和实现原理。该设计采用DS18B20温度传感器进行温度采集,使用LCD1602显示屏进行温度显示,通过按键设置温度的上限和下限阀值,并通过蜂鸣器进行报警。

image-20230707170047960

image-20230707170116521

image-20230707170129434

二、系统架构

数字温度计的系统架构如下所示:

(1)硬件部分:主控芯片STC89C52、DS18B20温度传感器、LCD1602显示屏、按键、蜂鸣器;

(2)软件部分:嵌入式C语言程序。

三、系统功能设计

【1】温度采集:通过DS18B20温度传感器采集环境温度;

【2】温度显示:使用LCD1602显示屏显示当前环境温度;

【3】阈值设置:通过按键设置温度的上限和下限阀值;

【4】报警功能:当温度超出阀值时,蜂鸣器发出报警信号。

四、整体设计

4.1 硬件设计

【1】主控芯片选择:STC89C52,具有较好的性能和丰富的外设资源,适合作为数字温度计的核心处理器;

【2】温度传感器:采用DS18B20温度传感器,利用其一线通信功能实现温度采集;

【3】显示屏:使用LCD1602显示屏,通过并口连接到主控芯片,实时显示温度信息;

【4】按键:通过按键设置温度阀值,包括上限和下限;

【5】蜂鸣器:当温度超出阀值时,蜂鸣器发出报警信号。

4.2 软件设计

【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() 中的逻辑:

  • 调用 LCD_Init() 初始化LCD显示屏。
  • 进入一个无限循环,不断读取当前温度并显示在LCD上。
  • 如果当前温度超过设定的高温上限或低于设定的低温下限,就触发报警。
  • 通过按键扫描函数来修改高温上限和低温下限。

六、总结

本文章详细介绍了基于STC89C52主控芯片的数字温度计的设计过程和实现原理。通过集成DS18B20温度传感器、LCD1602显示屏、按键和蜂鸣器等功能,实现了温度的采集、显示和报警功能。通过按键设置温度的上限和下限阀值,用户可以根据需要进行调整,并在超出阀值时触发报警,提醒用户注意环境温度的变化。该设计可以广泛应用于家庭、办公室和实验室等场景,为用户提供了方便、准确和实用的温度监测工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/942607.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

点云配准算法之NDT

1 前言 很久之前记录了一篇博客PCL点云配准_thequitesunshine007的博客-CSDN博客 &#xff0c;记录的是基于点特征&#xff08;FPFH特征描述子&#xff09;匹配的SAC-ICP点云配准思想。 今天记录一下完全不一样的点云配准方法NDT。 2 介绍 2.1 多元正态分布 如果随机变量X满…

Servlet与Web容器的初探

Servlet 是用Java编写的服务端程序&#xff0c;具有独立于平台和协议的特性&#xff0c;主要功能在于交互式地浏览和生成数据&#xff0c;生成动态Web内容。 Servlet也需要帮助。请求到来时&#xff0c;必须有人实例化Servlet&#xff0c;或者至少要建立一个新的线程处理这个请…

js 正则表达式 验证 :页面中一个输入框,可输入1个或多个vid/pid,使用英文逗号隔开...

就是意思一个输入框里面&#xff0c;按VID/PID格式输入,VID和PID最大长度是4,最多50组 1、页面代码 <el-form ref"ruleForm" :model"tempSet" :rules"rules" label-position"right"> <!-- 最多 50组&#xff0c;每组9个字符…

RT_Thread内核机制学习(三)进程间通信

队列 队列里有多个消息块&#xff0c;每个消息块大小一致。 写&#xff1a; 有空间&#xff0c;成功。无空间&#xff1a;返回Err&#xff1b;等待一段时间。 队列里面会有两个链表&#xff1a;发送链表和接收链表 struct rt_messagequeue {struct rt_ipc_object parent; …

ChatGPT Prompting开发实战(二)

一、基于LangChain源码react来解析prompt engineering 在LangChain源码中一个特别重要的部分就是react&#xff0c;它的基本概念是&#xff0c;LLM在推理时会产生很多中间步骤而不是直接产生结果&#xff0c;这些中间步骤可以被用来与外界进行交互&#xff0c;然后产生new con…

C#,数值计算——双指数DE (double exponential)结构的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Structure for implementing the DE (double exponential) rule. /// </summary> public class DErule : Quadrature { private double a { get; set; …

基于SpringBoot的员工(人事)管理系统

基于SpringBoot的员工&#xff08;人事&#xff09;管理系统 一、系统介绍二、功能展示三.其他系统实现五.获取源码 一、系统介绍 项目名称&#xff1a;基于SPringBoot的员工管理系统 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 前端技术&#xff1a;BootS…

【Spring Cloud系列】- 分布式系统中实现幂等性的几种方式

【Spring Cloud系列】- 分布式系统中实现幂等性的几种方式 文章目录 【Spring Cloud系列】- 分布式系统中实现幂等性的几种方式一、概述二、什么是幂等性三、幂等性需关注几个重点四、幂等性有什么用五、常见用来保证幂等的手段5.1 MVCC方案5.2 去重表5.3 去重表5.4 select in…

5G 数字乡村数字农业农村大数据中心项目农业大数据建设方案PPT

导读&#xff1a;原文《5G 数字乡村数字农业农村大数据中心项目农业大数据建设方案PPT》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。以下是部分内容&#xff0c; 喜…

市级数字政府电子政务大数据中心项目建设和运营方案WORD

导读&#xff1a;原文《市级数字政府电子政务大数据中心项目建设和运营方案WORD》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。以下是部分内容&#xff0c; 目 录 …

5、监测数据采集物联网应用开发步骤(5.1)

监测数据采集物联网应用开发步骤(4) Sqlite3数据库读写操作开发、异常信息统一处理类开发 本章节需要调用sqlite3及mysql-connector 安装sqlite3 Pip3 install sqlite3 安装mysql-connector pip3 install mysql-connector 验证是否安装成功&#xff0c;python中运行下列…

Unity网格编程笔记[十]一些网格基础操作的封装(Mesh合并,UV映射,正反面反转,顶点合并,法线求切线计算等)

这里的代码是在 Unity网格编程笔记[五]网格切割 中整合出来的。 这里的mesh可以直接接入到使用mesh的unity组件 一些基础的属性还是要参考 Unity网格编程笔记[零]网格编程基础知识点 Mesh合并 网格的合并&#xff0c;其实底层也没那么复杂。对于三角面&#xff0c;只是顺序…

LiveGBS伴侣

【1】LiveGBS 简介 LiveGBS是一套支持国标(GB28181)流媒体服务软件。 国标无插件;提供用户管理及Web可视化页面管理&#xff1b; 提供设备状态管理&#xff0c;可实时查看设备是否掉线等信息&#xff1b; 实时流媒体处理&#xff0c;PS&#xff08;TS&#xff09;转ES&…

python的安装(推荐)

torch安装与卸载推荐链接1推荐链接2 推荐链接3 安装pytorch步骤推荐链接 python关键字&#xff1a;

19.CSS雨云动画特效

效果 源码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Cloud & Rain Animation</title><link rel="stylesheet" href="style.css"> </head> <bo…

SpringCluod深入教程

1.Nacos配置管理 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我们需要一种统一配置管理方案&#…

Jmeter+ServerAgent

一、Jmeter 下载 https://jmeter.apache.org/download_jmeter.cgi选择Binaries二进制下载 apache-jmeter-5.6.2.tgz 修改配置文件 jmeter下的bin目录&#xff0c;打开jmeter.properties 文件 languagezh_CN启动命令 cd apache-jmeter-5.6/bin sh jmeter二、ServerAgent 监…

Mysql--技术文档--MVCC(Multi-Version Concurrency Control | 多版本并发控制)

MVCC到底是什么 MVCC&#xff08;Multi-Version Concurrency Control&#xff09;是一种并发控制机制&#xff0c;用于解决并发访问数据库时的数据一致性和隔离性问题。MVCC允许多个事务同时读取数据库的同一数据&#xff0c;而不会相互干扰或导致冲突。 在传统的并发控制机制中…

CTFhub-文件上传-无验证

怎样判断一个网站是 php asp jsp 网站 首先&#xff0c;上传用哥斯拉生成 .php 文件 然后&#xff0c;用蚁剑测试连接 找到 flag_1043521020.php 文件&#xff0c;进去&#xff0c;即可发现 flag ctfhub{ee09842c786c113fb76c5542}

「Vue|网页开发|前端开发」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转

本文主要介绍如何使用路由控制来实现将一个单页面网站扩展成多页面网站&#xff0c;包括页面扩展的逻辑&#xff0c;vue的官方路由vue-router的基本用法以及扩展用法 文章目录 一、场景说明二、基本的页面扩展页面扩展是在扩什么创建新页面的代码&#xff0c;让页面内容变化起…