仿真图:
功能简介:
单片机采用STM32F103(由于STM32仿真电路非常卡,因此没有绘制复位和晶振电路)
显示器采用LCD1602用于显示该项目的参数信息
具有多个功能按键,分别是设置、加、减和确认等功能
具有LED和蜂鸣器组成的声光报警电路
通过滑动变阻器模拟MQ-2传感器
继电器驱动小风扇模拟排气过程
通过串口模块来模拟演示蓝牙上报的过程
芯片/模块的特点:
MQ-2简介:
MQ-2是一种气体传感器模块,用于检测和监测空气中的各种有害气体和可燃气体。它可以检测到多种气体,包括烟雾、甲烷、丙烷、液化石油气(LPG)、氢气、酒精和一氧化碳等。
MQ-2传感器模块基于半导体气敏电阻原理工作。当目标气体进入传感器并与其敏感材料发生化学反应时,电阻值会发生变化。通过测量电阻值的变化,就可以判断目标气体的浓度。
MQ-2传感器模块通常由传感器本体和一个集成的电路板组成。电路板上包含放大器、比较器和AD转换器等电子元件,可以将传感器所产生的模拟信号转换为数字信号,并输出给微控制器或其他设备进行处理。
使用MQ-2传感器模块可以实现以下应用:
燃气泄露检测:可以将MQ-2模块安装在家庭或工业环境中,用于检测可燃气体(如甲烷、丙烷等)的泄漏,以及预防燃气事故的发生。
烟雾检测:可以将MQ-2模块应用于火灾报警系统中,用于检测空气中的烟雾,及时发出警报并采取适当的应对措施。
安全检测:MQ-2模块还可以用于监测一氧化碳等有害气体的浓度,从而保护人们免受有害气体的危害。
主程序:
#include "led.h"
#include "sys.h"
#include "usart.h"
#include <stdio.h>
#include "timer.h"
#include "key.h"
#include <stdio.h>
#include "bsp_lcd1602.h"
#include "adc.h"
#include "bsp_clkconfig.h"
#define BASICS_VAL 15 // 用于数据转换的基础值
#define DEFAULT_SET_VAL 20 // 第一次下载默认设置值
char dis0[17]; // 暂存数组
char dis1[17]; // 暂存数组
unsigned int sensorVal = 0; // 当前采集值
unsigned int adcx;
unsigned int setNum = 20; // 设置值
unsigned char setMode = 0; // 默认手动模式
unsigned char disFlag = 0; // 显示标志
unsigned char timeDelay = 0; // 延时
void CheckKey(void);
int main(void)
{
// 使用HSI,SYSCLK = 4M * RCC_PLLMul_x, x:[2,3,...16],最高是64MH
HSI_SetSysClock(RCC_PLLMul_2); // 使用内部8MHz晶振,并设置PLL输出为8MHz
TIM3_Int_Init(50000-1, 8-1); // 定时器初始化
BUZZER_Init(); // 初始化接口
KEY_Init();
DelayMs(200);
Adc_Init(); // 初始化ad转换
UART_Init(9600); // 串口初始化为9600
BUZZER = 1; // 蜂鸣器报警一下
RELAY = 1;
DelayMs(200);
BUZZER = 0; // 蜂鸣器 停止报警
RELAY = 0;
LCD_GPIO_Init(); // 液晶接口初始化
LCD_Init(); // 液晶配置初始化
DelayMs(20);
while (1)
{
CheckKey();
if (disFlag == 1) // 定时读取标志
{
disFlag = 0; // 清空标志
adcx = Get_Adc_Average(ADC_Channel_8, 5); // 读取ad转换值 5次求平均
sensorVal = ((float)adcx * 3.3 / 4096) * 2 * 99.0 / 5.0; // 采集值 *2表示电阻分压 输出最大5v 但是要转化为最大3.3v
if (sensorVal < BASICS_VAL)
sensorVal = 0; // 过滤传感器本身自带电压
else
{
sensorVal = (sensorVal - BASICS_VAL) * 99 / (99 - BASICS_VAL); // 将30-99值转化为0-99的值
}
sprintf(dis0, "nowValue:%3d%% ", sensorVal); // 打印
LCD_DispStr(0, 0, dis0); // 显示
printf(dis0);
printf("\r\n");
if (setMode)
{
sprintf(dis1, "setValue:%3d%%<", setNum); // 打印
}
else
{
sprintf(dis1, "setValue:%3d%% ", setNum);
}
LCD_DispStr(0, 1, dis1); // 显示
printf(dis1);
printf("\r\n");
if (sensorVal > setNum) // 采集值 和 设置值 对比
{
if (timeDelay < 50) //50*100ms
{
timeDelay++; //持续5s检测到超标
}
else
{
BUZZER = !BUZZER;
RELAY = 1;
}
} // 蜂鸣器报警
else
{
timeDelay = 0;
BUZZER = 0;
RELAY = 0;
} // 不报警
}
}
}
void CheckKey(void)
{
if (!KEY_SET) //设置键
{
DelayMs(20); //延时去抖
if(!KEY_SET) //再次确认按键按下
{
setMode = 1; // 设置状态
}
while(!KEY_SET);
}
if (!KEY_ADD) //加键
{
DelayMs(180); //延时去抖
if(!KEY_ADD) //再次确认按键按下
{
if (setMode)
{ // 设置条件下
if (setNum < 99)
{
setNum = setNum + 1;
} //+1
}
}
// while(!KEY_ADD);
}
if (!KEY_SUB) //减键
{
DelayMs(180); //延时去抖
if(!KEY_SUB) //再次确认按键按下
{
if (setMode)
{ // 设置条件下
if (setNum > 0)
{
setNum = setNum - 1;
}
}
}
// while(!KEY_SUB);
}
if (!KEY_ENTER) //确认键
{
DelayMs(20); //延时去抖
if(!KEY_ENTER) //再次确认按键按下
{
setMode = 0; // 取消设置
}
while(!KEY_ENTER);
}
}
设计文件: