当前位置:   article > 正文

基于STM32的简单火灾报警介绍_基于stm32火灾自动报警系统

基于stm32火灾自动报警系统

 材料

简答记录一下自己学32的过程,这次介绍的是基于STM32的火灾报警系统,用到了面板板,MQ5烟雾传感器,温湿度传感器,0.96寸OLED屏幕,火焰传感器,4个插座式按键,一个STM32F103单片机。

简单介绍

     单片机上电,OLED可以显示温度湿度,可以通过两个按键调节温度阈值(本实验中的四个按键分别用K0 K1 K2 K3来表示,这里的两个按键为K1 K2用于调节阈值的),当温度超过阈值时,OLED会提示危险。一秒后会提示重新设置温度阈值,当设置的阈值还是小于当前温度时,会提示当前温度大于设置的阈值,跳回设置阈值界面,重新设置阈值。

当火焰传感器检测到火焰时,OLED显示着火了。

通过按键K0来切换OLED界面从而显示烟雾传感器的数值,当OLED页面显示的烟雾传感器的数值时可以通过K1 K2来设置烟雾的阈值,当超过阈值时,单片机的led灯被点亮。当OLED页面显示的是温湿度传感器的值时,则K1 K2设置的是温度阈值

关键代码

DHT.c

  1. #include "DHT.h"
  2. #include "delay.h"
  3. //DHT11初始化函数
  4. //DHT11 DATA---PB3
  5. void Dht11_Init(void)
  6. {GPIO_InitTypeDef GPIO_InitStruct;
  7. //开B组时钟和AFIO时钟
  8. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
  9. //初始化IO口
  10. //定义结构体变量
  11. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //配置为开漏输出
  12. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //选定管脚3
  13. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //输出速度为2MHZ
  14. GPIO_Init( GPIOB, &GPIO_InitStruct);
  15. GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);
  16. delay_ms(1000); //延时1s越过不稳定状态
  17. }
  18. /*
  19. * 函数名:DHT11_Mode_IPU
  20. * 描述 :使DHT11-DATA引脚变为上拉输入模式
  21. * 输入 :无
  22. * 输出 :无
  23. */
  24. static void DHT11_Mode_IPU(void)
  25. {
  26. GPIO_InitTypeDef GPIO_InitStructure;
  27. /*选择要控制的DHT11_PORT引脚*/
  28. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  29. /*设置引脚模式为上拉输入模式*/
  30. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
  31. /*调用库函数,初始化DHT11_PORT*/
  32. GPIO_Init(GPIOB, &GPIO_InitStructure);
  33. }
  34. /*
  35. * 函数名:DHT11_Mode_Out_PP
  36. * 描述 :使DHT11-DATA引脚变为推挽输出模式
  37. * 输入 :无
  38. * 输出 :无
  39. */
  40. static void DHT11_Mode_Out_PP(void)
  41. {
  42. GPIO_InitTypeDef GPIO_InitStructure;
  43. /*选择要控制的DHT11_PORT引脚*/
  44. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  45. /*设置引脚模式为通用推挽输出*/
  46. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  47. /*设置引脚速率为50MHz */
  48. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  49. /*调用库函数,初始化DHT11_PORT*/
  50. GPIO_Init(GPIOB, &GPIO_InitStructure);
  51. }
  52. //MCU发送开始信号函数
  53. void Mcu_Send_Start_Sign(void)
  54. {
  55. DHT11_Mode_Out_PP();
  56. GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
  57. delay_ms(18); //拉低总线18ms以上
  58. GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET); //拉高总线等待DHT11响应
  59. DHT11_Mode_IPU();
  60. }
  61. //等待DHT11响应函数
  62. //返回值 1---响应失败 0-----响应成功
  63. u8 Dht11_Ack(void)
  64. {
  65. u8 i = 0;
  66. while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1)
  67. {
  68. i++;
  69. delay_us(1);
  70. if(i>50)
  71. {
  72. return 1; //Dht11响应失败
  73. }
  74. }
  75. //代码运行到这里代表DHT11响应成功
  76. while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0);//跳过DHT11响应时间
  77. while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1);//跳过DHT11测量时间
  78. return 0; //DHT11响应成功
  79. }
  80. //读DHT11测到的数据
  81. u8 Read_Dht11_Data(void)
  82. {
  83. u8 i,data = 0;
  84. for(i=0;i<8;i++)
  85. {
  86. while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0);//跳过数据的1bit低电平开始位
  87. delay_us(40);
  88. // data = data<<1;
  89. if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1) //数据1
  90. {
  91. while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1);//跳过数据'1'的剩余高电平时间
  92. // data |= 1;
  93. data|=(uint8_t)(0x01<<(7-i));
  94. }
  95. else{
  96. data&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
  97. }
  98. }
  99. return data;
  100. }
  101. u8 Mcu_Control_Dht11(u8 *p)
  102. {
  103. u8 ret;
  104. Mcu_Send_Start_Sign(); //发送开始信号
  105. ret = Dht11_Ack();
  106. if(ret)
  107. {
  108. return 1; //测量失败
  109. }
  110. p[0] = Read_Dht11_Data(); //湿度整数数据
  111. p[1] = Read_Dht11_Data(); //湿度小数数据
  112. p[2] = Read_Dht11_Data(); //温度整数数据
  113. p[3] = Read_Dht11_Data(); //温度小数数据
  114. p[4] = Read_Dht11_Data(); //8bit校验和
  115. // for(int i=0;i<4;i++)
  116. // {
  117. // *p=Read_Dht11_Data();
  118. // p++;
  119. // }
  120. if(p[0]+p[1]+p[2]+p[3] != p[4])
  121. {
  122. return 1; //测量失败
  123. }
  124. return 0; //测量成功
  125. }

DHT.h

  1. #ifndef __DHT_H
  2. #define __DHT_H
  3. #include "sys.h"
  4. #include "stm32f10x.h"
  5. #include "delay.h"
  6. static void DHT11_Mode_IPU(void);
  7. static void DHT11_Mode_Out_PP(void);
  8. void Dht11_Init(void);
  9. u8 Mcu_Control_Dht11(u8 *p);
  10. #endif

key_exit.c

  1. #include "key_exit.h"
  2. //PC14 increase增加 PC15 reduce减少 PB5 确定
  3. uint16_t flag=29,temp=0,menu=0,Smokeflag=300;
  4. void key_exit_Init()
  5. {
  6. GPIO_InitTypeDef GPIO_InitStruct;
  7. EXTI_InitTypeDef EXTI_InitStruct;
  8. NVIC_InitTypeDef NVIC_InitStrcut;
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB, ENABLE);
  11. GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
  12. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_14|GPIO_Pin_15;
  13. GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
  14. GPIO_Init(GPIOC,&GPIO_InitStruct);
  15. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6;
  16. GPIO_Init(GPIOB,&GPIO_InitStruct);
  17. GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource14);
  18. GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource15);
  19. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);
  20. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6);
  21. EXTI_InitStruct.EXTI_Line=EXTI_Line14|EXTI_Line15;
  22. EXTI_InitStruct.EXTI_LineCmd=ENABLE;
  23. EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
  24. EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
  25. EXTI_Init(&EXTI_InitStruct);
  26. EXTI_InitStruct.EXTI_Line=EXTI_Line5|EXTI_Line6;
  27. EXTI_InitStruct.EXTI_LineCmd=ENABLE;
  28. EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
  29. EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
  30. EXTI_Init(&EXTI_InitStruct);
  31. NVIC_InitStrcut.NVIC_IRQChannel=EXTI9_5_IRQn;
  32. NVIC_InitStrcut.NVIC_IRQChannelCmd=ENABLE;
  33. NVIC_InitStrcut.NVIC_IRQChannelPreemptionPriority=0;
  34. NVIC_InitStrcut.NVIC_IRQChannelSubPriority=0;
  35. NVIC_Init(&NVIC_InitStrcut);
  36. NVIC_InitStrcut.NVIC_IRQChannel=EXTI15_10_IRQn;
  37. NVIC_InitStrcut.NVIC_IRQChannelCmd=ENABLE;
  38. NVIC_InitStrcut.NVIC_IRQChannelPreemptionPriority=1;
  39. NVIC_InitStrcut.NVIC_IRQChannelSubPriority=1;
  40. NVIC_Init(&NVIC_InitStrcut);
  41. }
  42. void EXTI15_10_IRQHandler()
  43. {
  44. delay_ms(20);
  45. if(EXTI_GetITStatus(EXTI_Line14))//K1被按下(K1为GPIOC的P14引脚)K1用于加阈值
  46. {
  47. if(menu==0)//当前OLED界面为显示温湿度数值的界面
  48. flag++;//此标志位为标志温度阈值,flag++则表示阈值加一
  49. else Smokeflag++;//当当前OLED界面显示的是烟雾传感器的值且K1被按下时,则增加的是烟雾的阈值
  50. printf("11");
  51. EXTI_ClearITPendingBit(EXTI_Line14);
  52. }
  53. if(EXTI_GetITStatus(EXTI_Line15))//K2被按下(K2为GPIOC的P15引脚)K2用于减阈值
  54. {
  55. if(menu==0)//当前OLED界面为显示烟雾数值的界面
  56. flag--;//flag++则表示阈值减一
  57. else Smokeflag--;//当当前OLED界面显示的是烟雾传感器的值且K1被按下时,则减少的是烟雾的阈值
  58. EXTI_ClearITPendingBit(EXTI_Line15);
  59. }
  60. }
  61. void EXTI9_5_IRQHandler()
  62. {
  63. delay_ms(20);
  64. if(EXTI_GetITStatus(EXTI_Line5))//PB5即K3,K3被按下表示温度阈值确定设置为此值
  65. {
  66. if(temp==0)//temp此时初始化为0
  67. temp=1;//标志位置1,temp=1则表示设置为当前选定的温度阈值
  68. else temp=0;//当要重新设置阈值时,temp=0,表示设置为此温度阈值
  69. EXTI_ClearITPendingBit(EXTI_Line5);
  70. }
  71. if(EXTI_GetITStatus(EXTI_Line6))//K0即PB6切换界面
  72. {
  73. if(menu==1)//切换到温湿度界面
  74. menu=0;
  75. else menu=1;
  76. EXTI_ClearITPendingBit(EXTI_Line6);
  77. }
  78. }

key_exit.h

  1. #ifndef __key_exit_H
  2. #define __key_exit_H
  3. #include "sys.h"
  4. #include "stm32f10x.h"
  5. #include "delay.h"
  6. void key_exit_Init();
  7. #endif

main.c

  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "usart.h"
  5. #include "DHT.h"
  6. #include "OLED.h"
  7. #include "MQ.h"
  8. #include "usart2.h"
  9. #include "key_exit.h"
  10. #include "MQ_fire_in.h"
  11. extern uint16_t Get_adcValue;
  12. float Get_daValue=0;
  13. extern float tureValue;
  14. extern uint16_t buff;
  15. extern uint16_t data[2];
  16. extern uint16_t usart2_RX;
  17. extern uint8_t OLED_yuzhiF8x16[][28];
  18. extern uint8_t OLED_zhaohuoF8x16[][28];
  19. extern uint8_t OLED_keranqitiF14x16[][28];
  20. extern uint8_t OLED_keranqiyuzhiF14x16[][28];
  21. extern uint8_t OLED_CurrentF14x16[][28];
  22. extern uint8_t OLED_SetyuzhiF14x16[][28];
  23. extern uint8_t OLED_Chargeyuzhi[][28];
  24. extern uint16_t menu;
  25. extern uint16_t flag;
  26. extern uint16_t temp;
  27. extern uint16_t Smokeflag;
  28. u8 t[5]={0};
  29. uint16_t Value=0;
  30. //uint16_t Flag=29;
  31. //uint16_t temp=29;
  32. float SmokeValue=0;
  33. int main(void)
  34. {
  35. u8 t[5]=0;
  36. delay_init(); //延时函数初始化
  37. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
  38. uart_init(9600); //串口初始化为9600
  39. LED_Init(); //初始化与LED连接的硬件接口
  40. OLED_Init();
  41. Dht11_Init();
  42. MQ_Init();
  43. usart2_DMA_Init(9600);
  44. key_exit_Init();
  45. MQ_fire_Init();
  46. while(1)
  47. {
  48. MQ
  49. Get_daValue=data[1]*99/4096;
  50. printf("%f\r\n",Get_daValue);
  51. //温湿度
  52. // printf("%d\r\n",Mcu_Control_Dht11(t));
  53. Mcu_Control_Dht11(t);
  54. // printf("湿度%d.%d\r\n",t[0],t[1]);
  55. // printf("温度%d.%d\r\n",t[2]),t[3];
  56. Show_Chain_wenshi(1,1,0);
  57. Show_Chain_wenshi(1,2,1);
  58. OLED_ShowNum(1,5,t[0],2);
  59. Show_Chain_wenshi(2,1,2);
  60. Show_Chain_wenshi(2,2,3);
  61. OLED_ShowNum(2,5,t[2],2);
  62. Show_Chain(3,1,OLED_yuzhiF8x16,4);
  63. OLED_ShowNum(3,8,flag,2);
  64. if(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1))//检测着火了输出0
  65. {
  66. while(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1))
  67. {
  68. OLED_Clear();
  69. Show_Chain(1,1,OLED_zhaohuoF8x16,3);
  70. printf("着火了");
  71. }
  72. }
  73. printf("%f\r\n",(tureValue/4096*3.3)*210+10);
  74. if(temp==1)
  75. {
  76. Value=flag;
  77. if(t[2]>Value)
  78. {
  79. OLED_Clear();
  80. Show_Chain_weixian(1,1,0);
  81. Show_Chain_weixian(1,2,1);
  82. Mcu_Control_Dht11(t);
  83. Show_Chain_wenshi(2,1,0);
  84. Show_Chain_wenshi(2,2,1);
  85. OLED_ShowNum(2,5,t[2],2);
  86. OLED_ShowNum(3,1,Value,2);
  87. delay_ms(100000);
  88. OLED_Clear();
  89. while(t[2]>Value)//实际温度超过阈值
  90. {
  91. while(temp==1)//重新设置阈值
  92. {
  93. Mcu_Control_Dht11(t);
  94. Show_Chain(1,1,OLED_CurrentF14x16,5);
  95. OLED_ShowNum(1,10,t[2],2);
  96. Show_Chain(2,1,OLED_SetyuzhiF14x16,9);
  97. OLED_ShowNum(3,1,flag,2);
  98. Value=flag;
  99. }
  100. Mcu_Control_Dht11(t);
  101. if(t[2]>Value)//实际的温度还是超过了刚才设置的阈值,会提示重新设置阈值
  102. {
  103. temp=1;//便于重新进入while(temp==1)里
  104. OLED_Clear();
  105. Show_Chain(1,1,OLED_Chargeyuzhi,12);
  106. delay_ms(100000);
  107. }
  108. OLED_Clear();
  109. }
  110. // Mcu_Control_Dht11(t);
  111. // OLED_Clear();
  112. }
  113. }
  114. if(menu==1)//切换到烟雾界面
  115. {
  116. OLED_Clear();
  117. while(menu==1)
  118. {
  119. Show_Chain(1,1,OLED_keranqitiF14x16,4);
  120. Show_Chain(3,1,OLED_keranqiyuzhiF14x16,5);
  121. SmokeValue=(tureValue/4096*3.3)*210+10;
  122. OLED_ShowFNum(2,1,SmokeValue);
  123. OLED_ShowNum(3,10,Smokeflag,3);
  124. if(SmokeValue>Smokeflag)
  125. {
  126. GPIO_ResetBits(GPIOC,GPIO_Pin_13);
  127. }
  128. }
  129. OLED_Clear();
  130. }
  131. }
  132. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/540229
推荐阅读
相关标签
  

闽ICP备14008679号