67 基于单片机的温湿度、烟雾、阈值切换、状态灯、串口收发

所有仿真详情导航:

PROTEUS专栏说明-CSDN博客

目录

一、主要功能

二、硬件资源

三、主程序编程

四、资源下载


一、主要功能

基于51单片机,采用DHT11温湿度传感器检测温湿度,采用滑动变阻器连接ADC0832数模转换器模拟烟雾传感器,通过LCD1602显示温度 湿度 烟雾的值,温度初始范围是26-38,湿度阈值范初始范围60-80,烟雾初始阈值100,然后三个按键,一个切换,两个负责增减阈值,按下切换键后LCD1602进入阈值设置页面,首先是温度上限,然后是温度下限,湿度上限,湿度下限,浓度上限,最后切换回实时显示温湿度页面。加五个LED灯,分别是温度过高,过低,湿度过高,湿度过低,浓度过高指示灯。然后如果温度高于阈值,湿度低于阈值,并且浓度高于阈值的这种情况,继电器吸合电机转动,蜂鸣器报警。
加个按键切换模式,手动模式下,电脑串口发送0x01控制单片机继电器吸合
发送0x02,控制单片机继电器断开。

具体动态效果看B站演示视频(高清需要跳转到B站看)

基于单片机的温湿度、烟雾、阈值切换、状态灯、串口收发_哔哩哔哩_bilibili

二、硬件资源

基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。

三、主程序编程

cpp 复制代码
#include <REGX52.H>
#include <intrins.h>
#include <stdio.h>
#include "Delay.h"
#include "LCD1602.h"
#define uchar unsigned char
#define uint unsigned  int
sbit CS=P1^0;                 //adc0832引脚
sbit CLK=P1^1;
sbit DIO=P1^2;
sbit wdled_high = P1^3;
sbit wdled_low  = P1^4;
sbit sdled_high = P1^5;
sbit sdled_low  = P1^6;
sbit ndled_high = P1^7;
sbit beep=P3^4;
sbit key1=P3^7; // 切换
sbit key3=P3^5; // 减少
sbit key2=P3^6; // 增加
sbit key4=P2^7;
sbit jdq = P3^3;//继电器
sbit Temp_data=P2^6;  //DHT11


unsigned char rec_dat_lcd0[6];
unsigned char rec_dat_lcd1[6];
unsigned char rec_dat_lcd2[6];
unsigned char rec_dat_lcd3[6];
unsigned int rec_dat[4];
static uchar u;      //定义变量
int mode=0;
static char Dat_rxd;
static uchar wd,sd;
static int wdsx=38,wdxx=26,sdsx=80,sdxx=60,ndsx=100;
static int flag=0;


void DHT11_delay_us(unsigned char n);
void DHT11_delay_ms(unsigned int z);
void DHT11_start();
unsigned char DHT11_rec_byte();
void DHT11_receive();
void beep_warning();
void cshq();
void xxpxs();
void ajjc();

//延时ms
void DHT11_delay_ms(unsigned int z)
{
    unsigned int i,j;
    for(i=z; i>0; i--)
        for(j=110; j>0; j--);
}

//延时us   --2*n+5us
void DHT11_delay_us(unsigned char n)
{
    while(--n);
}

//DHT11起始信号
void DHT11_start()
{
    Temp_data=1;

    DHT11_delay_us(10);

    Temp_data=0;

    DHT11_delay_ms(50);//这个延时不能过短,18ms以上,实际在仿真当中要想读到数据延时要在延时参数要在40以上才能出数据

    Temp_data=1;

    DHT11_delay_us(30);//这个延时不能过短


}

//接收一个字节

unsigned char DHT11_rec_byte()
{
    unsigned char i,dat=0;
    for(i=0; i<8; i++)
    {
        while(!Temp_data);
        DHT11_delay_us(8);
        dat <<=1;
        if(Temp_data==1)
        {
            dat +=1;
        }
        while(Temp_data);
    }
    return dat;
}



//接收温湿度数据
void DHT11_receive()
{
    unsigned int R_H,R_L,T_H,T_L;
    unsigned char RH,RL,TH,TL,revise;

    DHT11_start();
    Temp_data=1;
    if(Temp_data==0)
    {
        while(Temp_data==0);   //等待拉高
        DHT11_delay_us(40);  //拉高后延时80us

        R_H=DHT11_rec_byte();    //接收湿度高八位
        R_L=DHT11_rec_byte();    //接收湿度低八位
        T_H=DHT11_rec_byte();    //接收温度高八位
        T_L=DHT11_rec_byte();    //接收温度低八位
        revise=DHT11_rec_byte(); //接收校正位

        DHT11_delay_us(25);    //结束

        if((R_H+R_L+T_H+T_L)==revise)      //校正
        {
            RH=R_H;
            RL=R_L;
            TH=T_H;
            TL=T_L;

        }
        /*数据处理,方便显示*/
        rec_dat[0]=RH;
        rec_dat[1]=RL;
        rec_dat[2]=TH;
        rec_dat[3]=TL;

    }

}

void dht11()
{
	      DHT11_delay_ms(150);
        DHT11_receive();
	      sprintf(rec_dat_lcd0,"%d",rec_dat[0]);
        sprintf(rec_dat_lcd1,"%d",rec_dat[1]);
        sprintf(rec_dat_lcd2,"%d",rec_dat[2]);
        sprintf(rec_dat_lcd3,"%d",rec_dat[3]);
        DHT11_delay_ms(100);
	
	      wd = rec_dat[3]*10 + rec_dat[2];
				sd = rec_dat[1]*10 + rec_dat[0];

}

uchar get_AD_Res()            //ADC0832启动读取函数
{
	uchar i, data1=0, data2=0;
	CS=0;
	
	CLK=0;DIO=1;_nop_();
	CLK=1;_nop_();
	
	CLK=0;DIO=1;_nop_(); 
	CLK=1;_nop_();
	
	CLK=0;DIO=0;_nop_();
	CLK=1;_nop_();
	
	CLK=0;DIO=1;_nop_(); 
	
	for(i=0; i<8; i++)
	{
		CLK=1;_nop_();
		CLK=0;_nop_();
		data1=(data1<<1)|(uchar)DIO; 
	}
	
	for(i=0; i<8; i++)
	{
		data2=data2|(uchar)DIO<<i;
		CLK=1;_nop_();
		CLK=0;_nop_();
	}
	CS=1;
	
	return(data1 == data2)?data1:0;
}
void beep_warning()//蜂鸣器警报并且电机转动
{
	if(wd>=wdxx && wd<=wdsx)
	{
		wdled_high = 1;
		wdled_low  = 1;
	}
	if(wd>wdsx)
	{
		wdled_high = 0;
	}
	if(wd<wdxx)
	{
		wdled_low = 0;
	}
	
	if(sd>=sdxx && sd<=sdsx)
	{
		sdled_high = 1;
		sdled_low  = 1;
	}
	if(sd>sdsx)
	{
		sdled_high = 0;
	}
	if(sd<sdxx)
	{
		sdled_low = 0;
	}
	
	if(u>ndsx)
	{
		ndled_high = 0;
	}
	else
	{
		ndled_high = 1;
	}
	
	if(wd>wdsx  && sd < sdxx  && u>ndsx)
	{
		jdq = 0;
		beep = 1;
	}
	else
	{
		jdq = 1;
		beep = 0;
	}
}


void Com0_Init(void)
{
	  EA = 1;
    ES=1;        //允许串口中断
    TMOD=0x21;   //定时器T1,在方式3中断产生波特率
    SCON=0x50;
    TH1=0xfd;    //波特率设置为9600(晶振12M)
    TL1=0xfd;
    TR1=1;       //开定时器T1运行控制位
}

void Com0(void) interrupt 4 using 1
{
    if(RI)
    {
        Dat_rxd=SBUF;                 //串口接收
        Dat_rxd=Dat_rxd-0x30;
        RI=0;
    }
}
void send_to_com(const char *msg)
{
    while(*msg)
    {
        SBUF = *msg;  // 发送数据
        while(!TI);   // 等待发送完成
        TI = 0;       // 清除发送完成标志位
        msg++;        // 指向下一个字符
    }
}

void send_int_to_com(int num) {
    char buffer[20]; // 假设最大整数位数不超过20
    sprintf(buffer, "%d", num); // 将整数转换为字符串
    send_to_com(buffer); // 发送字符串
}

void main()					  //主函数
{	
	Com0_Init();//串口初始化 
	LCD_Init();         //显示屏初始化
	beep = 0;
	jdq = 1;
	do
	{
		cshq();  //参数获取
		dht11(); //温湿度获取
		ajjc();   //按键检测
		xxpxs();  //显示屏显示
		send_to_com("温度=");
		send_int_to_com(wd);
		send_to_com("\r\n");
		
		send_to_com("湿度=");
		send_int_to_com(sd);
		send_to_com("\r\n");
		
		send_to_com("浓度=");
		send_int_to_com(u);
		send_to_com("\r\n");
		if(mode == 0)
		{
	  beep_warning();    //状态判断
		}
		else if(mode == 1)
		{
			if(Dat_rxd == 0x01)
				{ 
					jdq=0;
				}
				else if(Dat_rxd==0x02)
				{ 
					jdq=1;
				}
		}

	}  while(1);
}
void ajjc()  //按键检测
{
	if(!key1)
	{
		flag++;
	 LCD_Init();
		if(flag>5)
		{
			flag=0;
		}
		while(!key1);
	}
	
	if(!key4)
	{
		mode++;
		if(mode>1)
		{
			mode=0;
		}
		while(!key4);
	}
	
	if(!key2)
	{
		switch(flag)
		{
			case 0:break;
			case 1:wdsx++;break;
			case 2:wdxx++;break;
			case 3:sdsx++;break;
			case 4:sdxx++;break;
			case 5:ndsx++;break;
		}
		while(!key2);
	}
	
	if(!key3)
	{
		switch(flag)
		{
			case 0:break;
			case 1:wdsx--;break;
			case 2:wdxx--;break;
			case 3:sdsx--;break;
			case 4:sdxx--;break;
			case 5:ndsx--;break;
		}
		while(!key3);
	}
}
void xxpxs()  //显示屏显示
{
	if(mode == 0)
	{
	LCD_ShowString(1,15,"zd");
	}
	else
	{
	LCD_ShowString(1,15,"sd");
	}
	LCD_ShowNum(2,16,flag,1);
	switch(flag)
	{
		case 0:LCD_ShowString(1,1,"nd:");	
					LCD_ShowNum(1,4,u,3); 
					LCD_ShowString(2,1,"wd:");	
					LCD_ShowNum(2,4,wd,3);
					LCD_ShowString(2,8,"sd:");	
					LCD_ShowNum(2,11,sd,3);
		break;
		case 1:
					 LCD_ShowString(1,1,"wdxx:");
					 LCD_ShowNum(1,6,wdxx,3); 
					 LCD_ShowString(2,1,"wdsx:");
					 LCD_ShowNum(2,6,wdsx,3); 
		break;
		case 2:
					 LCD_ShowString(1,1,"wdxx:");
					 LCD_ShowNum(1,6,wdxx,3); 
					 LCD_ShowString(2,1,"wdsx:");
					 LCD_ShowNum(2,6,wdsx,3); 
		break;
		case 3:
				   LCD_ShowString(1,1,"sdxx:");
					 LCD_ShowNum(1,6,sdxx,3); 
					 LCD_ShowString(2,1,"sdsx:");
					 LCD_ShowNum(2,6,sdsx,3); 
		break;
		case 4:
			     LCD_ShowString(1,1,"sdxx:");
					 LCD_ShowNum(1,6,sdxx,3); 
					 LCD_ShowString(2,1,"sdsx:");
					 LCD_ShowNum(2,6,sdsx,3); 
		break;
		case 5:
			     LCD_ShowString(1,1,"ndsx:");
					 LCD_ShowNum(1,6,ndsx,3); 
					 LCD_ShowString(2,1,"        ");
		break;
	}

	
	
}
void cshq()  //参数获取
{
	  u=get_AD_Res();
}

四、资源下载

全部资料(源程序、仿真文件、安装包、演示视频):

链接: https://pan.baidu.com/s/19JUIfVYJc24vcu2DwKnILw?pwd=5nt5 提取码: 5nt5

--来自百度网盘超级会员v4的分享

相关推荐
hollq1 小时前
STM32F103RCT6+STM32CubeMX+keil5(MDK-ARM)+Flymcu实现串口重定向
arm开发·stm32·嵌入式硬件
小鱼儿电子2 小时前
17-基于STM32的宠物饲养系统设计与实现
stm32·嵌入式硬件·物联网·宠物·宠物饲养系统
小莞尔4 小时前
【51单片机】【protues仿真】基于51单片机四层电梯系统
单片机·嵌入式硬件
CFZPL4 小时前
使用江科大串口发送函数发送freertos的vTaskList出现跑飞
单片机
F133168929575 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·51单片机·硬件工程·pcb工艺
易享电子6 小时前
基于单片机电器断路器保护器系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus
爱倒腾的老唐8 小时前
01、如何学习单片机
单片机·嵌入式硬件·学习
点灯小铭8 小时前
基于单片机的夹具压力控制系统设计
单片机·嵌入式硬件·mongodb·毕业设计·课程设计
雾削木14 小时前
stm32解锁芯片
javascript·stm32·单片机·嵌入式硬件·gitee
璞致电子16 小时前
fpga开发板ZYNQ 璞致 PZ7010/7020 邮票孔核心板简介-ZYNQ7000系列小系统学习板
linux·嵌入式硬件·学习·fpga开发·fpga·fpga开发板·xilinx开发板