当前位置: 首页 > article >正文

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  int
typedef 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;  				//DHT11
sbit 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修正补偿	
}


//延时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);	 
				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


http://www.kler.cn/a/420165.html

相关文章:

  • Cannot resolve symbol ‘ActivityThread‘ | Android 语法
  • Qt 5 中的 QTextStream 使用指南
  • wordpress网站首页底部栏显示网站备案信息
  • 【AI系统】Ascend C 语法扩展
  • 设计模式 更新ing
  • ubuntu 和windows时区设置和时间修改
  • Linux学习笔记13 系统进程管理
  • Javaweb梳理20——Tomcat
  • 创建一个vue前端项目
  • float globalMapVIsualizationLeafSize; 的中文意思是什么
  • leetcode——移除数组
  • 关于开设人工智能教育的培训笔记
  • 如何确保爬虫程序的稳定性和效率:Java爬虫实践
  • 兔子繁衍问题
  • 今天我们来聊聊Maven中两个高级的概念—— 插件和目标
  • SprinBoot整合KafKa的使用(详解)
  • 编译器优化技术
  • 【工具变量】上市公司企业金融错配程度数据(1999-2022年)
  • MySQL查看日志
  • 16asm - 汇编介绍 和 debug使用
  • transformers gpt2 语言模型
  • Java与AWS S3的文件操作
  • spring boot+jpa接入达梦数据库
  • 《只狼》运行时提示“mfc140u.dll文件缺失”是什么原因?“找不到mfc140u.dll文件”要怎么解决?教你几招轻松搞定
  • Spring源码导入idea时gradle构建慢问题
  • 初识QT第一天