实物演示视频:
https://www.bilibili.com/video/BV1vS4y1z73k/
功能简介:
0.单片机采用STM32F103C8T6最小系统板
1.采用SGP30传感器可检测二氧化碳浓度
2.利用MQ136可检测硫化氢气体
3.利用MQ-4传感器可检测天然气甲烷等气体
原理图:
PCB:
代码:
#define __MIAN_C
#include "main.h"
/************************* 变量定义 *************************/
CreatByte Flag;
enum _MODE_DF_ dispMode;
char dis[16];
u32 humidity = 0;
volatile uint16_t hmMin= 25;
volatile uint16_t hmMax= 60;
uint16_t temperature = 0;
volatile uint16_t tempMin = 20;
volatile uint16_t tempMax = 40;
uint16_t CO2_CONC = 0;
volatile uint16_t CO2_CONC_Max = 800;
uint16_t CH4_CONC = 0;
volatile uint16_t CH4_CONC_Max = 5;
uint16_t H2S_CONC = 0;
volatile uint16_t H2S_CONC_Max = 5;
u8 volatile setIndex = 0;
/************************* 主函数 *************************/
int main(void)
{
// 使用HSI,SYSCLK = 4M * RCC_PLLMul_x, x:[2,3,...16],最高是64MH
HSI_SetSysClock(RCC_PLLMul_2); //使用内部8MHz晶振,并设置PLL输出为8MHz
// 端口初始化
GPIO_Config();
GENERAL_TIM_Init();
Key_GPIO_Config();
DelayMs(200);
DHT11_GPIO_Init();
SGP30_Init();
LCD_GPIO_Init();
LCD_Init();
LCD_Clear();
DelayMs(200);
ADCx_Init();
while (1)
{
if (refreshFlag == 1)
{
refreshFlag = 0;
RefreshData(); //刷新数据
if ((humidity <= hmMax && humidity >= hmMin)\
&& (temperature <= tempMax && temperature >= tempMin) \
&& CO2_CONC <= CO2_CONC_Max && CH4_CONC <= CH4_CONC_Max && H2S_CONC <= H2S_CONC_Max) //在范围内蜂鸣器关闭
{
BUZZER_OFF;
}
else //任一项指标超出阈值范围,蜂鸣器报警
{
BUZZER_ON;
}
if (dispMode == NORMAL) //显示
{
DispNormal();
}
}
KeyProcess(); //按键检测
}
}
/************************* 刷新数据 *************************/
void RefreshData(void)
{
u8 i;
u32 sgp30_dat;
DHT11_ReadData();
humidity = U8RH_data_H;
temperature = U8T_data_H;
sprintf(dis, "Hm:%2d%% T:%3d", humidity, temperature);
CH4_CONC = 0;
H2S_CONC = 0;
for (i = 0; i < 20; i++)
{
CH4_CONC = CH4_CONC + ADC_ConvertedValue[0];
H2S_CONC = H2S_CONC + ADC_ConvertedValue[1];
}
CH4_CONC = CH4_CONC / 20; //取20次平均
if (CH4_CONC < 368) //去掉零值电压
{
CH4_CONC = 0;
}
else
{
CH4_CONC = (CH4_CONC-368) * 100 / (4096-368); //读取CH4浓度信息
}
H2S_CONC = H2S_CONC / 20; //取20次平均
if (H2S_CONC < 123) //去掉零值电压
{
H2S_CONC = 0;
}
else
{
H2S_CONC = (H2S_CONC-123) * 100 / (4096-123); //读取H2S浓度信息
}
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();//读取SGP30的值
CO2_CONC = (sgp30_dat & 0xffff0000) >> 16; //读取CO2浓度信息
}
void DispNormal(void) //显示
{
static uint8_t cnt = 0;
LCD_DispStr(0, 0, dis);
LCD_DispOneChar(12, 0, 0xdf);
LCD_DispOneChar(13, 0, 'C');
//定时切换界面
cnt++;
if (cnt < 10)
{
sprintf(dis, "CO2:%5dppm ", CO2_CONC);
LCD_DispStr(0, 1, dis);
}
else if (cnt < 20)
{
sprintf(dis, "CH4:%2d%% H2S:%2d%%", CH4_CONC, H2S_CONC);
LCD_DispStr(0, 1, dis);
}
else
{
cnt = 0;
}
}
/************************* 显示湿度阈值设定 *************************/
void DispSetHm(u8 setIndex)
{
LCD_DispStr(0, 0, " Set Humidity ");
sprintf(dis, " H:%2d%% L:%2d%% ", hmMax, hmMin);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(6, 1, 1); break;
case 2: LCD_SetCursor(12, 1, 1); break;
default:;
}
}
/************************* 显示温度阈值设定 *************************/
void DispSetTemp(u8 setIndex)
{
LCD_DispStr(0, 0, "Set Temperature ");
sprintf(dis, " H:%3d L:%3d ", tempMax, tempMin);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(7, 1, 1); break;
case 2: LCD_SetCursor(13, 1, 1); break;
default:;
}
}
/************************* 显示CO2浓度阈值设定 *************************/
void DispSetCO2(u8 setIndex)
{
LCD_DispStr(0, 0, " Set CO2 Limit ");
sprintf(dis, " Max:%5dppm ", CO2_CONC_Max);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(10, 1, 1); break;
default:;
}
}