系列文章目录
前言
本文设计出一款基于STM32单片机的空气质量监测系统。
主要功能如下:
1、STM32F103C8T6单片机作为主控制器。
2、DHT11温湿度传感器采集温湿度
3、监测一氧化碳浓度;监测甲醛浓度;监测PM2.5浓度;
4、阈值可以调节,超出阈值报警
5、温度超出阈值,打开风扇调温
6、OLED实时显示当前信息
7、通过ESP8266连接机智云APP,实现单片机-手机APP交互。
1 资料获取与演示视频
1.1 资料介绍
1.2 资料获取
完整资料获得链接:
咸鱼:【胜磊电子】基于STM32单片机的空气质量监测系统设计(STM32代码编写+手机APP+PCB设计+Proteus仿真)
淘宝:【胜磊电子】基于STM32单片机的空气质量监测系统设计(STM32代码编写+手机APP+PCB设计+Proteus仿真)
1.3 演示视频
哔哩哔哩:【胜磊电子】基于STM32单片机的空气质量监测系统设计(STM32代码编写+手机APP+PCB设计+Proteus仿真)
2 系统框架
2.1 系统框架
2.2 单片机整体框图
3 硬件
3.1 主控制器
主控制器选择STM32F103C8T6,在淘宝上买的,如下图所示:
STM32F103C8T6 是意法半导体(ST)推出的一款基于 ARM Cortex-M3 内核的 32 位微控制器,以下从其性能参数、功能特性、应用领域等方面进行介绍:
-
主频
最高可达 72MHz,具备 1.25DMIPS/MHz 的运算能力,能够快速处理各种指令和任务。
内核处理器:采用 ARM Cortex-M3 内核,具有高性能、低功耗的特点,支持 Thumb-2 指令集,能够高效地执行各种指令。 -
存储
拥有 64KB 的 Flash 存储器,用于存储程序代码和常量数据;20KB 的 SRAM,用于存储运行时的变量和临时数据。 -
丰富的外设接口
USART:集成了 3 个 USART(通用同步异步收发器)接口
SPI:2 个 SPI(串行外设接口)接口
I2C:2 个 I2C(Inter-Integrated Circuit)接口
USB: 1 个 USB 2.0 全速接口
定时器:包含 7 个定时器,其中包括 4 路 PWM 输出,可用于脉冲宽度调制、输入捕获、输出比较、正交编码器接口等功能,广泛应用于电机控制、脉冲信号生成等领域。
ADC(模数转换器):内置 2 个 12 位 ADC,转换时间仅为 1μs,具有 10 个通道,可对多路模拟信号进行快速采样转换,适用于各种需要采集模拟信号的场景,如传感器数据采集等。 -
时钟系统
内置 4-16MHz 的高速内部时钟(HSI)和 32KHz 的低速内部时钟(LSI),也可通过外部晶振提供更高精度的时钟源,通常包括一个 8MHz 的高速外部时钟(HSE)和一个 32.768KHz 的低速外部时钟(LSE),为芯片内部各个模块提供精确的时钟信号,确保它们能够同步工作。 -
其他功能
集成了看门狗定时器、CRC 计算单元、RTC 实时时钟、SysTick 定时器、DMA(Direct Memory Access)控制器等,进一步增强了芯片的功能和可靠性。支持 JTAG(Joint Test Action Group)和 SWD(Single Wire Debug)调试接口,方便开发人员连接调试器进行程序调试和下载,提高开发效率。
3.2 显示屏
使用1.8寸显示屏,分辨率128*160。如图,
1.8寸彩屏,支持16BIT RGB 65K彩色显示,显示色彩丰富
128X160分辨率,显示清晰
采用SPI串行总线,只需几个IO即可点亮显示
带SD卡槽方便功能扩展
军工级工艺标准,长期稳定工作
3.3 WIFI模块
WIFI模块使用ESP8266,如图,
ESP01S 是一款基于乐鑫 ESP8266EX 芯片的低成本、低功耗 Wi-Fi 模块,专为物联网(IoT)和嵌入式系统设计。
以下是其详细介绍:
-
核心架构与性能
处理器:采用 32 位 Tensilica L106 RISC 处理器,主频支持 80MHz 或 160MHz,集成 TCP/IP 协议栈,可直接运行用户程序。
内存配置:
闪存(Flash):提供 1MB 或 4MB 两种版本(具体型号差异),用于存储固件和用户代码。
RAM:64KB,支持程序运行和数据缓存。
通信协议:支持 802.11b/g/n 标准,数据传输速率最高 4Mbps,覆盖 2.4GHz 频段,支持 STA、AP、STA+AP 三种工作模式。 -
硬件资源与接口
引脚定义:
供电:3.0V~3.6V(推荐 3.3V),传输电流 170mA,接收电流 56mA。
通信:UART 接口(TXD/RXD),支持 AT 指令交互,波特率默认 115200bps。
GPIO:提供 2 个可编程引脚(GPIO0、GPIO2),可用于控制外设(如 LED、继电器)或传感器输入。
其他:CH_PD(使能引脚,高电平有效)、RST(复位引脚)。
扩展能力:
PWM:部分引脚支持 PWM 输出,用于电机调速或灯光控制。
I²C/SPI:需通过外部扩展芯片(如 PCF8574、MCP23017)实现。 -
低功耗特性
工作模式:
活跃模式:传输时电流约 170mA,接收时 56mA。
睡眠模式:
轻睡眠:电流约 10mA,保留网络连接。
深度睡眠:电流低至 20μA,适用于电池供电设备。
唤醒方式:支持定时唤醒、GPIO 触发唤醒或 UART 数据唤醒。 -
应用场景
智能家居:通过 Wi-Fi 连接控制灯光、空调、门锁等设备。
环境监测:采集温湿度、空气质量等数据并上传至云端。
工业自动化:远程监控设备状态,实现无线数据传输。
智能农业:监测土壤湿度、光照等参数,优化种植管理。
3.4 DHT11温湿度传感器
使用DHT11模块检测环境的温度和湿度。
DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大电流 0.5mA。
DHT11 的技术参数如下:
⚫ 工作电压范围:3.3V-5.5V
⚫ 工作电流 :平均 0.5mA
⚫ 输出:单总线数字信号
⚫ 测量范围:湿度 20~90%RH,温度 0~50℃
⚫ 精度 :湿度±5%,温度±2℃
⚫ 分辨率 :湿度 1%,温度 1℃
DHT11 数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由 5Byte(40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。DHT11 的数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数
数据+8bit 温度小数数据+8bit 校验和。其中校验和数据为前四个字节相加。
传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。例如,某次从 DHT11 读到的数据如图所示:
由以上数据就可得到湿度和温度的值,计算方法:
湿度= byte4 . byte3=45.0 (%RH)
温度= byte2 . byte1=28.0 ( ℃)
校验= byte4+ byte3+ byte2+ byte1=73(=湿度+温度)(校验正确)
可以看出,DHT11 的数据格式是十分简单的,DHT11 和 MCU 的一次通信最大为 3ms 左右,
建议主机连续读取时间间隔不要小于 100ms。
首先主机发送开始信号,即:拉低数据线,保持 t1(至少 18ms)时间,然后拉高数据线 t2(20~40us)时间,然后读取 DHT11 的响应,正常的话,DHT11 会拉低数据线,保持 t3(40~50us)时间,作为响应信号,然后 DHT11 拉高数据线,保持 t4(40~50us)时间后,开始输出数据。
DHT11 输出数字‘0’的时序如图所示:
DHT11 输出数字‘1’的时序如图所示:
通过以上了解,我们就可以通过 STM32 来实现对 DHT11 的读取了。
3.5 一氧化碳传感器
-
工作原理
MQ-7 传感器采用二氧化锡(SnO₂)半导体气敏材料,属于表面离子式 N 型半导体。在 200-300℃时,二氧化锡表面吸附空气中的氧,形成氧的负离子吸附,使半导体中的电子密度减少,电阻值增加。当与一氧化碳气体接触时,晶粒间界处的势垒发生变化,引起表面导电率的变化,一氧化碳浓度越大导电率越大,输出电阻越低,输出的模拟信号就越大。 -
主要参数
工作电压:DC 5V。
工作电流:150mA。
检测气体:主要检测一氧化碳,也能检测天然气、甲烷等。
检测浓度范围:一般为 10-10000ppm。
输出类型:具有 AO 模拟信号输出和 DO 开关信号输出。DO 输出为 TTL 数字量 0 和 1(0.1V 和 5V),AO 输出在相对无污染时为 0.1-0.3V,高浓度时电压约 4V。 -
模块特点
高灵敏度:能够检测低至 10ppm 的 CO 浓度。
快速响应:可在几秒钟内响应气体浓度的变化。
长寿命:可在多种环境条件下稳定工作,使用寿命长。
低成本:相对其他类型的气体传感器,成本较低。
易集成:输出为模拟信号,可通过 ADC 转换为数字信号,与微控制器系统容易集成。 -
典型应用
家庭安全:用于家庭用气体泄漏报警器,检测室内一氧化碳浓度,防止中毒。
工业安全:适用于工业用可燃气体报警器,监测工厂等场所的一氧化碳含量。
便携式检测:可作为便携式一氧化碳气体检测器的核心部件,用于现场检测。
3.6 甲醛传感器
3.7 PM2.5传感器
4 设计PCB
直接使用上述模块,线路非常杂乱,因此,我们需要自己设计一块PCB底板。开发工具使用立创EDA。
相关资料已经放在本文第一节。
4.1 安装下载立创EDA专业版
4.2 画原理图
4.3 摆放元器件,设计规则,泪滴,铺铜。
4.4 使用嘉立创下单助手进行下单,打板。
4.5 实物图
实物如图:
5 软件设计
5.1 编写STM32单片机代码
工程目录如图所示:
5.1.1 main.c
#include "board_config.h"
#include "module_config.h"
#include "lcd_app.h"
#include "sensor_app.h"
//网络协议层
#include "gizwits_product.h"
/************************************************
串口驱动
实验现象:LED1闪烁,按下按键,串口打印按键信息。
淘宝店铺:https://shop475501589.taobao.com/?spm=pc_detail.29232929/evo365560b447259.shop_block.dshopinfo.5dd97dd6JvMuG3
咸鱼店铺:https://www.goofish.com/personal?spm=a21ybx.item.itemHeader.1.c17a3da6hy8k28&userId=3890583014
哔哩哔哩:https://space.bilibili.com/482024430?spm_id_from=333.788.upinfo.detail.click
作者:胜磊电子
************************************************/
/************************************* 宏定义 *******************************************************/
/*********************************** 局部函数 *******************************************************/
// 定时器3,定时1ms
void TIMER3_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
//初始化
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
// 72MHz
TIM_TimeBaseInitStruct.TIM_Period=10-1;
TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
TIM_ClearFlag(TIM3, TIM_IT_Update);
TIM_ITConfig(TIM3, TIM_IT_Update,ENABLE);
NVIC_InitStruct.NVIC_IRQChannel=TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM3,ENABLE);
}
//机智云初始化
void MyGizwistInit(void)
{
TIMER3_Init();//1ms
// Uart2_Init(9600);//gizPutData((uint8_t *)&aRxBuffer,1);
userInit();//用户信息初始化,目前只是把结构体信息复位
gizwitsInit();//机智云的初始化
}
/*
************************************************************
* 函数名称: main
*
* 函数功能:
*
* 入口参数: 无
*
* 返回参数: 0
*
* 说明:
************************************************************
*/
int main(void)
{
unsigned short timeCount = 0; //发送间隔变量
// 初始化所有外设
BOARD_InitAll();
// 初始化模块
MODULE_InitAll();
//APP初始化
MyGizwistInit();
gizwitsSetMode(WIFI_AIRLINK_MODE);
DelayMs(2000);
/* 1、显示不变量 */
LCD_Display_Init();
while (1) {
/* 2、系统轮询 */
LCD_StatusPOLL();
// MQTT 数据发送
if(++timeCount >= 200) //发送间隔5s
{
/* 3、得到传感器数据 */
Sensor_GetValueAll();
timeCount = 0;
// 闪烁LED1
LED_Toggle(&BOARD_LED2);
}
/* 4、更新传感器数据 */
LCD_Refresh_Data();
/* 5、报警检测 */
Sensor_AlarmDetection();
/* 6、APP */
userHandle(); // 数据上行
gizwitsHandle((dataPoint_t *)¤tDataPoint); // 将报文,发送到APP
DelayMs(10);
}
}
5.1.2 board_config.c
#include "board_config.h"
/************************************************
淘宝店铺:https://shop475501589.taobao.com/?spm=pc_detail.29232929/evo365560b447259.shop_block.dshopinfo.5dd97dd6JvMuG3
咸鱼店铺:https://www.goofish.com/personal?spm=a21ybx.item.itemHeader.1.c17a3da6hy8k28&userId=3890583014
哔哩哔哩:https://space.bilibili.com/482024430?spm_id_from=333.788.upinfo.detail.click
作者:胜磊电子
************************************************/
/**
* @file board_config.c
* @brief 开发板外设配置与初始化
* @details 本文件实现了开发板上所有外设的配置与初始化函数,
* 包括LED、蜂鸣器、按键、SPI、USART等模块的初始化。
*/
/************************************* 变量定义 *******************************************************/
/**
* @brief 开发板LED对象定义
* @details 定义了开发板上三个LED的控制结构体
*/
LED_TypeDef BOARD_LED1; /**< 开发板LED1对象 (PB0) */
LED_TypeDef BOARD_LED2; /**< 开发板LED2对象 (PB1) */
/**
* @brief 开发板蜂鸣器对象定义
* @details 定义了开发板上蜂鸣器的控制结构体
*/
Beep_TypeDef BOARD_BEEP; /**< 开发板蜂鸣器对象 (PB8) */
/**
* @brief SPI2接口配置结构体
* @details 配置SPI2接口的参数,包括GPIO引脚、通信模式、时钟参数等
*/
SPI_ConfigTypeDef BOARD_SPI2 = {
// 配置SPI接口
.SPIx = SPI2, /**< SPI外设选择:SPI2 */
.GPIOx = GPIOB, /**< SPI2使用的GPIO端口:GPIOB */
.SCK_Pin = GPIO_Pin_13, /**< SCK引脚:PB13 */
.MISO_Pin = GPIO_Pin_14, /**< MISO引脚:PB14 */
.MOSI_Pin = GPIO_Pin_15, /**< MOSI引脚:PB15 */
.RCC_APBxPeriph_SPI = RCC_APB1Periph_SPI2, /**< SPI2时钟使能:APB1总线 */
.RCC_APBxPeriph_GPIO = RCC_APB2Periph_GPIOB, /**< GPIO时钟使能:APB2总线 */
// 配置SPI初始化结构体
.SPI_InitStruct = {
.SPI_Direction = SPI_Direction_2Lines_FullDuplex, /**< 双线全双工模式 */
.SPI_Mode = SPI_Mode_Master, /**< 主模式 */
.SPI_DataSize = SPI_DataSize_8b, /**< 8位数据格式 */
.SPI_CPOL = SPI_CPOL_Low, /**< 时钟极性:空闲低电平 */
.SPI_CPHA = SPI_CPHA_1Edge, /**< 时钟相位:第一个边沿采样 */
.SPI_NSS = SPI_NSS_Soft, /**< 软件片选控制 */
.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2, /**< 波特率预分频:2分频 */
.SPI_FirstBit = SPI_FirstBit_MSB, /**< 高位先行 */
.SPI_CRCPolynomial = 7 /**< CRC多项式:7 */
}
};
/**
* @brief 开发板按键配置数组
* @details 定义了开发板上4个按键的配置参数,包括GPIO、中断设置等
*/
Key_InitTypeDef BOARD_KEYS[] = {
{
RCC_APB2Periph_GPIOA, /**< GPIO时钟使能:GPIOA */
GPIOA, /**< GPIO端口:GPIOA */
GPIO_Pin_0, /**< 引脚:PA0 */
GPIO_PortSourceGPIOA, /**< 端口源:GPIOA */
GPIO_PinSource0, /**< 引脚源:Pin0 */
EXTI_Line0, /**< 外部中断线:Line0 */
EXTI0_IRQn, /**< 中断号:EXTI0_IRQn */
2, /**< 抢占优先级:2 */
1, /**< 子优先级:1 */
EXTI_Trigger_Rising, /**< 触发方式:上升沿触发 */
GPIO_Mode_IPD /**< GPIO模式:下拉输入 */
},
{
RCC_APB2Periph_GPIOC, /**< GPIO时钟使能:GPIOC */
GPIOC, /**< GPIO端口:GPIOC */
GPIO_Pin_13, /**< 引脚:PC5 */
GPIO_PortSourceGPIOC, /**< 端口源:GPIOC */
GPIO_PinSource13, /**< 引脚源:Pin5 */
EXTI_Line13, /**< 外部中断线:Line5 */
EXTI15_10_IRQn, /**< 中断号:EXTI9_5_IRQn */
2, /**< 抢占优先级:2 */
2, /**< 子优先级:2 */
EXTI_Trigger_Falling, /**< 触发方式:下降沿触发 */
GPIO_Mode_IPU /**< GPIO模式:上拉输入 */
},
{
RCC_APB2Periph_GPIOC, /**< GPIO时钟使能:GPIOC */
GPIOC, /**< GPIO端口:GPIOC */
GPIO_Pin_14, /**< 引脚:PC6 */
GPIO_PortSourceGPIOC, /**< 端口源:GPIOC */
GPIO_PinSource14, /**< 引脚源:Pin6 */
EXTI_Line14, /**< 外部中断线:Line6 */
EXTI15_10_IRQn, /**< 中断号:EXTI9_5_IRQn */
2, /**< 抢占优先级:2 */
2, /**< 子优先级:2 */
EXTI_Trigger_Falling, /**< 触发方式:下降沿触发 */
GPIO_Mode_IPU /**< GPIO模式:上拉输入 */
},
{
RCC_APB2Periph_GPIOC, /**< GPIO时钟使能:GPIOC */
GPIOC, /**< GPIO端口:GPIOC */
GPIO_Pin_15, /**< 引脚:PC7 */
GPIO_PortSourceGPIOC, /**< 端口源:GPIOC */
GPIO_PinSource15, /**< 引脚源:Pin7 */
EXTI_Line15, /**< 外部中断线:Line7 */
EXTI15_10_IRQn, /**< 中断号:EXTI9_5_IRQn */
2, /**< 抢占优先级:2 */
2, /**< 子优先级:2 */
EXTI_Trigger_Falling, /**< 触发方式:下降沿触发 */
GPIO_Mode_IPU /**< GPIO模式:上拉输入 */
}
};
/**
* @brief 按键数量常量
* @details 计算并存储按键配置数组的元素个数
*/
const uint8_t BOARD_KEYS_NUM = sizeof(BOARD_KEYS) / sizeof(BOARD_KEYS[0]);
ADC_ConfigTypeDef adc_config = {
.GPIOx = GPIOA,
.GPIO_Clock = RCC_APB2Periph_GPIOA,
.GPIO_Pins = GPIO_Pin_4,
.Channel_Num = 1,
.Channels = {ADC_Channel_4},
.ADCx = ADC1,
.ADC_Clock = RCC_APB2Periph_ADC1,
.ADC_Prescaler = RCC_PCLK2_Div6 // 72MHz/6=12MHz
};
/************************************* 局部初始化函数 *******************************************************/
/**
* @brief 初始化开发板LED
* @details 配置开发板上LED的GPIO引脚,使其可以被控制
* @return 无
*/
static void BOARD_InitLEDs(void) {
// 初始化LED1 (PB0)
LED_Init(&BOARD_LED1, GPIOB, GPIO_Pin_0);
// 初始化LED2 (PB1)
LED_Init(&BOARD_LED2, GPIOB, GPIO_Pin_1);
}
/**
* @brief 初始化开发板蜂鸣器
* @details 配置开发板上蜂鸣器的GPIO引脚,使其可以被控制
* @return 无
*/
static void BOARD_InitBeep(void) {
// 初始化蜂鸣器 (PB8)
Beep_Init(&BOARD_BEEP, GPIOB, GPIO_Pin_8);
}
/**
* @brief 初始化延时模块
* @details 配置系统延时功能,选择指定的定时器作为延时基准
* @param timer 选择的定时器编号 (如1代表TIM2)
* @return 无
*/
static void BOARD_InitDelay(uint8_t timer) {
// 初始化延时模块,选择TIM2作为定时器
Delay_Init(timer);
}
/**
* @brief 初始化开发板USART
* @details 配置开发板上的USART1和USART2串口,设置波特率、引脚等参数
* @return 无
*/
static void BOARD_InitUSART(void) {
// 配置USART1初始化参数
USART_InitParams usart1_params = {
.USARTx = USART1, /**< USART外设:USART1 */
.RCC_APBxPeriph_USART = RCC_APB2Periph_USART1, /**< USART1时钟使能:APB2总线 */
.RCC_APBxPeriph_GPIO = RCC_APB2Periph_GPIOA, /**< GPIO时钟使能:APB2总线 */
.GPIO_Pin_Tx = GPIO_Pin_9, /**< TX引脚:PA9 */
.GPIO_Pin_Rx = GPIO_Pin_10, /**< RX引脚:PA10 */
.NVIC_IRQChannel = USART1_IRQn, /**< 中断号:USART1_IRQn */
.NVIC_IRQChannelPreemptionPriority = 0, /**< 抢占优先级:0 */
.NVIC_IRQChannelSubPriority = 2 /**< 子优先级:2 */
};
// 配置USART2初始化参数
USART_InitParams usart2_params = {
.USARTx = USART2, /**< USART外设:USART2 */
.RCC_APBxPeriph_USART = RCC_APB1Periph_USART2, /**< USART2时钟使能:APB1总线 */
.RCC_APBxPeriph_GPIO = RCC_APB2Periph_GPIOA, /**< GPIO时钟使能:APB2总线 */
.GPIO_Pin_Tx = GPIO_Pin_2, /**< TX引脚:PA2 */
.GPIO_Pin_Rx = GPIO_Pin_3, /**< RX引脚:PA3 */
.NVIC_IRQChannel = USART2_IRQn, /**< 中断号:USART2_IRQn */
.NVIC_IRQChannelPreemptionPriority = 0, /**< 抢占优先级:0 */
.NVIC_IRQChannelSubPriority = 0 /**< 子优先级:0 */
};
// 配置USART3初始化参数
USART_InitParams usart3_params = {
.USARTx = USART3, /**< USART外设:USART2 */
.RCC_APBxPeriph_USART = RCC_APB1Periph_USART3, /**< USART2时钟使能:APB1总线 */
.RCC_APBxPeriph_GPIO = RCC_APB2Periph_GPIOB, /**< GPIO时钟使能:APB2总线 */
.GPIO_Pin_Tx = GPIO_Pin_10, /**< TX引脚:PA2 */
.GPIO_Pin_Rx = GPIO_Pin_11, /**< RX引脚:PA3 */
.NVIC_IRQChannel = USART3_IRQn, /**< 中断号:USART2_IRQn */
.NVIC_IRQChannelPreemptionPriority = 0, /**< 抢占优先级:0 */
.NVIC_IRQChannelSubPriority = 0 /**< 子优先级:0 */
};
// 初始化USART1,波特率为115200
Usart_Init(&usart1_params, 9600);
// 初始化USART2,波特率为115200
Usart_Init(&usart2_params, 9600);
// 初始化USART3,波特率为115200
Usart_Init(&usart3_params, 9600);
}
/**
* @brief 初始化开发板按键
* @details 配置开发板上按键的GPIO和中断参数,使其可以触发中断
* @return 无
*/
static void BOARD_InitKeys(void) {
Key_Init(BOARD_KEYS, BOARD_KEYS_NUM);
}
/**
* @brief 初始化开发板SPI
* @details 配置开发板上的SPI2接口,使用先前定义的配置结构体
* @return 无
*/
static void BOARD_InitSPI(void) {
// 初始化SPI2
SPI_Generic_Init(&BOARD_SPI2);
}
/**
* @brief 初始化板载ADC
* @details 初始化板载ADC,配置GPIO引脚和通道
* @return 无
*/
static void BOARD_InitADC(void) {
if (Adc_Init(&adc_config) != 0) {
// 处理初始化失败的情况
while(1); // 这里可以添加错误处理代码
}
}
/************************************* 全局初始化函数 *******************************************************/
/**
* @brief 初始化开发板上的所有外设
* @details 调用各个外设的初始化函数,完成整个开发板的初始化工作
* @return 无
*/
void BOARD_InitAll(void) {
// 配置中断优先级分组为2 (2位抢占优先级,2位子优先级)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// 初始化LED
BOARD_InitLEDs();
// 初始化蜂鸣器
BOARD_InitBeep();
// 使用TIM2作为延时定时器
BOARD_InitDelay(1);
// 初始化USART
BOARD_InitUSART();
// 初始化按键
BOARD_InitKeys();
// 初始化SPI
BOARD_InitSPI();
// 初始化ADC
BOARD_InitADC();
}
5.1.3 board_config.h
#ifndef BOARD_CONFIG_H
#define BOARD_CONFIG_H
#include "led.h"
#include "beep.h"
#include "delay.h"
#include "usart.h"
#include "key.h"
#include "spi.h"
#include "adc.h"
/************************************************
淘宝店铺:https://shop475501589.taobao.com/?spm=pc_detail.29232929/evo365560b447259.shop_block.dshopinfo.5dd97dd6JvMuG3
咸鱼店铺:https://www.goofish.com/personal?spm=a21ybx.item.itemHeader.1.c17a3da6hy8k28&userId=3890583014
哔哩哔哩:https://space.bilibili.com/482024430?spm_id_from=333.788.upinfo.detail.click
作者:胜磊电子
************************************************/
#define USART_DEBUG USART1 //调试打印所使用的串口组
// 按键中断处理函数声明
#define KEYUP_IRQHandler EXTI0_IRQHandler
#define KEY012_IRQHandler EXTI15_10_IRQHandler
// 导出LED对象供外部使用
extern LED_TypeDef BOARD_LED1;
extern LED_TypeDef BOARD_LED2;
// 导出蜂鸣器对象供外部使用
extern Beep_TypeDef BOARD_BEEP;
// 按键配置 - 可在board_config.c中修改
extern Key_InitTypeDef BOARD_KEYS[];
extern const uint8_t BOARD_KEYS_NUM;
// 板子初始化函数
void BOARD_InitAll(void);
#endif /* BOARD_CONFIG_H */
5.2手机APP
手机APP主页面:
6 proteus仿真
本系统使用proteus9.0
进行仿真测试。
完整视频请看本文1.3
演示视频
7 实验测试
7.1 准备
1、准备好硬件实物,接好传感器和其他外设。
2、将TFT LCD插在底板响应位置。
3、ESP8266插在相应位置。
4、在手机端安装APP。
5、上电
7.2 烧录软件
下载代码需要提前安装好MDK环境,准备好SWD下载器,在MDK中进行“LOAD”下载。
7.3 实验验证
1、 proteus仿真测试
2、温湿度测试
3、一氧化碳测试;甲醛测试;PM2.5测试
4、阈值调节,报警测试
5、温度超出阈值,风扇调温测试
6、单片机-手机APP交互测试
演示视频:
基于STM32单片机的空气质量检测系统设计(STM32代码编写+手机APP设计+PCB设计+Proteus仿真)