基于STM32的烟雾浓度检测报警仿真设计(仿真+程序+讲解)
- 1.主要功能
- 2.仿真
- 3. 程序
- 4. 资料清单&下载链接
基于STM32的烟雾浓度检测报警仿真设计(仿真+程序+讲解)
仿真图proteus 8.9
程序编译器:keil 5
编程语言:C语言
设计编号:C0085
1.主要功能
功能说明:
1、以STM32单片机和MQ-2控制核心设计烟雾浓度检测报警设计;
2、通过液晶屏LCD1602和串口上位机显示烟雾浓度,MV表示检测值,ALM表示报警值;
3、可以通过按键设置烟雾浓度ALM报警值大小。
4、监测烟雾浓度大于报警值时蜂鸣器报警电路导通,蜂鸣器报警。拨动开关打开情况下,风扇转动通风。
5、默认监测到烟雾浓度高于200ppm蜂鸣器报警。
主要硬件设备:STM32F103单片机
以下为本设计资料展示:
2.仿真
整体设计方案
本实验利用STM32单片机的ADC、GPIO、定时器等资源,将软、硬件有机地结合起来,使得系统能够正确地进识别输入模拟烟雾浓度传感器的AD值,LCD1602能够正确地显示,蜂鸣器根据烟雾浓度报警值工作。需注意的是,proteus是没有MQ-2等烟雾浓度传感器的,本设计使用滑动变阻器模拟烟雾浓度变化,不能直接用于实物设计,有需要的需跟据实物调试。
仿真运行情况:
开始仿真后LCD1602实时显示检测到的烟雾浓度,可以通过滑动变阻器改变测量值。可通过按键设置报警值浓度,按下设置键进入设置模式,通过设置+调高报警值,通过设置-调低报警值。蜂鸣器报警电路在烟雾浓度高于报警值时启动,有嘟嘟报警声,低于不启动。
本设计采用电磁式蜂鸣器进行。电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。因此需要一定的电流才能驱动它,单片机I/O引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。蜂鸣器的正极接到VCC(+5V)电源上面,蜂鸣器的负极接到三极管的集电极C,三极管的基极B经过限流电阻后由单片机的BEEP引脚控制,当BEEP输出低电平时,三级管QS截止,没有电流流过线圈,蜂鸣器不发声;当BEEP输出高电平时,三级管导通,这样蜂鸣器的电流形成回路,发出声音。
下图检测到烟雾浓度是192ppm,低于报警值200,蜂鸣器电路不工作。
下图检测到烟雾浓度是204ppm,大于等于报警值,三极管导通,蜂鸣器报警
3. 程序
程序是用keil5 mdk版本打开的,如果打开有问题,核实下keil的版本。程序是HAL库版本编写的,有注释可以结合讲解视频理解。
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd1602.h"
#include "stdio.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
uint16_t Tim_cnt = 0; //定时器变量
uint8_t set_flag = 0;
float warming_val=200; //报警浓度大小
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
ADC_ChannelConfTypeDef sConfig = {0}; //建立sConfig结构体
char str[20]; //字符串的存放数组
uint32_t adcv; //存放ADC转换结果
float temp;
set_flag = 0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; //采样周期为1.5个周期
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_USART1_UART_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
LCD_Init(); //初始化LCD1602
HAL_TIM_Base_Start_IT(&htim3);//开启定时器3
// LCD_ShowString(0,0,dis_str);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
sConfig.Channel = ADC_CHANNEL_1; //选择通道1
HAL_ADC_ConfigChannel(&hadc1, &sConfig); //选择ADC1的通道道1
HAL_ADC_Start(&hadc1); //启动ADC1
HAL_ADC_PollForConversion(&hadc1, 10); //等待ADC1转换结束,超时设定为10ms
adcv = HAL_ADC_GetValue(&hadc1); //读取ADC1的转换结果
temp=(float)adcv*(4.0/4095)*100;
sprintf(str,"%4.0fppm",temp);
LCD_ShowString(0,0,"MV:");
LCD_ShowString(0,4,str);
HAL_UART_Transmit(&huart1, (uint8_t *)&"AL=", 3, 10); //串口1发送字符串,数组长度为12,超时10ms
HAL_UART_Transmit(&huart1, (uint8_t *)str, 6, 10); //串口1发送字符串,数组长度为5,超时10ms
HAL_UART_Transmit(&huart1, (uint8_t *)&"\n\r", 2, 10); //串口1发送字符串,数组长度为2,超时10ms
if(set_flag){//设置模式
sprintf(str,"%4.0fppm^ ",warming_val);
LCD_ShowString(1,0,"ALM:");
LCD_ShowString(1,4,str);
}else{
sprintf(str,"%4.0fppm ",warming_val);
LCD_ShowString(1,0,"ALM:");
LCD_ShowString(1,4,str);
}
HAL_UART_Transmit(&huart1, (uint8_t *)&"ALM=", 4, 10); //串口1发送字符串,数组长度为12,超时10ms
HAL_UART_Transmit(&huart1, (uint8_t *)str, 6, 10); //串口1发送字符串,数组长度为5,超时10ms
HAL_UART_Transmit(&huart1, (uint8_t *)&"\n\r", 2, 10); //串口1发送字符串,数组长度为2,超时10ms
if(temp>warming_val&&!set_flag){//如果超过报警值
HAL_GPIO_WritePin(GPIOA,BEEP_Pin, GPIO_PIN_RESET);//BEEP引脚拉低
}else{
HAL_GPIO_WritePin(GPIOA,BEEP_Pin, GPIO_PIN_SET);
}
HAL_ADC_Stop(&hadc1); //停止ADC1
HAL_Delay(300);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == htim3.Instance)
{
Tim_cnt++;
if(Tim_cnt==5) //2.5ms进一次
{
Tim_cnt=0; //请
HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
}
}
}
//中断处理
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
UNUSED(GPIO_Pin);
if(GPIO_Pin == KEY1_Pin) //测到EXTI0线产生外部中断事件
{
if(set_flag){
set_flag = 0;
}else{
set_flag = 1;
}
}
else if(GPIO_Pin == KEY2_Pin) //测到EXTI1线产生外部中断事件
{
if(set_flag){
if(warming_val<390){//一次+10
warming_val+=10;
}
}
} else if(GPIO_Pin == KEY3_Pin) //测到EXTI2线产生外部中断事件
{
if(set_flag){
if(warming_val>10){//一次-10
warming_val-=10;
}
}
}
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
4. 资料清单&下载链接
0、常见使用问题及解决方法–必读!!!!
1、程序代码
2、Proteus仿真
3、功能要求
4、讲解视频
Altium Designer 软件资料
filename.bat
KEIL软件资料
MQ135-2.jpg
MQ135.jpg
MQ系列传感器工作原理.txt
Proteus软件资料
单片机学习资料
答辩技巧
设计报告常用描述
鼠标双击打开查找更多51 STM32单片机课程毕业设计.url
资料下载链接(可点击):