找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4110|回复: 4
收起左侧

stm32f4xx系列的DHT11+HCSR04超声波+LCD1602显示温湿度和超声波数值仿真程序

  [复制链接]
ID:780517 发表于 2020-6-22 11:25 | 显示全部楼层 |阅读模式
先说这次的实验:这次实验历经了差不多两个周,所获不少。最后实现了,还是有点小激动的,这同时也是我的课程设计。这次的设计主要是通过读取DHT11和HCSR04的数值,(Proteus的传感器貌似这两款好用一点)把读取的DHT11和HCSR04数值通过转化在lcd1602中显示出来,还有就是可以设置通过按键设置DHT11的温湿度阈值。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
2020-06-21_093836.png
运行结果图:
2020-06-21_093852.png
按下K1,K2为加1设置,K3为减1设置
2020-06-21_093933.png
调整湿度最小值要为88%


湿度低于88%;警报响,红灯亮
2020-06-21_093949.png
在调DHT11使它正常,同时也跳一下超声波,看数据传输是否正常
2020-06-21_094009.png


2020-06-21_094118.png
当超过阈值时警报,红灯亮起,绿灯灭。下面是主要代码:

主要代码:
  1. #include <stm32f4xx.h>
  2. #include "delay.h"
  3. #include "DHT11.h"
  4. #include "LCD1602.h"
  5. #include "SOUN.h"
  6. #include "KEY_ExitInit.h"
  7. #include "LED_INIT.h"
  8. #include "HCSR04.h"
  9. unsigned char move = 0x82;
  10. unsigned char RH,RL,TH,TL;
  11. unsigned char h0 = 0X38,h1 = 0X36;
  12. unsigned char t0 = 0X32,t1 = 0X38;
  13. unsigned char DATA[4];//存温湿度数据
  14. unsigned char Leg[4];//存超声波
  15. unsigned char R[7] = "SD:";
  16. unsigned char H[7] = "WD:";
  17. unsigned char L[7] = "Legth:";
  18. unsigned char r[2] = "%";
  19. unsigned char h[2] = "C";
  20. ////////////////////////// 读DHT11数据及数据转换 ///////////////////////////////////////
  21. int DHT11_ReadDATA(void)
  22. {
  23.         int i;
  24.         unsigned char RHTH[5]={0};
  25.         DHT11_Start();//开始信号

  26.         for(i=0;i<5;i++)
  27.         {
  28.           RHTH[i] = DHT11_ReadByte();//循环读5次一字节  刚好40bit
  29.         }

  30.         if(RHTH[0]+RHTH[1]+RHTH[2]+RHTH[3] == RHTH[4])
  31.         {
  32.        RH = RHTH[0];
  33.            RL = RHTH[1];
  34.            TH = RHTH[2];
  35.            TL = RHTH[3];
  36.    DATA[0]='0'+(RH/10);//数据显示处理
  37.    DATA[1]='0'+(RH%10);
  38.    DATA[2]='0'+(TH/10);
  39.    DATA[3]='0'+(TH%10);
  40.                 return 0;
  41.         }
  42.         else
  43.         {
  44.         
  45.                 return -1;
  46.         }
  47. }
  48. ///////////////////////////// END  //////////////////////////////////////////


  49. //////////////////////////// 获取超声波数据及转换////////////////////////
  50. void HCSR04_data(void)
  51. {
  52.         int        a = 0;
  53.         a = HCSR04_GetLength();
  54.     Leg[0]='0'+(a/10);
  55.     Leg[1]='0'+(a%10);
  56.         a = a*100;
  57.         Leg[2] = '0'+(a%100)/10;
  58.         Leg[3] = '0';  // '0'+(a%1000) 只显示到第三位,所以第四位写入0
  59. }
  60. /////////////////////////// END ///////////////////////////////////////////


  61. //////////////////////////// 显示设定的阈值 ////////////////////////////////
  62. void LCD_Config(void)
  63. {
  64.                     LCD_WRITE_StrDATA(1,1,"H:");
  65.                         LCD_WRITE_char(1,3,h0);
  66.                         LCD_WRITE_char(1,4,h1);
  67.                     LCD_WRITE_StrDATA(2,1,"T:");
  68.                         LCD_WRITE_char(2,3,t0);
  69.                         LCD_WRITE_char(2,4,t1);
  70.                  delay_ms(9);
  71. }
  72. ///////////////////////////  END ///////////////////////////////////////


  73. ////////////////////////////  显示温湿度和超声波数值,及超过阈值后警报 ///////////////////////////////////
  74. void LCD_Show(void)
  75. {
  76.    while(1)
  77.         {
  78.                 HCSR04_data();
  79.                 delay_ms(30);

  80.                 if(DHT11_ReadDATA() == 0)//读取温湿度成功
  81.                 {
  82.                         delay_ms(80);
  83.             LCD_WRITE_CMD( 0x0C );                        
  84.                         DHT11_ReadDATA();        //接受数据
  85.                         LCD_WRITE_StrDATA(1,1,R);
  86.                         LCD_WRITE_StrDATA(2,1,H);
  87.                         LCD_WRITE_char(1,4,DATA[0]);
  88.                         LCD_WRITE_char(1,5,DATA[1]);
  89.                         LCD_WRITE_StrDATA(1,6,r);
  90.                         LCD_WRITE_StrDATA(1,9,L);
  91.                         
  92.                         LCD_WRITE_char(2,4,DATA[2]);
  93.                         LCD_WRITE_char(2,5,DATA[3]);
  94.                         LCD_WRITE_char(2,6,0XDF);
  95.                         LCD_WRITE_StrDATA(2,7,h);
  96.                         
  97.                         LCD_WRITE_char(2,9,Leg[0]);
  98.                         LCD_WRITE_char(2,10,Leg[1]);
  99.                         LCD_WRITE_char(2,11,0xA5);
  100.                         LCD_WRITE_char(2,12,Leg[2]);
  101.                         LCD_WRITE_char(2,13,Leg[3]);
  102.                         LCD_WRITE_StrDATA(2,14,"cm");
  103.                 }        
  104.                 if(RH > ((h0-0x30)*10+(h1-0x30))|| TH < ((t0-0x30)*10+(t1-0x30)) )//正常
  105.                 {
  106.                   GPIO_SetBits(GPIOC,GPIO_Pin_7);
  107.                   GPIO_ResetBits(GPIOC,GPIO_Pin_6);
  108.                   GPIO_SetBits(GPIOB,GPIO_Pin_7);
  109.                   
  110.                 }
  111.                 if(RH <= ((h0-0x30)*10+(h1-0x30))|| TH >= ((t0-0x30)*10+(t1-0x30)) ) //警报
  112.                 {
  113.                   GPIO_SetBits(GPIOC,GPIO_Pin_6);
  114.                   GPIO_ResetBits(GPIOC,GPIO_Pin_7);
  115.                   GPIO_ResetBits(GPIOB,GPIO_Pin_7);
  116.                 }
  117.                
  118.         }        

  119. }
  120. ///////////////////////////   END  ///////////////////////////////////


  121. /////////////////////// 中断服务函数 ,第一个按键切换显示+光标移动////////////////////////////////////////
  122. void EXTI0_IRQHandler(void)
  123. {
  124.         static int Flag = 1;
  125.         switch (Flag)
  126.         {
  127.                 case 1:
  128.                   LCD_WRITE_CMD( 0x01 );  //清楚显示
  129.                   LCD_WRITE_CMD( 0x0f );  //开启光标、显示、闪烁
  130.           LCD_Config();             //切换显示
  131.                   LCD_WRITE_CMD( move );
  132.                 delay_ms(5);break;
  133.                 case 2:
  134.                   LCD_WRITE_CMD( 0x0f );
  135.                   move ++;               //光标移动
  136.                   LCD_WRITE_CMD( move );
  137.                   delay_ms(5);break;
  138.                 case 3:
  139.                    LCD_WRITE_CMD( 0x0f );
  140.                    move += 0x3f;
  141.                    LCD_WRITE_CMD( move );
  142.                 delay_ms(5);break;
  143.                 case 4:
  144.                    LCD_WRITE_CMD( 0x0f );
  145.                    move ++;
  146.                    LCD_WRITE_CMD( move );
  147.                 delay_ms(5);break;
  148.                 case 5:
  149.                    move = 0x82;         //光标复位
  150.                LCD_WRITE_CMD( 0x01 );
  151.                LCD_WRITE_CMD( 0x0C );
  152.                LCD_Show();
  153.                Flag = 0;
  154.                 delay_ms(5);break;
  155.         }
  156.         Flag ++;
  157.     EXTI_ClearITPendingBit(EXTI_Line0);
  158. }

  159. /////////////////////////  中断0 END ///////////////////////////////////


  160. /////////////////////////   中断 1  阈值加1 ///////////////////////////
  161. void EXTI1_IRQHandler(void)
  162. {
  163.         if(move == 0x82)    //判断光标位置
  164.         {
  165.           if((h0-0x30) >= 9)
  166.       {
  167.                   h0 = 0x30;
  168.           }        
  169.       else
  170.       {
  171.                   h0 ++;
  172.           }         
  173.         }
  174.                 if(move == 0x83)  //判断光标位置
  175.                 {
  176.                   if((h1-0x30) >= 9)
  177.                   {
  178.                           h1 = 0x30;
  179.                   }        
  180.                   else
  181.                   {
  182.                           h1 ++;
  183.                   }
  184.                  }         
  185.      if(move == 0xc2)  //判断光标位置
  186.         {
  187.           if((t0-0x30) >= 9)
  188.       {
  189.                   t0 = 0x30;
  190.           }        
  191.       else
  192.       {
  193.                   t0 ++;
  194.           }                  
  195.          }        
  196.                 if(move == 0xc3)  //判断光标位置
  197.                 {
  198.                   if((t1-0x30) >= 9)
  199.                   {
  200.                           t1 = 0x30;
  201.                   }        
  202.                   else
  203.                   {
  204.                           t1 ++;
  205.                   }                  
  206.                 }
  207.   LCD_WRITE_CMD( 0x0c );    //为了看清楚,关闭光标的闪烁功能
  208.   LCD_Config();                   //显示
  209.   delay_ms(5);                 
  210.   EXTI_ClearITPendingBit(EXTI_Line1);
  211. }
  212. ////////////////////////////// 中断1 END ///////////////////////////////////////


  213. ///////////////////////////// 中断 2  阈值加1 ////////////////////////////////
  214. void EXTI2_IRQHandler(void)
  215. {
  216.     if(move == 0x82)
  217.         {
  218.           if((h0-0x30) == 0)
  219.       {
  220.                   h0 = 0x39;
  221.           }        
  222.       else
  223.       {
  224.                   h0 --;
  225.           }                  
  226.         }
  227.                 if(move == 0x83)
  228.                 {
  229.                   if((h1-0x30) == 0)
  230.                   {
  231.                           h1 = 0x39;
  232.                   }        
  233.                   else
  234.                   {
  235.                           h1 --;
  236.                   }
  237.                  }         
  238.      if(move == 0xc2)
  239.         {
  240.           if((t0-0x30) == 0)
  241.       {
  242.                   t0 = 0x39;
  243.           }        
  244.       else
  245.       {
  246.                   t0 --;
  247.           }                  
  248.          }        
  249.                 if(move == 0xc3)
  250.                 {
  251.                   if((t1-0x30) == 0)
  252.                   {
  253.                           t1 = 0x39;
  254.                   }        
  255.                   else
  256.                   {
  257.                           t1 --;
  258.                   }                  
  259.                 }
  260.     LCD_WRITE_CMD( 0x0c );
  261.     LCD_Config();
  262.     delay_ms(5);               
  263.         EXTI_ClearITPendingBit(EXTI_Line2);
  264. }
  265. ///////////////////////////// 中断 2  END //////////////////////////////////////


  266. int main()
  267. {
  268.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  269.         Systick_init();//滴答定时器的初始化---精准延时
  270.         LED_INIT();    //警报灯
  271.         SOUN_INIT();    //蜂鸣器
  272.         
  273.         KEY_ExitInit();  //中断gpio口初始化
  274.         LCD_INIT();   //LCD1602初始化
  275.         
  276.         HCSR04_GPIO();  //超声波gpio口初始化
  277.         HCSR04_TIM2_Config();   //定时器2设置
  278.         TIM2_IRQHandler();    //定时器中断函数
  279.         
  280.     LCD_Show();   //lcd1602显示
  281.    return 0;
  282. }
复制代码


结束;
这次的实验也有不足的地方,代码也有待优化,有一些瑕疵,借此抛砖引玉,希望大家能提出建议!!

全部资料51hei下载地址:
keil 5工程 + Proteus工程.7z (98.08 KB, 下载次数: 246)

评分

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

查看全部评分

回复

使用道具 举报

ID:302325 发表于 2020-6-24 12:00 | 显示全部楼层
51黑  有你更精彩        
回复

使用道具 举报

ID:779099 发表于 2020-7-3 15:46 | 显示全部楼层
麻烦问一下这代码只能在keil5运行吗?
回复

使用道具 举报

ID:780517 发表于 2020-7-7 09:39 | 显示全部楼层
东坡是我家男神 发表于 2020-7-3 15:46
麻烦问一下这代码只能在keil5运行吗?

keil4 mdk 也可以   只不过你要安装相对应当stm32包
回复

使用道具 举报

ID:844192 发表于 2021-6-28 23:22 | 显示全部楼层
楼主请问一下这个报警温度怎么修改 就是超过多少修改这是哪里
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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