赞
踩
简答记录一下自己学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
- #include "DHT.h"
- #include "delay.h"
-
-
- //DHT11初始化函数
- //DHT11 DATA---PB3
-
-
- void Dht11_Init(void)
- {GPIO_InitTypeDef GPIO_InitStruct;
- //开B组时钟和AFIO时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
- //初始化IO口
-
- //定义结构体变量
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //配置为开漏输出
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //选定管脚3
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //输出速度为2MHZ
- GPIO_Init( GPIOB, &GPIO_InitStruct);
-
- GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);
-
- delay_ms(1000); //延时1s越过不稳定状态
- }
-
-
-
-
-
- /*
- * 函数名:DHT11_Mode_IPU
- * 描述 :使DHT11-DATA引脚变为上拉输入模式
- * 输入 :无
- * 输出 :无
- */
- static void DHT11_Mode_IPU(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /*选择要控制的DHT11_PORT引脚*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
-
- /*设置引脚模式为上拉输入模式*/
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
-
- /*调用库函数,初始化DHT11_PORT*/
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
-
- /*
- * 函数名:DHT11_Mode_Out_PP
- * 描述 :使DHT11-DATA引脚变为推挽输出模式
- * 输入 :无
- * 输出 :无
- */
- static void DHT11_Mode_Out_PP(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /*选择要控制的DHT11_PORT引脚*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
-
- /*设置引脚模式为通用推挽输出*/
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
-
- /*设置引脚速率为50MHz */
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-
- /*调用库函数,初始化DHT11_PORT*/
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
-
-
-
-
- //MCU发送开始信号函数
- void Mcu_Send_Start_Sign(void)
- {
- DHT11_Mode_Out_PP();
- GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
- delay_ms(18); //拉低总线18ms以上
- GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET); //拉高总线等待DHT11响应
- DHT11_Mode_IPU();
- }
-
- //等待DHT11响应函数
- //返回值 1---响应失败 0-----响应成功
- u8 Dht11_Ack(void)
- {
- u8 i = 0;
- while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1)
- {
- i++;
- delay_us(1);
- if(i>50)
- {
- return 1; //Dht11响应失败
- }
- }
-
- //代码运行到这里代表DHT11响应成功
- while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0);//跳过DHT11响应时间
- while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1);//跳过DHT11测量时间
-
- return 0; //DHT11响应成功
- }
-
- //读DHT11测到的数据
-
- u8 Read_Dht11_Data(void)
- {
- u8 i,data = 0;
- for(i=0;i<8;i++)
- {
- while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0);//跳过数据的1bit低电平开始位
- delay_us(40);
- // data = data<<1;
- if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1) //数据1
- {
- while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1);//跳过数据'1'的剩余高电平时间
- // data |= 1;
- data|=(uint8_t)(0x01<<(7-i));
- }
- else{
- data&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
- }
-
- }
-
- return data;
- }
-
- u8 Mcu_Control_Dht11(u8 *p)
- {
- u8 ret;
- Mcu_Send_Start_Sign(); //发送开始信号
- ret = Dht11_Ack();
- if(ret)
- {
-
- return 1; //测量失败
- }
- p[0] = Read_Dht11_Data(); //湿度整数数据
- p[1] = Read_Dht11_Data(); //湿度小数数据
- p[2] = Read_Dht11_Data(); //温度整数数据
- p[3] = Read_Dht11_Data(); //温度小数数据
- p[4] = Read_Dht11_Data(); //8bit校验和
- // for(int i=0;i<4;i++)
- // {
- // *p=Read_Dht11_Data();
- // p++;
- // }
- if(p[0]+p[1]+p[2]+p[3] != p[4])
- {
- return 1; //测量失败
- }
-
- return 0; //测量成功
- }
DHT.h
- #ifndef __DHT_H
- #define __DHT_H
- #include "sys.h"
-
-
- #include "stm32f10x.h"
- #include "delay.h"
-
-
- static void DHT11_Mode_IPU(void);
- static void DHT11_Mode_Out_PP(void);
- void Dht11_Init(void);
- u8 Mcu_Control_Dht11(u8 *p);
-
- #endif
-
key_exit.c
- #include "key_exit.h"
- //PC14 increase增加 PC15 reduce减少 PB5 确定
- uint16_t flag=29,temp=0,menu=0,Smokeflag=300;
- void key_exit_Init()
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- EXTI_InitTypeDef EXTI_InitStruct;
- NVIC_InitTypeDef NVIC_InitStrcut;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB, ENABLE);
-
- GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
- GPIO_InitStruct.GPIO_Pin=GPIO_Pin_14|GPIO_Pin_15;
- GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOC,&GPIO_InitStruct);
-
- GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6;
- GPIO_Init(GPIOB,&GPIO_InitStruct);
-
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource14);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource15);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6);
-
- EXTI_InitStruct.EXTI_Line=EXTI_Line14|EXTI_Line15;
- EXTI_InitStruct.EXTI_LineCmd=ENABLE;
- EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
- EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
- EXTI_Init(&EXTI_InitStruct);
-
- EXTI_InitStruct.EXTI_Line=EXTI_Line5|EXTI_Line6;
- EXTI_InitStruct.EXTI_LineCmd=ENABLE;
- EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
- EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
- EXTI_Init(&EXTI_InitStruct);
-
- NVIC_InitStrcut.NVIC_IRQChannel=EXTI9_5_IRQn;
- NVIC_InitStrcut.NVIC_IRQChannelCmd=ENABLE;
- NVIC_InitStrcut.NVIC_IRQChannelPreemptionPriority=0;
- NVIC_InitStrcut.NVIC_IRQChannelSubPriority=0;
- NVIC_Init(&NVIC_InitStrcut);
-
- NVIC_InitStrcut.NVIC_IRQChannel=EXTI15_10_IRQn;
- NVIC_InitStrcut.NVIC_IRQChannelCmd=ENABLE;
- NVIC_InitStrcut.NVIC_IRQChannelPreemptionPriority=1;
- NVIC_InitStrcut.NVIC_IRQChannelSubPriority=1;
- NVIC_Init(&NVIC_InitStrcut);
- }
-
-
-
- void EXTI15_10_IRQHandler()
- {
- delay_ms(20);
- if(EXTI_GetITStatus(EXTI_Line14))//K1被按下(K1为GPIOC的P14引脚)K1用于加阈值
- {
- if(menu==0)//当前OLED界面为显示温湿度数值的界面
- flag++;//此标志位为标志温度阈值,flag++则表示阈值加一
- else Smokeflag++;//当当前OLED界面显示的是烟雾传感器的值且K1被按下时,则增加的是烟雾的阈值
- printf("11");
- EXTI_ClearITPendingBit(EXTI_Line14);
- }
- if(EXTI_GetITStatus(EXTI_Line15))//K2被按下(K2为GPIOC的P15引脚)K2用于减阈值
- {
- if(menu==0)//当前OLED界面为显示烟雾数值的界面
- flag--;//flag++则表示阈值减一
- else Smokeflag--;//当当前OLED界面显示的是烟雾传感器的值且K1被按下时,则减少的是烟雾的阈值
- EXTI_ClearITPendingBit(EXTI_Line15);
- }
- }
- void EXTI9_5_IRQHandler()
- {
- delay_ms(20);
- if(EXTI_GetITStatus(EXTI_Line5))//PB5即K3,K3被按下表示温度阈值确定设置为此值
- {
- if(temp==0)//temp此时初始化为0
- temp=1;//标志位置1,temp=1则表示设置为当前选定的温度阈值
- else temp=0;//当要重新设置阈值时,temp=0,表示设置为此温度阈值
- EXTI_ClearITPendingBit(EXTI_Line5);
- }
- if(EXTI_GetITStatus(EXTI_Line6))//K0即PB6切换界面
- {
- if(menu==1)//切换到温湿度界面
- menu=0;
- else menu=1;
- EXTI_ClearITPendingBit(EXTI_Line6);
- }
- }
key_exit.h
- #ifndef __key_exit_H
- #define __key_exit_H
- #include "sys.h"
-
-
- #include "stm32f10x.h"
- #include "delay.h"
-
- void key_exit_Init();
-
- #endif
-
main.c
- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "DHT.h"
- #include "OLED.h"
- #include "MQ.h"
- #include "usart2.h"
- #include "key_exit.h"
- #include "MQ_fire_in.h"
- extern uint16_t Get_adcValue;
- float Get_daValue=0;
- extern float tureValue;
- extern uint16_t buff;
- extern uint16_t data[2];
- extern uint16_t usart2_RX;
- extern uint8_t OLED_yuzhiF8x16[][28];
- extern uint8_t OLED_zhaohuoF8x16[][28];
- extern uint8_t OLED_keranqitiF14x16[][28];
- extern uint8_t OLED_keranqiyuzhiF14x16[][28];
- extern uint8_t OLED_CurrentF14x16[][28];
- extern uint8_t OLED_SetyuzhiF14x16[][28];
- extern uint8_t OLED_Chargeyuzhi[][28];
- extern uint16_t menu;
- extern uint16_t flag;
- extern uint16_t temp;
- extern uint16_t Smokeflag;
-
- u8 t[5]={0};
- uint16_t Value=0;
- //uint16_t Flag=29;
- //uint16_t temp=29;
- float SmokeValue=0;
- int main(void)
- {
- u8 t[5]=0;
- delay_init(); //延时函数初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
- uart_init(9600); //串口初始化为9600
- LED_Init(); //初始化与LED连接的硬件接口
- OLED_Init();
- Dht11_Init();
- MQ_Init();
- usart2_DMA_Init(9600);
- key_exit_Init();
- MQ_fire_Init();
- while(1)
- {
- MQ
- Get_daValue=data[1]*99/4096;
- printf("%f\r\n",Get_daValue);
- //温湿度
- // printf("%d\r\n",Mcu_Control_Dht11(t));
- Mcu_Control_Dht11(t);
- // printf("湿度%d.%d\r\n",t[0],t[1]);
- // printf("温度%d.%d\r\n",t[2]),t[3];
- Show_Chain_wenshi(1,1,0);
- Show_Chain_wenshi(1,2,1);
-
- OLED_ShowNum(1,5,t[0],2);
-
-
- Show_Chain_wenshi(2,1,2);
- Show_Chain_wenshi(2,2,3);
- OLED_ShowNum(2,5,t[2],2);
- Show_Chain(3,1,OLED_yuzhiF8x16,4);
- OLED_ShowNum(3,8,flag,2);
- if(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1))//检测着火了输出0
- {
- while(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1))
- {
- OLED_Clear();
- Show_Chain(1,1,OLED_zhaohuoF8x16,3);
- printf("着火了");
- }
- }
- printf("%f\r\n",(tureValue/4096*3.3)*210+10);
- if(temp==1)
- {
- Value=flag;
- if(t[2]>Value)
- {
- OLED_Clear();
- Show_Chain_weixian(1,1,0);
- Show_Chain_weixian(1,2,1);
- Mcu_Control_Dht11(t);
- Show_Chain_wenshi(2,1,0);
- Show_Chain_wenshi(2,2,1);
- OLED_ShowNum(2,5,t[2],2);
- OLED_ShowNum(3,1,Value,2);
- delay_ms(100000);
- OLED_Clear();
- while(t[2]>Value)//实际温度超过阈值
- {
- while(temp==1)//重新设置阈值
- {
- Mcu_Control_Dht11(t);
- Show_Chain(1,1,OLED_CurrentF14x16,5);
- OLED_ShowNum(1,10,t[2],2);
- Show_Chain(2,1,OLED_SetyuzhiF14x16,9);
- OLED_ShowNum(3,1,flag,2);
- Value=flag;
- }
- Mcu_Control_Dht11(t);
- if(t[2]>Value)//实际的温度还是超过了刚才设置的阈值,会提示重新设置阈值
- {
- temp=1;//便于重新进入while(temp==1)里
- OLED_Clear();
- Show_Chain(1,1,OLED_Chargeyuzhi,12);
- delay_ms(100000);
- }
- OLED_Clear();
- }
- // Mcu_Control_Dht11(t);
- // OLED_Clear();
- }
-
- }
- if(menu==1)//切换到烟雾界面
- {
- OLED_Clear();
- while(menu==1)
- {
- Show_Chain(1,1,OLED_keranqitiF14x16,4);
- Show_Chain(3,1,OLED_keranqiyuzhiF14x16,5);
- SmokeValue=(tureValue/4096*3.3)*210+10;
- OLED_ShowFNum(2,1,SmokeValue);
- OLED_ShowNum(3,10,Smokeflag,3);
- if(SmokeValue>Smokeflag)
- {
- GPIO_ResetBits(GPIOC,GPIO_Pin_13);
- }
- }
- OLED_Clear();
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。