嵌入式毕设分享:基于STM32的环境监测系统设计与实现

文章目录

  • 0 前言
  • 1 简介
  • 2 主要器件
  • 3 实现效果
  • 4 设计原理
  • 4.1 红外光电检测模块
  • 4.2 DHT11温湿度传感器
  • 4.3 光照传感器
  • 4.4 MQ-2烟雾传感器
  • 5 部分核心代码
  • 5 最后

  • 0 前言

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

    为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

    🚩 毕业设计 单片机Stm32环境监测系统

    🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:4分
  • 工作量:4分
  • 创新点:3分
  • 1 简介

    基于Stm32的环境监测系统,单片机检测温湿度,光照,烟雾浓度,并通过红外检测周围是否有人或者是否有遮挡,OLED液晶显示屏实时显示检测的数据,并通过蓝牙实时传输到手机上。

    2 主要器件

  • STM32F103C8T6主控芯片
  • DHT11温湿度模块
  • MQ2烟雾检测模块
  • 红外检测模块
  • 蓝牙模块
  • OLED屏
  • 光敏模块
  • 3 实现效果

    4 设计原理

    4.1 红外光电检测模块

    简介

    光电开关是一种具有开关量输出的位移传感器,输出有NPN、PNP、常开、常闭及继电器等,可检测金属(如钢、铁、铜)、塑料、玻璃、木头、水、纸、磁铁等透明和不透明物体,可与PLC、伺服控制器、变频器、计算器、控制器相连接达到自动输入信号的目的,广泛应用于机械、纺织、轻工造纸、印刷、包装等行业。

    光电开关属于无接触测量传感器,其检测距离范围比较宽,在计数、测距和行程控制等许多测控系统中得到广泛应用。反射式光电开关又分为漫反射和镜反射式光电开关
       

    工作原理
    漫反射光电开关是一种集发射器和接收器于一体的传感器,当有被检测物体经过时,将光电开关发射器发射的足够量的光线反射到接收器,于是光电开关就产生了开关信号。当被检测物体的表面光亮或其反光率极高时,漫反射式的光电开关是首选的检测模式。

    检测距离的调节
       

    4.2 DHT11温湿度传感器

    简介

    DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为 4 针单排引脚封装。连接方便,特殊封装形式可根据用户需求而提供。
    接线

    DHT11编码步骤

    1. 单片机上点后1s内不读取(不重要)
    2. 主机(单片机)发送起始信号:
    3. 主机先拉高data
    4. 拉低data延迟18ms
    5. 拉高data(通过此操作将单片机引脚设置为输入)。
    6. 从机(DHT11)收到起始信号后进行应答:
    7. 从机拉低data,主机读取到data线被拉低持续80us后从机拉高data线, 持续80us,直到高电平结束,意味着主机可以开始接受数据。
    8. 主机开始接收数据:
    9. 主机先把data线拉高(io设置为输入)
    10. 从机把data线拉低,主机读取data线电平,直到低电平结束(大约50us)
    11. 从机拉高data线后,延迟40us左右(28~70us之间)主机再次读取data线电平,如果为低电平,则为“0”,如果为高电平,则为“1”。
    12. 继续重复上述1,2步骤累计40次。

    4.3 光照传感器

    简介
    光敏传感器是最常见的传感器之一,它的种类繁多,主要有:光电管、光电倍增管、光敏电阻、光敏三极管、太阳能电池、红外线传感器、紫外线传感器、光纤式光电传感器、色彩传感器、CCD和CMOS图像传感器等。光传感器是目前产量最多、应用最广的传感器之一,它在自动控制和非电量电测技术中占有非常重要的地位。光敏传感器是利用光敏元件将光信号转换为电信号的传感器,它的敏感波长在可见光波长附近,包括红外线波长和紫外线波长。光传感器不只局限于对光的探测,它还可以作为探测元件组成其他传感器,对许多非电量进行检测,只要将这些非电量转换为光信号的变化即可。
    总结:照射光敏二极管的光强不同,通过光敏二极管的电流大小就不同,所以可以通过检测电流大小,达到检测光强的目的。利用这个电流变化,我们串接一个电阻,就可以转换成电压的变化,从而通过ADC读取电压值,判断外部光线的弱。

    优点

  • 采用灵敏型光敏电阻传感器
  • 比较器输出,信号干净,波形好,驱动能力超过15mA。
  • 配可调电位器可调节检测光线亮度
  • 工作电压3.3V-5V
  • 输出形式 :数字开关量输出(0和1)
  • 设有固定螺栓孔,方便安装
  • 原理图

    4.4 MQ-2烟雾传感器

    简介
    MQ-2常用于家庭和工厂的气体泄漏监测装置,适宜于液化气、苯、烷、酒精、氢气、烟雾等的探测。故因此,MQ-2可以准确来说是一个多种气体探测器。
    MQ-2的探测范围极其的广泛。它的优点:灵敏度高、响应快、稳定性好、寿命长、驱动电路简单。
    ![在这里插入图片描述](https://i3.wp.com/img-blog.csdnimg.cn/121d1a53127e460e9266beef04e4aa64.png#pic_center =500x#pic_center =500x)
    二、MQ-2的工作原理
    MQ-2型烟雾传感器属于二氧化锡半导体气敏材料,属于表面离子式N型半导体。处于200~300摄氏度时,二氧化锡吸附空气中的氧,形成氧的负离子吸附,使半导体中的电子密度减少,从而使其电阻值增加。当与烟雾接触时,如果晶粒间界处的势垒收到烟雾的调至而变化,就会引起表面导电率的变化。利用这一点就可以获得这种烟雾存在的信息,烟雾的浓度越大,导电率越大,输出电阻越低,则输出的模拟信号就越大。
    ![在这里插入图片描述](https://i3.wp.com/img-blog.csdnimg.cn/17c28e9c5598498e9707786cad8a7b67.png#pic_center =500x#pic_center =500x)

    MQ-2应用电路

    MQ-2常用的电路有两种,一种使用采用比较器电路监控,另一种为ADC电路检测。

    比较器电路
    ![在这里插入图片描述](https://i3.wp.com/img-blog.csdnimg.cn/9a6764e53c2047e8be40fcc7fb6a1603.png#pic_center =500x#pic_center =500x)
    MQ-2的4脚输出随烟雾浓度变化的直流信号,被加到比较器U1A的2脚,Rp构成比较器的门槛电压。当烟雾浓度较高输出电压高于门槛电压时,比较器输出低电平(0v),此时LED亮报警;当浓度降低传感器的输出电压低于门槛电压时,比较器翻转输出高电平(Vcc),LED熄灭。调节Rp,可以调节比较器的门槛电压,从而调节报警输出的灵敏度。
    R1串入传感器的加热回路,可以保护加热丝免受冷上电时的冲击。

    ADC转换电路
    MQ-2传感器另外一个采集方法为AD信号采集,即将电压信号转化为数字信号,进而转化为精确的烟雾浓度值。

    MQ-2传感器的4脚、6脚的电压为输出信号,Rs为传感器的本体电阻。其中若气体浓度上升,必导致Rs下降。而Rs的下降则会导致MQ-2的4脚、6脚对地输出的电压增大。所以气体浓度增大,其输出的电压也会增大,最终通过ADC0832转换后数值增大。

    5 部分核心代码

    //DHT11温湿度传感器部分
    #include "reg52.h"
    #include "LCD1602.h"
    #include "intrins.h"
    
    //typedef unsigned char uchar;
    //typedef unsigned int uint;
    	
    //定义变量
    sbit Data=P3^6;
    uchar rec_dat[13];//用于保存接收到的数据组
    
    void DHT11_delay_us(uchar n)
    {
        while(--n);
    }
    
    void DHT11_delay_ms(uint z)
    {
       uint i,j;
       for(i=z;i>0;i--)
          for(j=110;j>0;j--);
    }
    
    void DHT11_start()
    {
       Data=1;
       DHT11_delay_us(2);
       Data=0;
       DHT11_delay_ms(20);   //延时18ms以上
       Data=1;
       DHT11_delay_us(30);
    }
    
    uchar DHT11_rec_byte()      //接收一个字节
    {
       uchar i,dat=0;
      for(i=0;i<8;i++)    //从高到低依次接收8位数据
       {          
          while(!Data);   //等待50us低电平过去
          DHT11_delay_us(8);     //延时60us,如果还为高则数据为1,否则为0 
          dat<<=1;           //移位使正确接收8位数据,数据为0时直接移位
          if(Data==1)    //数据为1时,使dat加1来接收数据1
             dat+=1;
          while(Data);  //等待数据线拉低    
        }  
        return dat;
    }
    
    void DHT11_receive()      //接收40位的数据
    {
        uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise; 
        DHT11_start();
        if(Data==0)
        {
            while(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/10+'0';
            rec_dat[1]=(RH%10)+'0';
    		rec_dat[2]='%';
            rec_dat[3]='R';
            rec_dat[4]='H';
            rec_dat[5]=' ';
    		rec_dat[6]=' ';
            rec_dat[7]=(TH/10)+'0';
            rec_dat[8]=(TH%10)+'0';
    		rec_dat[9]='^';
            rec_dat[10]='C';
        }
    }
    
    void main()
    {
    	//使用lcd1602显示数据
    	DHT11_receive();
    	lcd1602(rec_dat);
    }
    
    
    
    /*******************************************************************************
    * 函 数 名         : DS18B20_Start
    * 函数功能		   : 开始温度转换
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    void DS18B20_Start(void)// ds1820 start convert
    {   						               
        DS18B20_Reset();	   
    	DS18B20_Check();	 
        DS18B20_Write_Byte(0xcc);// skip rom
        DS18B20_Write_Byte(0x44);// convert
    } 
    /*******************************************************************************
    * 函 数 名         : DS18B20_Init
    * 函数功能		   : 初始化DS18B20的IO口 DQ 同时检测DS的存在
    * 输    入         : 无
    * 输    出         : 1:不存在,0:存在
    *******************************************************************************/   	 
    u8 DS18B20_Init(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStructure;
    	RCC_APB2PeriphClockCmd(DS18B20_PORT_RCC,ENABLE);
    	GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    	GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);
     
     	DS18B20_Reset();
    	return DS18B20_Check();
    }  
    /*******************************************************************************
    * 函 数 名         : DS18B20_GetTemperture
    * 函数功能		   : 从ds18b20得到温度值
    * 输    入         : 无
    * 输    出         : 温度数据
    *******************************************************************************/ 
    float DS18B20_GetTemperture(void)
    {
        u16 temp;
    	u8 a,b;
    	float value;
        DS18B20_Start();                    // ds1820 start convert
        DS18B20_Reset();
        DS18B20_Check();	 
        DS18B20_Write_Byte(0xcc);// skip rom
        DS18B20_Write_Byte(0xbe);// convert	    
        a=DS18B20_Read_Byte(); // LSB   
        b=DS18B20_Read_Byte(); // MSB   
    	temp=b;
    	temp=(temp<<8)+a;
        if((temp&0xf800)==0xf800)
    	{
    		temp=(~temp)+1;
    		value=temp*(-0.0625);
    	}
    	else
    	{
    		value=temp*0.0625;	
    	}
    	return value;    
    
    
    
    // MQ-2烟雾传感器
    
    unsigned char GetYanWuValue(void)
    {
    		unsigned int sum=0;
    		unsigned char m,value=0;
    		for(m=0;m<20;m++)			//读50次AD值
    			sum = adc0832(0)+sum;		//读到的AD值,将读到的数据累加到sum
    		value=(unsigned char)(sum/20);				//跳出上面的for循环后,将累加的总数除以50得到平均值value
    	
    		if(value > ADC_Zero) 
    				value = value - ADC_Zero;              //首先减去零点漂移
    			else
    				value = 0;
    	
    		return value;
    
    }
    
    
    

    5 最后

    物联沃分享整理
    物联沃-IOTWORD物联网 » 嵌入式毕设分享:基于STM32的环境监测系统设计与实现

    发表评论