基于51单片机的温度甲烷监测报警串口上报proteus仿真原理图PCB

news2024/7/4 5:13:19

功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前温度和甲烷浓度
2.超过甲烷浓度阈值,蜂鸣器报警
3.按键可更改甲烷浓度阈值上限和启动/暂停检测
4.0`20%浓度,绿色LED点亮
20%~阈值上限,黄色LED点亮,电机启动
超过阈值上限,红色LED点亮,电机启动,蜂鸣器报警
5.每隔2天,电机转动10分钟(为了方便演示,演示视频为间隔20秒)
6.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:
在这里插入图片描述

PCB :
在这里插入图片描述

主程序:

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include "18b20.h"
#include "tlc0832.h"
#include "lcd1602.h"
#include "delay.h"

sbit KEY_SUB = P3^6;
sbit KEY_ADD = P3^4;
sbit KEY_ALARM = P3^5;

sbit BUZZER = P2^2;
sbit MOTOR = P3^7;

sbit LED_RED = P1^5;
sbit LED_YELLOW = P1^4;
sbit LED_GREEN = P1^3;



#define ON 0
#define OFF 1

#define BUZZER_ON (BUZZER = 0)
#define BUZZER_OFF (BUZZER = 1)

#define MOTOR_ON (MOTOR = 0)
#define MOTOR_OFF (MOTOR = 1)

unsigned char dispFlag = 0; //更新显示标志
bit setFlag = 0; //设置参数标志
bit sendFlag = 0; //串口发送标志
bit alarmSwitch = 1; //报警开关
bit alarmFlag = 1; //报警标志
bit motorFlag = 0; //报警开启电机标志
bit motorFlag1 = 1; //定时开启电机标志
unsigned int second = 0;
unsigned char hour = 0;


int tempBuf = 0;                   //读取温度值
float temperature;              //实际温度值
int temperatureMax = 50;              //温度阈值
bit readTempFlag = 0; //定义读温度标志

int Conc = 0;
unsigned int ConcMax = 50;

char dis0[18]; //定义显示区域临时存储数组

void SendData(void);
void CheckKey(void);
void Timer0_Init(void); //定时器初始化
void UART_Init(void); //串口初始化
void UART_SendByte(unsigned char dat); //串口发送单字节数据
void UART_SendStr(unsigned char *s, unsigned char length); //发送定长度字符串


void main(void)
{
    bit ack = 0;
    
    Timer0_Init();
    LCD_Init();   //初始化液晶
    DelayMs(200); //延时有助于稳定
    LCD_Clear();  //清屏

    LCD_DispStr(0, 0, "T:      C S:   %");
    LCD_DispOneChar(7, 0, 0xdf); //写入温度右上角点

    sprintf(dis0, "SS:%3d%%", ConcMax); //打印温度值
    LCD_DispStr(0, 1, dis0);             //显示第二行
    UART_Init(); //初始化串口

    while (1) //主循环
    {
        CheckKey();            //检测按键
        if (readTempFlag == 1) //读取温度标志
        {
            readTempFlag = 0;
            DS18B20_Start();
            ack  = DS18B20_GetTemp(&tempBuf);
            if (ack == 1)
            {
                temperature = (float)tempBuf * 0.0625; //温度值转换
            }
            else 
            {
                temperature = 0;
            }
        }

        if (dispFlag == 1)
        {
            dispFlag = 0;

            sprintf(dis0, "%5.1f", temperature); //打印温度值
            LCD_DispStr(2, 0, dis0);             //显示第二行
           
            Conc = ReadADC(AIN0_GND);
            if (Conc <= 29)
            {
                Conc = 29;
            }
            Conc = (100 * (Conc - 29)) / 227; //计算有害气体浓度百分比
            

            sprintf(dis0, "%3d", Conc); //打印温度值
            LCD_DispStr(12, 0, dis0);             //显示第二行

            if (alarmSwitch)
            {
                if (Conc > ConcMax) //浓度超过最大设定则报警
                {
                    BUZZER_ON;
                    motorFlag = 1;
                    LED_RED = ON;
                    LED_YELLOW = OFF;
                    LED_GREEN = OFF;
                    alarmFlag = 1;
                }
                else if (Conc > 20 && Conc <= ConcMax) //浓度处于中间范围
                {
                    BUZZER_OFF;
                    motorFlag = 1;
                    LED_RED = OFF;
                    LED_YELLOW = ON;
                    LED_GREEN = OFF;
                    alarmFlag = 0;
                }
                else //浓度正常范围
                {
                    BUZZER_OFF;
                    motorFlag = 0;
                    LED_RED = OFF;
                    LED_YELLOW = OFF;
                    LED_GREEN = ON;
                    alarmFlag = 0;
                }
            }

            if (motorFlag == 1 || motorFlag1 == 1)
            {
                MOTOR_ON;
            }
            else
            {
                MOTOR_OFF;
            }

        }

        if (sendFlag == 1)
        {
            sendFlag = 0;
            SendData();
        }
    }
}


/************************* 串口发送数据 *************************/
void SendData(void)
{
    sprintf(dis0, "T:%5.1f'C S:%3d%%\r\n", temperature, Conc); //串口发送
    UART_SendStr(dis0, 18); //发送数据
    DelayMs(100);
    if (alarmFlag == 1)
    {
        UART_SendStr("Warning!!!\r\n", 12); //发送数据
        DelayMs(100);
    }
}

void CheckKey(void)
{

    if (KEY_SUB == 0) //减键按下
    {
        DelayMs(200);
        if (KEY_SUB == 0) //减键按下
        {
            if (ConcMax > 20)
            {
                ConcMax = ConcMax - 1;
            }
            sprintf(dis0, "SS:%3d%%", ConcMax);
            LCD_DispStr(0, 1, dis0);
        }
        
    }
    
    if (KEY_ADD == 0) //加键按下
    {
        DelayMs(200);
        if (KEY_ADD == 0) //加键按下
        {
            if (ConcMax < 99)
            {
                ConcMax = ConcMax + 1;
            }
            sprintf(dis0, "SS:%3d%%", ConcMax);
            LCD_DispStr(0, 1, dis0);
        }
        
    }
    
    if (KEY_ALARM == 0) //取消报警按键
    {
        DelayMs(20);
        if (KEY_ALARM == 0) //取消报警按键
        {
            if (alarmSwitch)
            {
                alarmSwitch = 0;
                BUZZER_OFF;
                LED_RED = OFF;
                LED_YELLOW = OFF;
                LED_GREEN = OFF;
            }
            else
            {
                alarmSwitch = 1;
            }
        }
        while (KEY_ALARM == 0);
    }
}

/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void Timer0_Init(void)
{
    TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
    TH0 = (65536 - 18432) / 256; //重新赋值 20ms
    TL0 = (65536 - 18432) % 256;
    EA = 1;  //总中断打开
    ET0 = 1; //定时器中断打开
    TR0 = 1; //定时器开关打开
}
/*------------------------------------------------
                定时器中断子程序
------------------------------------------------*/
void Timer0_Interrupt(void) interrupt 1
{
    static unsigned char time20ms  = 0;
    TH0 = (65536 - 18432) / 256; //重新赋值 20ms
    TL0 = (65536 - 18432) % 256;
    time20ms++;

    if (time20ms > 50)
    {
        time20ms = 0;
        readTempFlag = 1; //读标志位置1
        sendFlag = 1;
        if (motorFlag1 == 0) //电机停止状态
        {
            if (second >= 20 - 1) //1小时
            {
                second = 0;
                hour++;
                if (hour >= 2 - 1) //48小时
                {
                    hour = 0;
                    motorFlag1 = 1; //电机启动标志
                }
            }
            else
            {
                second++;
            }
        }
        else
        {
            if (second >= 20 - 1) //10分钟
            {
                second = 0;
                motorFlag1 = 0;
            }
            else
            {
                second++;
            }
        }
    }

    if (time20ms % 10 == 0)
    {
        dispFlag = 1;
    }
}


/************************* 串口配置 *************************/
void UART_Init(void)
{
	SCON = 0x50;
	TH2 = 0xFF;
	TL2 = 0xFD;
	RCAP2H = 0xFF;  //(65536-(FOSC/32/BAUD))   BAUD = 115200 FOSC = 11059200
	RCAP2L = 0xFD;

	/*****************/
	TCLK = 1;
	RCLK = 1;
	C_T2 = 0;
	EXEN2 = 0;

	/*****************/
	TR2 = 1;
	ES   = 0; //关闭串口中断
	EA   = 1; //打开总中断

}

/************************* 串口发送字节 *************************/
void UART_SendByte(unsigned char dat) //串口发送单字节数据
{
	unsigned char time_out;
    
	time_out = 0;
	SBUF = dat;						  //将数据放入SBUF中
	while ((!TI) && (time_out < 100)) //检测是否发送出去
	{
		time_out++;
		DelayUs10x(2);
	}		//未发送出去 进行短暂延时
	TI = 0; //清除ti标志
}

/************************* 串口发送字符串 *************************/
void UART_SendStr(unsigned char *s, unsigned char length)
{
	unsigned char num;
	num = 0x00;
	while (num < length) //发送长度对比
	{
		UART_SendByte(*s); //放松单字节数据
		s++;			  //指针++
		num++;			  //下一个++
	}
}


仿真演示视频:
https://www.bilibili.com/video/BV1514y1h7eT/

实物演示视频:
https://www.bilibili.com/video/BV1uN4y1A7B5/

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

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

相关文章

C#操作modbus

modbus使用范围广泛&#xff0c;广泛应用于各类仪表&#xff0c;PLC等。 modbus的好处是免费&#xff0c;属于应用层协议&#xff0c;底层硬件基于485/以太网。 modbus协议本质还是自定义协议。 modbus调试软件&#xff1a; mthings: modbuspoll: 主站/从站&#xff0c;客…

前端静态页面基本开发思路(一)

有不少刚入门前端的同学经常问我前端布局的问题&#xff0c;总是跟我说在面对学校布置的作业或者想自己搭建博客的时候不知道怎么下手&#xff0c;不知道怎么去写静态的页面&#xff0c;每当我解决了一个又一个同学的问题的时候&#xff0c;又有新的同学来问&#xff0c;故思来…

nginx 配置防盗链(了解)

一 防盗链 1.1 防盗链概念 网站上页面的一些静态资源&#xff0c;不想让本站点的静态资源被他人盗取访问。使用nginx判断请求连接的头部refer中是否含有内容以及合法性来进行处理。 referer表示第二次资源的来源地址 1.2 配置规则 valiad_referers none|blocked|server_na…

Spring--IOC基于XML管理bean

IOC容器 IOC思想 IOC&#xff1a;Inversion of Control 即反转控制 获取资源的传统方式 自己做饭&#xff1a;买菜、洗菜、择菜、改刀、炒菜&#xff0c;全过程参与&#xff0c;费时费力&#xff0c;必须清楚了解资源创建整个过程中的全部细节且熟练掌握。 在应用程序中的组件…

Antd表格性能优化

今天来分享一个实际项目的性能优化的内容。 文章目录一、背景介绍二、性能问题原因及解决方案一、背景介绍 国内React项目大多数人选择配套的UI库的时候都会选择Antd。如果是非常简单的页面用Antd的话其实是完全没问题的&#xff0c;性能感觉不到什么瓶颈&#xff0c;样式也还…

计算机网络

目录 介绍 组成部分 工作方式 功能组成 网络范围分类 传输技术&#xff1a; 总结 标准化工作 RFC文档的作用&#xff1a; 速率&#xff0c;带宽 有容量和速率的区别 带宽 吞吐量 时延&#xff0c;时延带宽积 1.发送时延&#xff1a; 2.传播时延&#xff1a; ​编辑 3.…

Vant组件库 引入 阿里矢量图 添加自己喜欢的 ICON

&#x1f4c3;目录跳转一.矢量图下载&#x1f4a8;使用CDN方式&#x1f389;下载本地&#xff08;推荐&#xff09;二.Vant引入Icon&#x1f5fa;️&#x1f383; 使用方式&#x1f680; 运行效果&#xff1a;一.矢量图下载 &#x1f4a8;使用CDN方式 当然你也可以使用官方的C…

【编程题】【Scratch三级】2021.12 分身术

分身术 1. 准备工作 (1)删除小猫角色、添加角色“Monkey”,Money位于舞台的中心; (2)添加背景Light; (3)新建变量“编号”。 2. 功能实现 (1)程序开始时,Monkey说:“我会分身术!变!!!”2秒; (2)每隔2秒克隆出一个位置随机、大小随机、颜色随机的Monke…

python easygui修改窗口位置

EasyGui是一个十分简单的Python图形界面库&#xff0c;支持窗口文本显示、图片显示、按钮、文本框、选项栏、文件选择等等必要的组件且操作十分简单。但也因如此&#xff0c;导致EasyGui甚至不能手动调整窗口位置、按钮位置、名字等&#xff0c;因为EasyGui是基于Tkinter编写的…

VMware三种网络模式详解

VMware三种网络模式 linux重启网络服务命令&#xff1a; service network restart 一、桥接模式 原理&#xff1a;VMware和宿主机&#xff0c;处于同一网段、两者地位平等。&#xff08;无需虚拟网卡&#xff09; 1.1、使用方法 虚拟网络编辑器 虚拟机设置-适配器 上面两…

<Linux> 编译器与调试器—gcc/g++/gdb 的使用

< Linux > 编译器与调试器—gcc/g/gdb 的使用 文章目录< Linux > 编译器与调试器—gcc/g/gdb 的使用一、Linux编译器 - gcc/g 使用1. 编译程序的四个过程背景知识预处理编译汇编链接2. 链接方式与函数库2.1 动态链接与静态链接2.2.函数库2.3.动态库与静态库3. gcc/…

干货分享:谷歌主动搜索开发客户的万能公式

大家在用谷歌(Google)开发是不是也有以下常见问题&#xff1a; 关键词不准&#xff0c;搜索到的都是零售商&#xff0c;B2C平台搜索到的客户太大&#xff0c;已经被开发多次&#xff0c;开发信不回复搜索到的客户找不到邮箱搜索到的客户与工厂不匹配&#xff0c;无法合作 其实…

车路协同 智能路侧设备网络安全接入技术要求

1 范围 本文件包含智能路侧设备网络安全接入技术要求&#xff0c;包括智能路侧设备连接要求、接入要求、证书管理要求。 本文件适用于智能路侧设备网络安全接入的设计与开发。 2 规范性引用文件 下列文件中的内容通过文中的规范性引用而构成本文件必不可少的条款。其中&…

Simulink永磁同步电机控制仿真:过调制及电流重构

在一些高功率密度的应用场景中&#xff0c;追求极致的电压利用率&#xff0c;这个时候要用到过调制技术&#xff1b;当svpwm工作在过调制区域时&#xff0c;逆变电桥会在一个基波周期内多次达到100%占空比&#xff0c;且较多时间处于较高的占空比&#xff0c;这个时候下桥臂电流…

数据结构系列学习(七) - 链栈(Chain_Stack)

目录 引言&#xff1a; 学习&#xff1a; 代码实现&#xff1a; 头文件&#xff08;Chain_Stack.h&#xff09;&#xff1a; 设置链栈中的元素范型&#xff1a; 链栈的结构体设计&#xff1a; 所有功能函数的声明&#xff1a; 源文件&#xff08;Chain_Stack.cpp&#…

性能测试场景设计之 阶梯性能场景(负载测试场景)

「负载测试&#xff1a;」 逐步增加并发用户数。看服务器的最大拐点区间在哪里。再缩小拐点区间&#xff0c;找出最大并发用户数。 使用方式&#xff1a; 安装 jpgc插件 添加线程组 每次递增10个并发 This group will start&#xff1a;给定当前负载的并发用户数First, wait …

机器学习-集成算法

文章目录集成算法1. 定义2. 具体模型2.1. Bagging2.2. Boosting2.3. Stacking3. 随机森林3.1. 树模型结构3.2. 随机森林的优点3.3. 分类与回归问题3.4. 树模型个数问题3.5. 参数问题(特征重要性)3.6. 可视化展示问题4. 集成基本思想4.1. 硬投票策略步骤4.2. 软投票策略步骤5. B…

【SpringMVC】基础、环境搭建、注解搭建、 and so on……

文章目录SpringMVC【原理】&#xff1a;一、why?&#xff1a;二、环境搭建&#xff08;配置方式&#xff09;&#xff1a;▶1.导入jar包▶2.创建简单测试----创建Controller类继承AbstractController▶3.如何读取Controller文件&#xff0c;创建SpringMVC.xml配置文件&#xf…

使用SPACEDESK时iPad显示Connected-Display OFF解决方法

使用SPACEDESK时iPad显示Connected-Display OFF1. SPACEDESK 概述2. 使用SPACEDESK时iPad显示Connected-Display OFF解决方法结束语1. SPACEDESK 概述 SPACEDESK 是一款网络显示多显示器软件&#xff0c;适用于电脑桌面复制&#xff08;镜像或克隆&#xff09;&#xff0c;能将…

[附源码]java毕业设计代驾服务系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…