52 基于单片机的超声波、温湿度、光照检测分阶段报警

目录

一、主要功能

二、硬件资源

三、程序编程

四、实现现象


一、主要功能

1.通过DHT11模块读取环境温度和湿度:
2.将湿度、障碍物距显示在lcd1602上面,第一行显示温度和湿度,格式为:xx°Cyy%,第二行显示超声波传感器测得的距离,格式为:Distance: zzz CM:
3.判断距离是否超过设定阈值,默认阈值为150cm,当测得距离低于150cm时,蜂鸣器长鸣,LED1(黄灯)闪烁,直至恢复安全距离以上:当湿度大于65%时,蜂鸣器间断报警(需与刚才报警声有明显区别),不对LED1进行操作,如果距离和湿度两个同时满足报警条件时,距离报警优先。
4.LDR模块用于检测环境光亮度,将光敏电阳模拟信号通过ADC0832转换为数字信号传递给单片机,当亮度低于50时自动打开LED2(红色)常亮。
5.设置模块,由三个按键组成,用于修改距离阈值,当点击按键1时进入阈值设置模式,进入设置模式后点击按键2增大阈值,点击按键了减小阈值,每次变化幅度为1,lcd显示实时显示设置情况,Set Distance:sss CM,当设置完毕再次点击按键1会退出设置模式并保存刚才设定的闽值,lcd恢复原来的显示内容

二、硬件资源

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

编辑

三、程序编程

复制代码
#include <REGX52.H>#include <intrins.h>#include <stdio.h>#include "Delay.h"#include "LCD1602.h"#define uchar unsigned char#define uint unsigned  inttypedef unsigned char u8;typedef unsigned int  u16;typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;
sbit CS=P1^0;      
sbit CLK=P1^1;
sbit DIO=P1^2;
sbit Tr=P3^5;//触发信号sbit Ec=P3^6;//回响信号sbit Temp_data=P2^6;  				//DHT11sbit beep = P1^3;
sbit key1 = P1^4;
sbit key2 = P1^5;
sbit key3 = P1^6;
sbit led = P3^7;static int jlyz = 150;
uchar Recv_Buffer\[4\];
uint Voltage\[\]={'0','0','0','0'};
bit bdata IIC\_ERROR;unsigned int distance;unsigned int Read\_value(void);//读值函数static double u;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 int wd,sd;static int flag1=0,flag2=0,flag = 0;static int ymflag=0;static int flag3=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 Delay10us(void);//10us延时函数void display();void canshu();void ajpd();void Time0_Init()          //定时器初始化{
    TMOD = 0x21;
    TH0 = 0x00;
    TL0 = 0x00;
    TR0 = 0;//先关闭定时器0}void Time0_Int() interrupt 1 //中断程序{
   TH0  = 0xfe;             //重新赋值
   TL0  = 0x33;
}unsigned int Read_value(){
	uint result;
	Tr=1;//触发引脚发出11us的触发信号(至少10us)
	Delay10us();
	Tr=0;	while(!Ec);//度过回响信号的低电平
	TR0=1;//开启定时器0
	while(Ec);//度过回响信号高电平
	TR0=0;//关闭定时器0
	result=((TH0\*256+TL0)\*0.034)/2;		// 距离cm=(时间us * 速度cm/us)/2
	return result + 2;	//+2修正补偿	}//延时msvoid 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+5usvoid 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);	 
				sd = rec\_dat\[1\]*10 + rec\_dat\[0\];
				wd = rec\_dat\[3\]*10 + rec\_dat\[2\];
}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(distance < jlyz)
	{
		flag1 = 1;
	}	else
	{
		flag1 = 2;
	}	
	if(sd > 65)
	{
		flag2 = 3;
	}	else
	{
		flag2 = 4;
	}
	
	flag = flag1 * flag2;	if(flag == 3 || flag == 4)
	{
		beep =~ beep;		Delay(500);
	}	else if(flag == 6)
	{
		beep =~ beep;		Delay(100);
	}	else if(flag == 8)
	{
		beep = 1;
	}	
	if(u>=50)
	{
		led = 0;
	}	else
	{
		led = 1;
	}
}void main()					  //主函数{	
	Tr=0;               //出发引脚首先拉低
	LCD_Init();         //显示屏初始化
	Time0_Init();	   //定时初始化
	beep = 1;
	led = 0;	while(1)
	{		canshu();  //参数获取
		display();  //显示
		beep_warning();//报警
		ajpd();  //按键判断

	}
}void ajpd(){	if(key1==0)
	{		Delay(100);		if(key1 == 0)
		{			LCD_Init();         //显示屏初始化
			ymflag++;			if(ymflag>1)
			{
				ymflag = 0;
			}
		}
	}	if(key2==0)
	{		Delay(100);		if(key2 == 0)
		{
			jlyz++;
		}
	}	
	if(key3==0)
	{		Delay(100);		if(key3 == 0)
		{
			jlyz--;
		}
	}
}void canshu() {
	distance = Read_value();//读值
	distance+=12;	 dht11(); //温湿度获取
   u=get\_AD\_Res();
	 u = (u/177)*50;
   
}void display(){	if(ymflag == 0)
	{	  LCD_ShowNum(2,10,distance,3); //显示距离
	  LCD\_ShowNum(1,1,wd,2);	  LCD\_ShowNum(1,7,sd,2);
		flag3 = 0;
	}	else if(ymflag == 1)
	{		LCD_ShowNum(2,1,jlyz,3); //显示距离
		flag3 = 1;
	}	
	if(flag3 == 0)
	{	LCD_ShowString(2,1,"Distance:"); //显示字符串Distance
	LCD_ShowString(2,14,"CM"); //显示字符串Distance
	LCD_ShowString(1,3,"C"); //显示字符串Distance
		LCD_ShowString(1,9,"%"); //显示字符串Distance
		flag3 = 2;
	}	else if (flag3 == 1)
	{		LCD_ShowString(1,1,"SetDistance"); //显示字符串Distance
		LCD_ShowString(2,4,"CM");
		flag3 = 2;
	}
}	
//	void Delay10us(){
	TL0=0xF5;
	TH0=0xFF;
	TR0=1;	while (TF0==0);
	TR0=0;
	TF0=0;
}

四、实现现象

具体动态效果看B站演示视频:

基于单片机的超声波、温湿度、光照检测分阶段报警_哔哩哔哩_bilibili

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

http:// https://pan.baidu.com/s/1nZjWADtV0UnN-OcZPSpc1Q?pwd=rqn5

相关推荐
该用户已不存在21 分钟前
MySQL 与 PostgreSQL,该怎么选?
数据库·mysql·postgresql
GoldenaArcher42 分钟前
GraphQL 工程化篇 III:引入 Prisma 与数据库接入
数据库·后端·graphql
川石课堂软件测试44 分钟前
自动化测试之 Cucumber 工具
数据库·功能测试·网络协议·测试工具·mysql·单元测试·prometheus
RestCloud1 小时前
StarRocks 数据分析加速:ETL 如何实现实时同步与高效查询
数据库
我先去打把游戏先1 小时前
VSCode通过SSH连接到Ubuntu虚拟机失败“找不到ssh安装”问题解决
笔记·vscode·单片机·嵌入式硬件·学习·ubuntu·ssh
野猪亨利6672 小时前
Qt day1
开发语言·数据库·qt
本就一无所有 何惧重新开始2 小时前
Redis技术应用
java·数据库·spring boot·redis·后端·缓存
isaki1372 小时前
qt day1
开发语言·数据库·qt
流星白龙2 小时前
【Qt】4.项目文件解析
开发语言·数据库·qt
小钻风33662 小时前
HTTPS是如何确保安全的
网络·数据库