找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2634|回复: 2
收起左侧

修改好的单片机PM2.5+DHT11温湿度传感程序

[复制链接]
ID:377166 发表于 2021-5-14 15:09 | 显示全部楼层 |阅读模式
  1. #include <reg52.h>  //头文件
  2. #include "1602.h"
  3. #include "DHT11.h"
  4. #include <adc0832.h>
  5. #include <intrins.h>
  6. #include "eeprom52.h"
  7. #define uchar unsigned char  //定义字符类型
  8. #define uint  unsigned int

  9. typedef bit BOOL  ;
  10. sbit DQ=P1^5;    //DTH11
  11. sbit beep = P1^7; //蜂鸣器
  12. sbit LED = P1^6;  //粉尘传感器内部LED控制

  13. uchar FlagStart = 0;           //标志位           
  14. uint Counter;
  15. uint DUST_SET;                  //固体颗粒的阈值
  16. uchar ADC_Get[10]={0};           //定义AD采样数组
  17. uchar num=0;       //定义的变量,采集一段时间内的值
  18. uchar time1=0;     //定义的时间变量,用于温湿度处理显示
  19. uchar time2=0;     //定义的时间变量,开机报警功能等待温度湿度PM2.5数据处理完成再启动,避免蜂鸣器开机就乱叫。
  20. uint DUST;       //定义的PM2.5的值
  21. uint   DUST_Value;    //定义的PM2.5的值
  22. uchar GetADVal(uchar);
  23. uchar RH,TH;
  24. uint num1,num2,Temp_H,Temp_L,Humi_H,Humi_L,s_dengji;  //定义的报警值,参数具有断电保存功能,仅支持STC单片机
  25. uchar yemian=0;  //定义的页面标志
  26. uchar flat=1;     //定义的判断标志


  27. sbit K1=P3^2;  //按键定义
  28. sbit K2=P3^3;
  29. sbit K3=P3^4;

  30. void  Delay_10us(void)
  31. {
  32.   uchar i;
  33.    i--;
  34.    i--;
  35.    i--;
  36.    i--;
  37.    i--;
  38. }

  39. /***********************1ms延时函数*****************************/
  40. void delay_1ms(uint q)
  41. {
  42.         uint i,j;
  43.         for(i=0;i<q;i++)
  44.                 for(j=0;j<120;j++);
  45. }

  46. /******************把数据保存到单片机内部eeprom中******************/
  47. void write_eeprom()
  48. {
  49.   num1=s_dengji/256;  //因为eeprom每个区间最大存放256个字节,当大于要分开存储
  50.         num2=s_dengji%256;
  51.         SectorErase(0x2000);
  52.         byte_write(0x2001,  num1);
  53.         byte_write(0x2002,  num2);
  54.         byte_write(0x2003,  Temp_H);
  55.         byte_write(0x2004,  Temp_L);
  56.         byte_write(0x2005,  Humi_H);
  57.         byte_write(0x2006,  Humi_L);
  58.        
  59.         byte_write(0x2060, a_a);       
  60. }

  61. /******************把数据从单片机内部eeprom中读出来*****************/
  62. void read_eeprom()
  63. {
  64.         num1   = byte_read(0x2001);
  65.         num2   = byte_read(0x2002);
  66.         Temp_H   = byte_read(0x2003);
  67.         Temp_L  = byte_read(0x2004);
  68.         Humi_H   = byte_read(0x2005);
  69.         Humi_L   = byte_read(0x2006);
  70.         a_a    = byte_read(0x2060);

  71.         s_dengji= num1*256+num2;
  72. }

  73. /**************开机自检eeprom初始化*****************/
  74. void init_eeprom()
  75. {
  76.         read_eeprom();                //先读
  77.         if(a_a != 2)                //新的单片机初始单片机内问eeprom
  78.         {
  79.                  num1=200/256;
  80.      num2=200%256;
  81.                 Temp_H   = 35;
  82.           Temp_L  = 5;
  83.           Humi_H   = 80;
  84.           Humi_L   = 10;
  85.                 a_a = 2;
  86.                 write_eeprom();
  87.         }       
  88. }
  89.         //**************************延时函数
  90. void delay_ms2(uint z)
  91. {
  92. uint x,y;
  93. for(x=z;x>0;x--)
  94.   for(y=114;y>0;y--);
  95. }

  96. //**************************初始化DTH11***********************/
  97. bit Init_DTH11()
  98. {
  99. bit flag;
  100. uchar num;
  101. DQ=0;
  102. delay_ms2(19);   // >18ms
  103. DQ=1;
  104. for(num=0;num<10;num++);   // 20-40us    34.7us
  105. for(num=0;num<12;num++);
  106. flag=DQ;
  107. for(num=0;num<11;num++); //DTH响应80us
  108. for(num=0;num<24;num++);    //DTH拉高80us
  109. return flag;
  110. }
  111. //****************************读DTH11数据
  112. uchar DTH11_RD_CHAR()
  113. {
  114. uchar byte=0;
  115. uchar num;
  116. uchar num1;
  117. while(DQ==1);
  118. for(num1=0;num1<8;num1++)
  119. {
  120.   while(DQ==0);
  121.   byte<<=1;     //高位在前
  122.   for(num=0;DQ==1;num++);
  123.   if(num<10)
  124.    byte|=0x00;
  125.   else
  126.    byte|=0x01;
  127. }
  128. return byte;
  129. }
  130. //******************************读取DTH11温度和湿度
  131. void  DTH11_DUSHU()
  132. {
  133. uchar num;
  134. if(Init_DTH11()==0)
  135. {
  136.   RH=DTH11_RD_CHAR();   //
  137.   DTH11_RD_CHAR();
  138.   TH=DTH11_RD_CHAR();
  139.   DTH11_RD_CHAR();
  140.   DTH11_RD_CHAR();
  141.   for(num=0;num<17;num++);  //最后BIT输出后拉低总线50us
  142.   DQ=1;
  143. }
  144. }
  145. ///////////////////////////////////////////////////////////////////////////

  146. //DS---185页  定时器初始化 定时10ms
  147. void Timer0_Init()
  148. {
  149.        
  150. //AUXR=0x80; //Time work in 1T mode      
  151.         TMOD= 0x01;     
  152.         TL0 = (65536-30000)/256;     
  153.         TH0 = (65536-30000)%256;   
  154.         TR0 = 1;
  155.         ET0 = 1;  
  156.   
  157.         EX0 = 1;  //开外部中断0
  158.         IT0 = 0;  //电平触发        
  159.         EA = 1;     
  160. }

  161. //定时器0中断
  162. void Timer0_ISR (void) interrupt 1 using 0
  163. {
  164.   uint i,j;       
  165.         TL0 = (65536-30000)/256;     
  166.         TH0 = (65536-30000)%256;   
  167.            
  168.          LED=0;                                 //开启传感器的LED
  169.          for (j=0;j<30;j++);  //0.28ms  //延时0.28ms
  170.    ADC_Get[num]=Get_AD_Result();          //开启ADC采集
  171.          
  172.          num++;
  173.         if(num>10)
  174.         {
  175.           FlagStart=1;
  176.           num=0;
  177.           TR0 = 0;   //先关闭定时器0

  178.         }                                                   //采集10次,关闭定时器0,进行数据处理
  179.      
  180.                                                            //关闭传感器LED
  181.         LED=1;
  182.        
  183. }







  184. //中值滤波
  185. //算法:先进行排序,然后将数组的中间值作为当前值返回。
  186. uchar Error_Correct(uchar *str,uchar num)
  187. {
  188.    unsigned char i=0;
  189.    unsigned char j=0;
  190.    uchar Temp=0;
  191.    
  192.    //排序
  193.    for(i=0;i<num-1;i++)
  194.      {
  195.           for(j=i+1;j<num;j++)
  196.            {
  197.              if(str[i]<str[j])
  198.                    {
  199.                    Temp=str[i];
  200.                    str[i]=str[j];
  201.                    str[j]=Temp;
  202.                
  203.                 }
  204.           
  205.            }
  206.         }
  207.     //去除误差,取中间值
  208.     return str[num/2];

  209. }

  210. void wenshidu()  //温湿度处理函数
  211. {  
  212.     time1++;
  213.    if(time1>=5)  //避免液晶快速刷新显示
  214.          {                 
  215.           EA=0;
  216.                 time1=0;
  217.     DTH11_DUSHU();
  218.                 DTH11_DUSHU();
  219.           EA=1;
  220.           LCD_Show2(2,1,TH);  //温度实时显示
  221.           LCD_Show2(11,1,RH);  //湿度实时显示
  222.                 LCD_Show3(6,0,DUST); //PM2.5的值实时显示
  223.          }

  224. }

  225. void voice() //按键提示音
  226. {
  227.   beep = 0;  //打开蜂鸣器
  228.         delay_1ms(30);  //短暂延时
  229.         beep = 1;  //关闭蜂鸣器
  230. }


  231. void Outside_Int1(void) interrupt 0        using 1   //打开外部中断处理函数  优点,进入设置界面可以快速响应,避免长时间等待
  232. {
  233.          if(K1==0 && K2==1 && K3==1 )
  234.                    {  
  235.                            delay_1ms(20);
  236.                            if(K1==0 && K2==1 && K3==1)
  237.                         {   
  238.                                       while(K1==0 && K2==1 && K3==1)
  239.                                       ;
  240.                                                  num=11;
  241.              yemian++;
  242.                                                        
  243.              if(yemian>=6) { yemian=0; flat=1;}  
  244.              voice(); //提示音
  245.             }
  246.                    }
  247. }

  248. void key()  //对里面的数值进行修改
  249. {
  250.       if(K1==0 && K2==1 && K3==1 )
  251.                    {  
  252.                            delay_1ms(20);
  253.                            if(K1==0 && K2==1 && K3==1)
  254.                         {   
  255.                                       while(K1==0 && K2==1 && K3==1)
  256.                                       ;
  257.                                                  TR0 = 0;   
  258.              yemian++;
  259.              if(yemian>=6) { yemian=0; flat=1;}  
  260.                                                  voice(); //提示音
  261.             }
  262.                    }
  263.                          
  264.                         if(K1==1 && K2==0 && K3==0) //长按5秒,K2和K3按键,系统设置值恢复初始值
  265.                    {  
  266.                            delay_1ms(20);
  267.                            if(K1==1 && K2==0 && K3==0)
  268.                         {   
  269.                                       while(K1==1 && K2==0 && K3==0)
  270.                                       ;
  271.                        s_dengji = 200;
  272.                        Temp_H   = 35;
  273.                  Temp_L  = 5;
  274.                  Humi_H   = 80;
  275.                  Humi_L   = 10;
  276.            write_eeprom();
  277.                                         beep = 0;
  278.                 delay_1ms(200);
  279.                 beep = 1;
  280.             }
  281.                    }
  282.                
  283. }

  284. void shezhi()         //独立按键程序
  285. {
  286. if(!K2)               //
  287.                   {
  288.                           delay_1ms(100);
  289.                                 if(!K2)
  290.                                 {
  291.           ;
  292.                                         if(yemian==1)  
  293.                                         {
  294.             if(s_dengji<999 ) { s_dengji++;}  //加1
  295.             LCD_Show3(5,1,s_dengji);
  296.           }
  297.                                        
  298.                                         if(yemian==2)  
  299.                                         {
  300.             if(Temp_H<99 ) { Temp_H++;}  //加1
  301.             LCD_Show2(7,1,Temp_H);
  302.           }
  303.                                        
  304.                                         if(yemian==3)  
  305.                                         {
  306.             if(Temp_L<99 ) { Temp_L ++;}  //加1
  307.             LCD_Show2(7,1,Temp_L);
  308.           }
  309.                                        
  310.                                         if(yemian==4)  
  311.                                         {
  312.             if(Humi_H<99 ) { Humi_H ++;}  //加1
  313.              LCD_Show2(7,1,Humi_H);
  314.           }
  315.                                        
  316.                                         if(yemian==5)  
  317.                                         {
  318.             if(Humi_L<99 ) { Humi_L ++;}  //加1
  319.             LCD_Show2(7,1,Humi_L);
  320.                                                
  321.           }
  322.                                  
  323.                 write_eeprom();       //保存数据
  324.           voice(); //提示音                                       
  325.                                 }
  326.                         }
  327.                        
  328. if(!K3)               //
  329.                   {
  330.                           delay_1ms(100);
  331.                                 if(!K3)
  332.                                 {
  333.           ;
  334.                                        
  335.                                 if(yemian==1)
  336.                                 {                                       
  337.                             if(s_dengji>1)  {  s_dengji--; }        //浓度设置数减1
  338.            LCD_Show3(5,1,s_dengji);
  339.         }
  340.                                
  341.                                 if(yemian==2)
  342.                                 {                                       
  343.                             if(Temp_H>1)  {  Temp_H--; }        //浓度设置数减1
  344.           LCD_Show2(7,1,Temp_H);
  345.         }
  346.                                
  347.                                 if(yemian==3)
  348.                                 {                                       
  349.                             if(Temp_L>1)  { Temp_L--; }        //浓度设置数减1
  350.            LCD_Show2(7,1,Temp_L);
  351.         }
  352.                                
  353.                                 if(yemian==4)
  354.                                 {                                       
  355.                             if(Humi_H>1)  {  Humi_H--; }        //浓度设置数减1
  356.           LCD_Show2(7,1,Humi_H);
  357.         }
  358.                                
  359.                                 if(yemian==5)
  360.                                 {                                       
  361.                             if(Humi_L>1)  {  Humi_L--; }        //浓度设置数减1
  362.           LCD_Show2(7,1,Humi_L);
  363.         }
  364.               write_eeprom();       //保存数据
  365.         voice(); //提示音                               
  366.                         }
  367.    }                       
  368. }

  369. //****************报警函数*************
  370. void baojing()
  371. {
  372.        
  373. if(DUST >= s_dengji || TH>=Temp_H || TH<=Temp_L || RH>=Humi_H || RH<=Humi_L )                //报警
  374.         {
  375.     beep = ~beep;          //蜂鸣器报警
  376.         }
  377.        
  378.         else
  379.         {
  380.           beep = 1;
  381.   }
  382. }


  383. void chengxu()  //主界面处理程序
  384. {
  385.   if(FlagStart==1)       //10次采集完成
  386.            {
  387.                    
  388.      DUST=Error_Correct(ADC_Get,10);                //求取10次AD采样的值
  389.            DUST_Value=(DUST/256.0)*5000-200;                //
  390.            DUST_Value=DUST_Value*0.32;
  391.            if(DUST_Value<0)              DUST_Value=0;
  392.            if(DUST_Value>999)         DUST_Value=999;        //限位
  393.            DUST=(uint)DUST_Value;                                         //
  394.      time2++;
  395.                  if(time2>5) //开机后程序运行5次再启动蜂鸣器功能
  396.                                    //开机报警功能等待温度湿度PM2.5数据处理完成再启动,避免蜂鸣器开机就乱叫。
  397.                  {
  398.                          time2=6;
  399.                          baojing();
  400.      }
  401.                
  402.      wenshidu();
  403.                 if(yemian==0)
  404.                 {                       
  405.     Delay_10us();  
  406.           TL0 = (65536-30000)/256;     
  407.           TH0 = (65536-30000)%256;
  408.           TR0 = 1;   //开启定时器0
  409.     FlagStart=0;
  410.                 }
  411.          }

  412. }





  413. void main()
  414. {   
  415.          init_eeprom();
  416.    LCD_Init();         //液晶初始化
  417.    LCD_Clear();//清屏
  418.    LCD_Write_String(4,0,"Welcome");
  419.    delay_ms(2000);
  420.    Timer0_Init();   //定时器0初始化
  421.   
  422. while(1)
  423.    {
  424.                  
  425.                  key();         //独立按键程序
  426.   //====================yemian==0时 进入工作状态=================================
  427.                          if(yemian==0)  
  428.                         {
  429.                                
  430.                                 if(flat==1)
  431.                                  {
  432.           flat=2;
  433.           LCD_Clear();//清屏
  434.           LCD_Write_String(0,0,"PM2.5:    ug/m3 ");
  435.           LCD_Write_String(0,1,"T:   C   H:  %RH");
  436.           LCD_Write_Char(4,1,0xdf);
  437.                                        
  438.                                         TL0 = (65536-30000)/256;     
  439.                 TH0 = (65536-30000)%256;
  440.                 TR0 = 1;   //开启定时器0
  441.                 EA = 1;
  442.          }

  443.                                   chengxu();//主界面处理程序
  444.         
  445.      }     
  446.           
  447. //====================yemian==1时 ======PM2.5报警值========================
  448.                          if(yemian==1)  
  449.                         {
  450.                                 if(flat==2)
  451.                                  {
  452.           flat=3;
  453.           beep = 1;
  454.                                         TR0 = 0;   //
  455.                                         EA=0;
  456.                                   LCD_Clear();//清屏
  457.           LCD_Write_String(0,0,"    Set PM2.5   ");
  458.           LCD_Write_String(0,1,"        ug/m3   ");
  459.          }
  460.                             shezhi() ;
  461.                                   LCD_Show3(5,1,s_dengji);
  462.                                
  463.        }               
  464.                          
  465. //====================yemian==2时 温度上限==============================
  466.                          if(yemian==2)  
  467.                         {
  468.                                 if(flat==3)
  469.                                  {
  470.           flat=4;
  471.           beep = 1;
  472.                                         TR0 = 0;   //
  473.                                         EA=0;
  474.                                   LCD_Clear();//清屏
  475.           LCD_Write_String(0,0,"   Set Temp_H   ");
  476.           LCD_Write_String(0,1,"          C     ");
  477.                                         LCD_Write_Char(9,1,0xdf);
  478.          }
  479.                             shezhi() ;
  480.                                   LCD_Show2(7,1,Temp_H);
  481.                                
  482.        }               
  483.           
  484. //====================yemian==3时 温度下限==============================
  485.                          if(yemian==3)  
  486.                         {
  487.                                 if(flat==4)
  488.                                  {
  489.           flat=5;
  490.           beep = 1;
  491.                                         TR0 = 0;   //
  492.                                         EA=0;
  493.                                   LCD_Clear();//清屏
  494.           LCD_Write_String(0,0,"   Set Temp_L   ");
  495.           LCD_Write_String(0,1,"          C     ");
  496.                                         LCD_Write_Char(9,1,0xdf);
  497.          }
  498.                             shezhi() ;
  499.                                   LCD_Show2(7,1,Temp_L);
  500.                                
  501.        }       

  502. //====================yemian==4时 湿度上限==============================
  503.                          if(yemian==4)  
  504.                         {
  505.                                 if(flat==5)
  506.                                  {
  507.           flat=6;
  508.           beep = 1;
  509.                                          TR0 = 0;   //
  510.                                         EA=0;
  511.                                   LCD_Clear();//清屏
  512.           LCD_Write_String(0,0,"   Set Humi_H   ");
  513.           LCD_Write_String(0,1,"         %      ");
  514.                                
  515.          }
  516.                             shezhi() ;
  517.                                   LCD_Show2(7,1,Humi_H);
  518.                                
  519.        }                         

  520. //====================yemian==5时 湿度下限==============================
  521.                          if(yemian==5)  
  522.                         {
  523.                                 if(flat==6)
  524.                                  {
  525.           flat=1;
  526.           beep = 1;
  527.                                         TR0 = 0;   //
  528.                                         EA=0;
  529.                                   LCD_Clear();//清屏
  530.           LCD_Write_String(0,0,"   Set Humi_L   ");
  531.           LCD_Write_String(0,1,"         %      ");
  532.          }
  533.                             shezhi() ;
  534.                                   LCD_Show2(7,1,Humi_L);
  535.      }               
  536.    
  537.   }
  538.    
  539. }
复制代码

51hei.png

以上代码下载: PM2.5+温湿度程序.rar (86.7 KB, 下载次数: 45)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1012237 发表于 2022-3-26 16:42 | 显示全部楼层
大佬有原理图吗?想看看
回复

使用道具 举报

ID:1112270 发表于 2024-4-25 15:36 | 显示全部楼层
您好我想请问一下,我的温湿度没有问题,但是PM没有显示是为什么呢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表