全部资料:可定制
基于STM32的火灾烟雾报警器
1. 烟雾采集传感器选用MQ-2,由于该传感器输出的是模拟信号,STM32内部ADC将模拟信号转为数字信号。
2. 温度采集使用DS18B20数字传感器,温度测量范围-55到128℃,测量精度±0.1℃;
3. 显示设备使用1602液晶,可以在屏幕上显示实时烟雾浓度值、温度值,以及报警值等信息;
4. 报警模块则采用蜂鸣器和LED灯组成,两个LED分别代表了烟雾报警指示和温度报警指示,无论哪个检测元素超标,蜂鸣器都会鸣叫报警;
5. 设计采用3个按键作为操作输入设备,可以用来调节报警阈值的大小;
6.串口实时发送温度检测值、烟雾浓度测量值和报警信息给PC机。
主要硬件设备:STM32F103C8T6+LCD1602+DS18B20+蜂鸣器
基于STM32的火灾烟雾报警器设计
摘要:
随着现代社会的快速发展,火灾安全问题日益受到人们的重视。火灾烟雾报警器作为火灾预警的重要设备,其准确性和可靠性对于保障人民生命财产安全具有重要意义。本文设计了一种基于STM32单片机的火灾烟雾报警器,通过MQ-2烟雾传感器和DS18B20温度传感器采集环境数据,利用1602液晶显示实时信息,并通过蜂鸣器和LED灯实现报警功能。同时,设计了按键模块用于调节报警阈值,并通过串口通信将检测数据实时发送给PC机。该系统具有结构简单、成本低廉、易于扩展等优点,具有较高的实用价值。
关键词:STM32;火灾烟雾报警器;MQ-2传感器;DS18B20传感器;1602液晶
Abstract:
With the rapid development of modern society, fire safety issues have increasingly attracted people's attention. As an important device for fire warning, the accuracy and reliability of fire smoke alarms are of great significance for safeguarding people's lives and property. This paper designs a fire smoke alarm based on the STM32 microcontroller, which collects environmental data through MQ-2 smoke sensors and DS18B20 temperature sensors, displays real-time information using a 1602 LCD, and implements alarm functions through buzzers and LED lights. At the same time, a keypad module is designed to adjust the alarm thresholds, and serial communication is used to send detection data to a PC in real-time. The system has the advantages of simple structure, low cost, and easy expansion, making it highly practical.
Keywords: STM32; Fire Smoke Alarm; MQ-2 Sensor; DS18B20 Sensor; 1602 LCD
一、引言
火灾是一种严重的灾害,具有突发性强、蔓延速度快、危害范围广等特点。为了有效预防火灾的发生,及时发现并处理火灾隐患,火灾烟雾报警器应运而生。传统的火灾烟雾报警器多采用离子感烟或光电感烟原理,虽然在一定程度上能够检测到火灾烟雾,但存在误报率高、稳定性差等问题。随着微电子技术、传感器技术和嵌入式技术的不断发展,基于单片机的智能火灾烟雾报警器逐渐成为研究热点。
STM32系列单片机作为ARM Cortex-M内核的32位微控制器,具有高性能、低功耗、易于编程等优点,广泛应用于工业自动化、智能家居、医疗设备等领域。本文设计了一种基于STM32单片机的火灾烟雾报警器,通过MQ-2烟雾传感器和DS18B20温度传感器采集环境数据,利用1602液晶显示实时信息,并通过蜂鸣器和LED灯实现报警功能。同时,设计了按键模块用于调节报警阈值,并通过串口通信将检测数据实时发送给PC机。该系统具有结构简单、成本低廉、易于扩展等优点,具有较高的实用价值。
二、系统总体设计
2.1 系统功能需求
本系统主要实现以下功能:
- 烟雾采集:通过MQ-2烟雾传感器采集环境中的烟雾浓度,并将模拟信号转换为数字信号进行处理。
- 温度采集:通过DS18B20温度传感器采集环境温度,测量范围在-55℃到128℃之间,测量精度为±0.1℃。
- 显示功能:通过1602液晶显示实时烟雾浓度值、温度值以及报警值等信息。
- 报警功能:当烟雾浓度或温度超过设定的阈值时,蜂鸣器鸣叫报警,同时对应的LED灯点亮。
- 按键调节:通过3个按键可以分别调节烟雾报警阈值、温度报警阈值和切换显示模式。
- 串口通信:通过串口实时发送温度检测值、烟雾浓度测量值和报警信息给PC机。
2.2 系统总体架构
本系统以STM32单片机为核心,通过MQ-2烟雾传感器和DS18B20温度传感器采集环境数据,利用1602液晶显示实时信息,并通过蜂鸣器和LED灯实现报警功能。同时,设计了按键模块用于调节报警阈值,并通过串口通信将检测数据实时发送给PC机。系统总体架构如图2.1所示。
<img src="https://example.com/system_architecture.png" />
图2.1 系统总体架构图
三、硬件设计
3.1 STM32单片机
STM32系列单片机是意法半导体(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器。本系统选用STM32F103C8T6型号单片机,该单片机具有丰富的外设资源,包括ADC、SPI、I2C、USART等接口,能够满足本系统对数据采集、显示、报警和通信的需求。
3.2 MQ-2烟雾传感器
MQ-2烟雾传感器是一种常用的气体传感器,对烟雾、液化气、天然气等可燃性气体具有较高的灵敏度。该传感器采用模拟信号输出,输出电压与烟雾浓度成正比。本系统通过STM32单片机的ADC接口采集MQ-2传感器的输出信号,并将其转换为数字信号进行处理。
3.3 DS18B20温度传感器
DS18B20温度传感器是一种常用的数字温度传感器,具有测量范围广、测量精度高、抗干扰能力强等优点。该传感器采用单总线通信协议,通过一根数据线即可实现与STM32单片机的通信。本系统通过STM32单片机的SPI接口与DS18B20传感器进行通信,读取环境温度值。
3.4 1602液晶显示模块
1602液晶显示模块是一种常用的字符型液晶显示器件,具有显示内容丰富、功耗低、体积小等优点。该模块采用并行接口与STM32单片机进行通信,可以显示两行16个字符的文本信息。本系统通过STM32单片机的GPIO接口控制1602液晶显示模块,实时显示烟雾浓度值、温度值以及报警值等信息。
3.5 报警模块
报警模块由蜂鸣器和LED灯组成。当烟雾浓度或温度超过设定的阈值时,蜂鸣器鸣叫报警,同时对应的LED灯点亮。本系统通过STM32单片机的GPIO接口控制蜂鸣器和LED灯的工作状态。
3.6 按键模块
按键模块由3个独立按键组成,分别用于调节烟雾报警阈值、温度报警阈值和切换显示模式。本系统通过STM32单片机的GPIO接口读取按键的状态,并根据按键的操作进行相应的处理。
3.7 串口通信模块
串口通信模块用于将STM32单片机采集到的温度检测值、烟雾浓度测量值和报警信息实时发送给PC机。本系统通过STM32单片机的USART接口实现与PC机的串口通信。
四、软件设计
4.1 主程序设计
主程序是系统的核心部分,负责初始化各个模块、采集环境数据、处理数据、显示信息、控制报警和通信等功能。主程序流程图如图4.1所示。
<img src="https://example.com/main_program_flowchart.png" />
图4.1 主程序流程图
在主程序中,首先进行STM32单片机的初始化,包括时钟配置、GPIO配置、ADC配置、SPI配置、USART配置等。然后,进入主循环,不断采集MQ-2烟雾传感器和DS18B20温度传感器的输出信号,并进行数据处理。接着,将处理后的数据通过1602液晶显示出来,并根据数据判断是否触发报警条件。如果触发报警条件,则控制蜂鸣器和LED灯进行报警。最后,通过串口将检测数据实时发送给PC机。
4.2 ADC采集程序设计
ADC采集程序用于采集MQ-2烟雾传感器的输出信号,并将其转换为数字信号进行处理。ADC采集程序流程图如图4.2所示。
<img src="https://example.com/adc_acquisition_flowchart.png" />
图4.2 ADC采集程序流程图
在ADC采集程序中,首先进行ADC模块的初始化,包括时钟配置、ADC通道配置、采样时间配置等。然后,启动ADC转换,并等待转换完成。接着,读取ADC转换结果,并进行数据处理,得到烟雾浓度值。最后,将烟雾浓度值存储在全局变量中,供后续程序使用。
4.3 SPI通信程序设计
SPI通信程序用于实现STM32单片机与DS18B20温度传感器的通信。SPI通信程序流程图如图4.3所示。
<img src="https://example.com/spi_communication_flowchart.png" />
图4.3 SPI通信程序流程图
在SPI通信程序中,首先进行SPI模块的初始化,包括时钟配置、主从模式配置、数据格式配置等。然后,通过SPI接口向DS18B20传感器发送温度转换命令,并等待转换完成。接着,通过SPI接口读取DS18B20传感器的温度值,并进行数据处理,得到环境温度值。最后,将环境温度值存储在全局变量中,供后续程序使用。
4.4 1602液晶显示程序设计
1602液晶显示程序用于实时显示烟雾浓度值、温度值以及报警值等信息。1602液晶显示程序流程图如图4.4所示。
<img src="https://example.com/1602_lcd_display_flowchart.png" />
图4.4 1602液晶显示程序流程图
602液晶显示程序中,首先进行1602液晶模块的初始化,包括设置显示模式、清屏等操作。然后,根据全局变量中的烟雾浓度值和温度值,格式化显示字符串。接着,通过GPIO接口将显示字符串发送到1602液晶模块,实现实时显示功能。如果触发报警条件,还需要在显示字符串中添加报警信息。
4.5 报警程序设计
报警程序用于在烟雾浓度或温度超过设定的阈值时控制蜂鸣器和LED灯进行报警。报警程序流程图如图4.5所示。
<img src="https://example.com/alarm_program_flowchart.png" />
图4.5 报警程序流程图
在报警程序中,首先读取全局变量中的烟雾浓度值和温度值,并与设定的阈值进行比较。如果烟雾浓度超过烟雾报警阈值,或者温度超过温度报警阈值,则控制对应的LED灯点亮。同时,启动蜂鸣器进行鸣叫报警。如果烟雾浓度和温度均未超过设定的阈值,则关闭LED灯和蜂鸣器。
4.6 按键处理程序设计
按键处理程序用于处理用户通过按键输入的操作指令。按键处理程序流程图如图4.6所示。
<img src="https://example.com/keypad_processing_flowchart.png" />
图4.6 按键处理程序流程图
在按键处理程序中,首先进行按键去抖动处理,确保按键状态的稳定性。然后,读取按键的状态,并根据按键的操作进行相应的处理。例如,如果按下调节烟雾报警阈值的按键,则增加或减少烟雾报警阈值;如果按下调节温度报警阈值的按键,则增加或减少温度报警阈值;如果按下切换显示模式的按键,则切换显示内容。
4.7 串口通信程序设计
串口通信程序用于将STM32单片机采集到的温度检测值、烟雾浓度测量值和报警信息实时发送给PC机。串口通信程序流程图如图4.7所示。
<img src="https://example.com/serial_communication_flowchart.png" />
图4.7 串口通信程序流程图
在串口通信程序中,首先进行USART模块的初始化,包括波特率配置、数据位配置、停止位配置等。然后,将全局变量中的温度检测值、烟雾浓度测量值和报警信息格式化为字符串。接着,通过USART接口将字符串发送给PC机。为了实现实时通信,该程序需要在主循环中不断执行。
五、系统测试与验证
5.1 测试环境搭建
为了对系统进行测试与验证,需要搭建一个测试环境。测试环境包括STM32单片机开发板、MQ-2烟雾传感器、DS18B20温度传感器、1602液晶显示模块、蜂鸣器、LED灯、按键模块、PC机等设备。将这些设备按照系统架构连接起来,并编写相应的测试程序。
5.2 功能测试
功能测试用于验证系统是否满足设计要求。测试内容包括:
- 烟雾采集功能:在测试环境中点燃香烟产生烟雾,观察1602液晶显示的烟雾浓度值是否逐渐增加,并触发烟雾报警。
- 温度采集功能:将DS18B20温度传感器置于不同温度的环境中,观察1602液晶显示的温度值是否准确,并触发温度报警(如需要)。
- 显示功能:观察1602液晶显示的烟雾浓度值、温度值以及报警信息是否清晰可读。
- 报警功能:在触发烟雾报警或温度报警时,观察蜂鸣器是否鸣叫报警,对应的LED灯是否点亮。
- 按键调节功能:通过按键调节烟雾报警阈值和温度报警阈值,观察1602液晶显示的阈值是否发生变化。
- 串口通信功能:通过串口调试助手观察PC机接收到的温度检测值、烟雾浓度测量值和报警信息是否正确。
5.3 性能测试
性能测试用于评估系统的稳定性和可靠性。测试内容包括:
- 长时间运行测试:将系统置于测试环境中连续运行数小时或数天,观察系统是否稳定工作,无异常现象发生。
- 干扰测试:在测试环境中加入电磁干扰、机械振动等干扰因素,观察系统是否能够正常工作,报警功能是否准确可靠。
- 精度测试:使用标准烟雾发生器和温度计对系统进行校准,观察系统测量的烟雾浓度值和温度值是否准确可靠。
六、结论与展望
本文设计了一种基于STM32单片机的火灾烟雾报警器,通过MQ-2烟雾传感器和DS18B20温度传感器采集环境数据,利用1602液晶显示实时信息,并通过蜂鸣器和LED灯实现报警功能。同时,设计了按键模块用于调节报警阈值,并通过串口通信将检测数据实时发送给PC机。该系统具有结构简单、成本低廉、易于扩展等优点,具有较高的实用价值。
经过测试与验证,该系统能够准确采集环境中的烟雾浓度和温度值,并在触发报警条件时及时发出报警信号。同时,该系统具有良好的稳定性和可靠性,能够满足实际应用的需求。
展望未来,可以进一步优化系统的性能,提高测量的准确性和稳定性。例如,可以采用更先进的传感器技术来提高测量的精度和灵敏度;可以采用更高效的算法来处理采集到的数据;可以设计更加人性化的用户界面来提高用户体验。此外,还可以将系统与智能家居系统相结合,实现远程监控和报警功能,进一步提高火灾预警的智能化水平。
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 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 "core_cm3.h"
#include "stdio.h"
#include "string.h"
#include "ds18b20.h"
#include "System.h"
#include "lcd1602.h"
#include "math.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
int16_t temp_H,smoke_H;
uint8_t setnum=0;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define LED_ON 0
#define LED_OFF 1
#define BEEP PAout(8)
#define LED1 PBout(6)
#define LED2 PBout(7)
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* 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 */
char data_str1[20];
// char data_str2[20];
char data_str2[]="L:000C H:000C ";
float temp;
char str[20]; //温度值转换为字符串的存放数组
float adc_temp;
uint32_t adcv; //存放ADC转换结果
ADC_ChannelConfTypeDef sConfig = {0}; //建立sConfig结构体
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* 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_USART1_UART_Init();
MX_TIM2_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
// printf("DS18B20测温实验\n\r");
HAL_UART_Transmit(&huart1, (uint8_t *)&"DS18B20_MQ-2\r\n", 13, 10); //串口1发送字符串,数组长度为10,
LCD_Init(); //LCD1602初始化
temp_H=100;smoke_H=10; //默认报警值 //默认温度阈值20-40
// DS18B20_Get_Temp();
// HAL_TIM_Base_Start_IT(&htim2); //初始化定时器
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(500);
sConfig.Channel = ADC_CHANNEL_8; //选择通道1
HAL_ADCEx_Calibration_Start(&hadc1); //开启adc前校准一下ADC
HAL_ADC_ConfigChannel(&hadc1, &sConfig); //选择ADC1的通道1
HAL_ADC_Start(&hadc1); //启动ADC1
HAL_ADC_PollForConversion(&hadc1, 30); //等待ADC1转换结束,超时设定为10ms
adcv = HAL_ADC_GetValue(&hadc1); //读取ADC1的转换结果
sprintf(str,"adc_value=%d\r\n",adcv);
// HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), 20);//串口1发送字符串,数组长度为strlen(str),超时20ms
memset(str,0,strlen(str));
// adc_temp=(float)adcv*(3.3/4095);
// adc_temp= pow(11.5428*35.904*adc_temp/(25.5-5.1*adc_temp),(1/0.6549));//计算公式源自https://blog.csdn.net/qq_35952136/article/details/95589074
adc_temp=(float)adcv*(100.0/4095);
#if 0
sprintf(str,"%0.2f",adc_temp);
HAL_UART_Transmit(&huart1, (uint8_t *)&"vote=", 5, 10); //串口1发送字符串,数组长度为12,超时10ms
HAL_UART_Transmit(&huart1, (uint8_t *)str, 6, 10); //串口1发送字符串,数组长度为5,超时10ms
HAL_UART_Transmit(&huart1, (uint8_t *)&"V\r\n", 3, 10); //串口1发送字符串,数组长度为2,超时10ms
#else
sprintf(str,"smoke=%0.1f%%\r\n",adc_temp);
HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), 10);//串口1发送字符串,数组长度为strlen(str),超时20ms
memset(str,0,strlen(str));
#endif
HAL_ADC_Stop(&hadc1); //停止ADC1
temp=DS18B20_Get_Temp();//获取温度值
sprintf(str,"temp=%0.1fC\r\n",temp);
HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), 10); //串口1发送字符串,数组长度为6,超时10ms
memset(str,0,strlen(str));
if(setnum==0){//正常模式
// sprintf(data_str1,"temp=%0.1fC \n",temp); //写字符到data_str1
sprintf(data_str1,"T=%0.1fC G=%0.1f%% \n",temp,adc_temp);
sprintf(data_str2,"TH:%d C GH:%d %% \n",temp_H,smoke_H);//写字符到data_str2
if(adc_temp>(float)smoke_H){
LED2=LED_ON;
HAL_UART_Transmit(&huart1, (uint8_t *)&"SMOKE!!\r\n", 10, 10); //串口1发送字符串,数组长度为10,超时10ms
}else{
LED2=LED_OFF;
}
if(temp>(float)temp_H){
LED1=LED_ON;
HAL_UART_Transmit(&huart1, (uint8_t *)&"TEMP!!\r\n", 10, 10); //串口1发送字符串,数组长度为10,超时10ms
}else{
LED1=LED_OFF;
}
if (LED1==LED_ON||LED2==LED_ON){
BEEP=1;
}else{
BEEP=0;
}
}else if(setnum==1){ //设置高温阈值
BEEP=0;LED1=LED2=LED_OFF;
sprintf(data_str1,"T=%0.1fC G=%0.1f%% \n",temp,adc_temp);
sprintf(data_str2,"TH:%dC< GH:%d %% \n",temp_H,smoke_H);
}else if(setnum==2){ //设置低温阈值
sprintf(data_str1,"T=%0.1fC G=%0.1f%% \n",temp,adc_temp);
sprintf(data_str2,"L:%d C H:%d%%< \n",temp_H,smoke_H);
}
LCD_ShowString(0,0,data_str1); //LCD1602显示第一行
LCD_ShowString(1,0,data_str2); //LCD1602显示第二行
memset(str,0,strlen(data_str1));
}
/* 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_DIV2;
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_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
//void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
//{
// if(htim == &htim2) //定时器2中断
// {
//
// }
//}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if(GPIO_Pin == GPIO_PIN_13){ /*检测到EXTI13线产生外部中断事件*/
setnum++;
if(setnum > 2){//按下次数超过2次,退出设置
setnum=0;
}
}
else if(GPIO_Pin == GPIO_PIN_14){ /*检测到EXTI14线产生外部中断事件*/
if(setnum == 2){
if(smoke_H<100)
smoke_H++;
}
if(setnum == 1){
if(temp_H<125)
temp_H++;
}
}
else if(GPIO_Pin == GPIO_PIN_15){ /*检测到EXTI15线产生外部中断事件*/
if(setnum ==2){
if(smoke_H>1)
smoke_H--;
}
if(setnum == 1){
if(temp_H>-55)
temp_H--;
}
}
}
//int fputc(int ch, FILE *f)
//{
// HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
// return ch;
//}
/* 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 */
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,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */