任务
硬件设计部分主要包括硬件选型及其配置,mq-2烟雾传感器,温湿度传感器dht11,lcd显示屏,红外热释传感器,声音报警器。
主要要求: dht11,红外传感器,了解其工作原理
(2)掌握STM32/51单片机基本的库函数,学会基本的C编程语言
(3)设计动物体温识别算法,能准确识别热源点
(4)能通过液晶显示器显示测到的温度和湿度
(5)可以通过按键来设置需要的值
(6)能通过单片机控制系统的运行,并在触发烟雾传感器,红外传感器时报警
(7)设计硬件图纸和相应的源程序
核心技术指标:
(1)温度未达到设定值,动机工作
(2)湿度未达到设定值时,动机工作
(3)有动物闯入别的区域时,触发报警蜂鸣器
(4)发声火灾时,烟雾报警器进行报警,触发蜂鸣器
本研究的目的是开发一种能实时、准确地显示温湿度值、可以进行动物走错区报警,以及火灾报警室内动物园温湿度控制系统。通过采集温湿度值,可以准确判断标准值与当前值的差值,并能及时报警,并通过外界采取相应的方案。温度和湿度可调节到所需状态,可提高系统的方便性,并可在上述目的的基础上节约能源。
实物
原理图
源程序
主函数main.c
/*******************************************************************************
* 文件名称:STM32温湿度控制体温检测烟雾报警系统
* 实验目的:1.
* 2.
* 程序说明:完整程序Q:2772272579;@: [email protected]
* 日期版本:51,STM32功能可定制。
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @说明 主函数
* @参数 None
* @返回值 None
*/
int main(void)
{
Proc_Init();
LED_Init();
OLED_Init();
LCD_Display();
ADC1_Init();
if(DHT11_Init() == 1)
{
OLED_Showx8_y16(0,3,(unsigned char*)" DHT11 ERROR! ");
}
else
{
OLED_Showx8_y16(0,3,(unsigned char*)" DHT11 SUCCESS! ");
}
BEEP_Init();
BEEP_Control(ON);
LED_Control(ON);
Delay_ms(1000);
BEEP_Control(OFF);
LED_Control(OFF);
KEY_Init();
RELAY_Init();
SMBus_Init();
TIM4_Init();
while(1){
Key_Proc();
if(TIM4_FlagStatus.Flag_200MS == SET){
TIM4_FlagStatus.Flag_200MS = RESET;
LED_Control(REVERSE);
Proc_200Ms();
}
Check_Sensior();
LCD_Display();
}
}
处理逻辑
#include "proc.h"
LCD_ENUM LCD_Menu = LCD_DEFAULT,LCD_Menu_Last = LCD_DEFAULT;
LCD_DEF_MENU LCD_DefShow;
LCD_SET_MENU LCD_SetShow;
#define LCD_BUFFMAX 21
char LCD_Buff[LCD_BUFFMAX];
void LCD_Display(void)
{
if(LCD_Menu_Last != LCD_Menu)
{
LCD_Menu_Last = LCD_Menu;
OLED_CLS();//清屏
}
if(LCD_Menu == LCD_DEFAULT)
{
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 检测界面 ");
OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 温度: %d℃ ",LCD_DefShow.DHT11_Tempe);
OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 湿度: %d%%RH ",LCD_DefShow.DHT11_Humi); // RH就是相对湿度,(Relative Humidity) %转义->%
OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 体温: %3.1f℃ ",LCD_DefShow.GY906_Temp);
OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);
}
else if(LCD_Menu == LCD_Tset02)
{
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 检测界面 ");
OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 烟雾: %dPPM ",LCD_DefShow.Yanwu);
OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 火焰: %.2fV ",LCD_DefShow.Adc_Huoyan); //
OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 体温: %3.1f℃ ",LCD_DefShow.GY906_Temp);
OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);
}
else if(LCD_Menu == LCD_SETTING)
{
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 设置界面 ");
OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)"温度L: %d℃ ",LCD_SetShow.DHT11_Tempe_Set_L);
OLED_Showx8_y16(1,1,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)"温度H: %d℃ ",LCD_SetShow.DHT11_Tempe_Set_H);
OLED_Showx8_y16(1,2,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)"湿度L: %d%%RH ",LCD_SetShow.DHT11_Humi_Set_L);
OLED_Showx8_y16(1,3,(unsigned char*)LCD_Buff);
if(LCD_SetShow.Now_SetLine > 1)
OLED_Showx8_y16(0,LCD_SetShow.Now_SetLine-1,(unsigned char*)" ");//LCD_SetShow.Now_SetLine
OLED_Showx8_y16(0,LCD_SetShow.Now_SetLine,(unsigned char*)"*");//LCD_SetShow.Now_SetLine
}
else if(LCD_Menu == LCD_SETTING02)
{
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 设置界面 ");
OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)"湿度H: %d%%RH ",LCD_SetShow.DHT11_Humi_Set_H);
OLED_Showx8_y16(1,1,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)"体温L: %3.1f℃ ",LCD_SetShow.GY906_Temp_Set_L);
OLED_Showx8_y16(1,2,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)"体温H: %3.1f℃ ",LCD_SetShow.GY906_Temp_Set_H);
OLED_Showx8_y16(1,3,(unsigned char*)LCD_Buff);
if(LCD_SetShow.Now_SetLine > 1)
OLED_Showx8_y16(0,LCD_SetShow.Now_SetLine-1,(unsigned char*)" ");//LCD_SetShow.Now_SetLine
OLED_Showx8_y16(0,LCD_SetShow.Now_SetLine,(unsigned char*)"*");//LCD_SetShow.Now_SetLine
}
else if(LCD_Menu == LCD_SETTING03)
{
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)" 设置界面 ");
OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)"烟雾: %dPPM ",LCD_SetShow.Yanwu_Set);
OLED_Showx8_y16(1,2,(unsigned char*)LCD_Buff);
memset(LCD_Buff,'0',LCD_BUFFMAX);
sprintf(LCD_Buff,(char *)"火焰: %.2fV ",LCD_SetShow.Huoyan_Set); //
OLED_Showx8_y16(1,3,(unsigned char*)LCD_Buff);
if(LCD_SetShow.Now_SetLine > 2)
OLED_Showx8_y16(0,LCD_SetShow.Now_SetLine-1,(unsigned char*)" ");//LCD_SetShow.Now_SetLine
OLED_Showx8_y16(0,LCD_SetShow.Now_SetLine,(unsigned char*)"*");//LCD_SetShow.Now_SetLine
}
}
STRUCT_NVICPriority NVICPriority_Structure;
void Proc_Init(void)
{
NVICPriority_Structure.Tim4 = 4;
LCD_SetShow.DHT11_Tempe_Set_L=15;
LCD_SetShow.DHT11_Tempe_Set_H=23;
LCD_SetShow.DHT11_Humi_Set_L = 60;
LCD_SetShow.DHT11_Humi_Set_H = 80;
LCD_SetShow.GY906_Temp_Set_L = 20;
LCD_SetShow.GY906_Temp_Set_H = 30;
LCD_SetShow.Huoyan_Set = 1.0;
LCD_SetShow.Yanwu_Set = 200;
}
extern STRUCT_DHT11 DHT11_Structure;
extern __IO uint16_t ADCConvertedValue[ADC_BUFFMAX];
void Proc_200Ms(void)
{
if(DHT11_Read_Data() != 0)
{
LCD_DefShow.DHT11_Humi = (u8)DHT11_Structure.Humi;
LCD_DefShow.DHT11_Tempe = (u8)DHT11_Structure.Tempe;
}
LCD_DefShow.GY906_Temp=SMBus_ReadTemp();
LCD_DefShow.Adc_Yanwu = (float)(ADCConvertedValue[0] * 3.3 / 0xfff);
LCD_DefShow.Adc_Yanwu-=0.138; //自减初值
if(LCD_DefShow.Adc_Yanwu <0)
LCD_DefShow.Adc_Yanwu=0;
LCD_DefShow.Yanwu = (u16)((LCD_DefShow.Adc_Yanwu*100) * 36.36); //0.14 - 0.7 ;0-2000PPM 均分比列
LCD_DefShow.Adc_Huoyan = (float)(ADCConvertedValue[1] * 3.3 / 0xfff);
}
void RELAY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOx clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //LED_RED
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6);
GPIO_SetBits(GPIOB,GPIO_Pin_7);
}
void RELAY_Control(u8 choice,ENUM_STATE NewState)
{
if(NewState == ON)
{
if(choice == 1)
GPIO_ResetBits(GPIOB,GPIO_Pin_6);
else
GPIO_ResetBits(GPIOB,GPIO_Pin_7);
}
else if(NewState == OFF)
{
if(choice == 1)
GPIO_SetBits(GPIOB,GPIO_Pin_6);
else
GPIO_SetBits(GPIOB,GPIO_Pin_7);
}
}
void BEEP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOx clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //LED_RED
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_15; //BEEP
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_12);
GPIO_SetBits(GPIOB,GPIO_Pin_9);
}
uint8_t BEEP_BUFF = 0x01;
void BEEP_Control(ENUM_STATE NewState)
{
if(NewState == ON)
{
BEEP_BUFF = 0x00;
GPIO_ResetBits(GPIOA,GPIO_Pin_12);
GPIO_ResetBits(GPIOB,GPIO_Pin_9);
}
else if(NewState == OFF)
{
BEEP_BUFF = 0x01;
GPIO_SetBits(GPIOA,GPIO_Pin_12);
GPIO_SetBits(GPIOB,GPIO_Pin_9);
}
else //reverse
{
if(BEEP_BUFF == 0x01) // currunt bit status is 1?--off
{
BEEP_BUFF = 0x00;
GPIO_ResetBits(GPIOA,GPIO_Pin_12);
GPIO_ResetBits(GPIOB,GPIO_Pin_9);
}
else
{
BEEP_BUFF = 0x01;
GPIO_SetBits(GPIOA,GPIO_Pin_12);
GPIO_SetBits(GPIOB,GPIO_Pin_9);
}
}
}
extern STRUCT_KEY KEY_Structure;
void Key_Proc(void)
{
if(KEY_Structure.TouchKey != 0xff)
{
switch(KEY_Structure.TouchKey)
{
case 1:
if(KEY_Structure.IS_ShortTouch == TRUE){
if(LCD_Menu == LCD_DEFAULT)
{
LCD_Menu = LCD_Tset02;
}
else
{
LCD_Menu = LCD_DEFAULT;
LCD_SetShow.Now_SetLine = 0;
}
}
break;
case 2:
if(KEY_Structure.IS_ShortTouch == TRUE){
if(LCD_Menu != LCD_SETTING && LCD_Menu != LCD_SETTING02 && LCD_Menu != LCD_SETTING03)
LCD_Menu = LCD_SETTING;
if(LCD_Menu == LCD_SETTING)
{
LCD_SetShow.Now_SetLine++; //u8 LCD_SetShow.Now_SetLine=0;
if(LCD_SetShow.Now_SetLine > 3)
{
LCD_SetShow.Now_SetLine = 0;
LCD_Menu = LCD_SETTING02;
}
}
if(LCD_Menu==LCD_SETTING02)
{
LCD_SetShow.Now_SetLine++; //u8 LCD_SetShow.Now_SetLine=0;
if(LCD_SetShow.Now_SetLine > 3)
{
LCD_SetShow.Now_SetLine = 1;
LCD_Menu = LCD_SETTING03;
}
}
if(LCD_Menu==LCD_SETTING03)
{
LCD_SetShow.Now_SetLine++; //u8 LCD_SetShow.Now_SetLine=0;
if(LCD_SetShow.Now_SetLine > 3)
{
LCD_SetShow.Now_SetLine = 0;
LCD_Menu = LCD_DEFAULT;
}
}
}
break;
case 3:
if(LCD_Menu == LCD_SETTING)
{
switch(LCD_SetShow.Now_SetLine)
{
case 1: //DHT11温度L
LCD_SetShow.DHT11_Tempe_Set_L++;
if(LCD_SetShow.DHT11_Tempe_Set_L>=LCD_SetShow.DHT11_Humi_Set_H)
LCD_SetShow.DHT11_Tempe_Set_L=LCD_SetShow.DHT11_Humi_Set_H-1;
break;
case 2: //DHT11温度H
LCD_SetShow.DHT11_Tempe_Set_H++;
if(LCD_SetShow.DHT11_Tempe_Set_H>99)
LCD_SetShow.DHT11_Tempe_Set_H=99;
break;
case 3: //DHT11湿度L
LCD_SetShow.DHT11_Humi_Set_L++;
if(LCD_SetShow.DHT11_Humi_Set_L>=LCD_SetShow.DHT11_Humi_Set_H)
LCD_SetShow.DHT11_Humi_Set_L=LCD_SetShow.DHT11_Humi_Set_L-1;
break;
default:break;
}
}
if(LCD_Menu == LCD_SETTING02)
{
switch(LCD_SetShow.Now_SetLine)
{
case 1: //DHT11湿度H
LCD_SetShow.DHT11_Humi_Set_H++;
if(LCD_SetShow.DHT11_Humi_Set_H>99)
LCD_SetShow.DHT11_Humi_Set_H=99;
break;
case 2: //GY906 L
LCD_SetShow.GY906_Temp_Set_L+=0.1;
if(LCD_SetShow.GY906_Temp_Set_L>=LCD_SetShow.GY906_Temp_Set_H)
LCD_SetShow.GY906_Temp_Set_L=LCD_SetShow.GY906_Temp_Set_H-0.1;
break;
case 3: //GY906 H
LCD_SetShow.GY906_Temp_Set_H+=0.1;
if(LCD_SetShow.GY906_Temp_Set_H>99.9)
LCD_SetShow.GY906_Temp_Set_H=99.9;
break;
default:break;
}
}
if(LCD_Menu == LCD_SETTING03)
{
switch(LCD_SetShow.Now_SetLine)
{
case 2: //烟雾
LCD_SetShow.Yanwu_Set++;
if(LCD_SetShow.Yanwu_Set>2000)
LCD_SetShow.Yanwu_Set=2000;
break;
case 3: //火焰
LCD_SetShow.Huoyan_Set+=0.1;
if(LCD_SetShow.Huoyan_Set>3.3)
LCD_SetShow.Huoyan_Set=3.3;
break;
default:break;
}
}
break;
case 4:
if(LCD_Menu == LCD_SETTING)
{
switch(LCD_SetShow.Now_SetLine)
{
case 1: //DHT11温度L
LCD_SetShow.DHT11_Tempe_Set_L--;
if(LCD_SetShow.DHT11_Tempe_Set_L<1)
LCD_SetShow.DHT11_Tempe_Set_L=1;
break;
case 2: //DHT11温度H
LCD_SetShow.DHT11_Tempe_Set_H--;
if(LCD_SetShow.DHT11_Tempe_Set_H<=LCD_SetShow.DHT11_Tempe_Set_L)
LCD_SetShow.DHT11_Tempe_Set_H=LCD_SetShow.DHT11_Tempe_Set_L+1;
break;
case 3: //DHT11湿度L
LCD_SetShow.DHT11_Humi_Set_L--;
if(LCD_SetShow.DHT11_Humi_Set_L<1)
LCD_SetShow.DHT11_Humi_Set_L=1;
break;
default:break;
}
}
if(LCD_Menu == LCD_SETTING02)
{
switch(LCD_SetShow.Now_SetLine)
{
case 1: //DHT11湿度H
LCD_SetShow.DHT11_Humi_Set_H--;
if(LCD_SetShow.DHT11_Humi_Set_H<=LCD_SetShow.DHT11_Humi_Set_L)
LCD_SetShow.DHT11_Humi_Set_H=LCD_SetShow.DHT11_Humi_Set_L-1;
break;
case 2: //GY906 L
LCD_SetShow.GY906_Temp_Set_L-=0.1;
if(LCD_SetShow.GY906_Temp_Set_L<=0.1)
LCD_SetShow.GY906_Temp_Set_L=0.1;
break;
case 3: //GY906 H
LCD_SetShow.GY906_Temp_Set_H-=0.1;
if(LCD_SetShow.GY906_Temp_Set_H<=LCD_SetShow.GY906_Temp_Set_L)
LCD_SetShow.GY906_Temp_Set_H=LCD_SetShow.GY906_Temp_Set_L-0.1;
break;
default:break;
}
}
if(LCD_Menu == LCD_SETTING03)
{
switch(LCD_SetShow.Now_SetLine)
{
case 2: //烟雾
LCD_SetShow.Yanwu_Set--;
if(LCD_SetShow.Yanwu_Set<1)
LCD_SetShow.Yanwu_Set=1;
break;
case 3: //火焰
LCD_SetShow.Huoyan_Set-=0.1;
if(LCD_SetShow.Huoyan_Set<0.1)
LCD_SetShow.Huoyan_Set=0.1;
break;
default:break;
}
}
break;
default:break;
}
KEY_Structure.TouchKey = 0xff;
KEY_Structure.IS_ShortTouch = FALSE;
}
}
u8 Flag_Gy906=0,Flag_Yanwu=0,Flag_Huoyan=0;
void Check_Sensior(void)
{
if(LCD_DefShow.DHT11_Tempe <LCD_SetShow.DHT11_Tempe_Set_L || LCD_DefShow.DHT11_Tempe >LCD_SetShow.DHT11_Tempe_Set_H)
{
RELAY_Control(1,ON);
}
else
{
RELAY_Control(1,OFF);
}
if(LCD_DefShow.DHT11_Humi <LCD_SetShow.DHT11_Humi_Set_L || LCD_DefShow.DHT11_Humi >LCD_SetShow.DHT11_Humi_Set_H)
{
RELAY_Control(2,ON);
}
else
{
RELAY_Control(2,OFF);
}
if(LCD_DefShow.GY906_Temp < LCD_SetShow.GY906_Temp_Set_L || LCD_DefShow.GY906_Temp > LCD_SetShow.GY906_Temp_Set_H)
{
Flag_Gy906 = 1;
}
else
{
Flag_Gy906 = 0;
}
if(LCD_DefShow.Yanwu >LCD_SetShow.Yanwu_Set)
{
Flag_Yanwu = 1;
}
else
{
Flag_Yanwu = 0;
}
if(LCD_DefShow.Adc_Huoyan <LCD_SetShow.Huoyan_Set)
{
Flag_Huoyan = 1;
}
else
{
Flag_Huoyan = 0;
}
if(Flag_Gy906 | Flag_Yanwu | Flag_Huoyan)
{
BEEP_Control(ON);
}
else
{
BEEP_Control(OFF);
}
}