Journal Article

GD32F407 + FreeRTOS 智能家居环境监测系统

基于GD32F407和FreeRTOS的智能家居系统,集成16个任务、10+种传感器和执行器,包含HMI串口屏交互、MPU6050姿态检测、RC522 RFID、WS2812B灯效和蜂鸣器音乐播放器,曾获海南省职业技能竞赛嵌入式赛道二、三等奖。

19 min2 views

GD32F407 + FreeRTOS 智能家居环境监测系统

项目地址:GitHub - GD32andFREERTOS

项目概述

基于 GD32F407 (Cortex-M4F, 168MHz) 与 FreeRTOS 实时操作系统的模块化智能家居与环境监测系统,集成 10+ 种传感器与执行器,通过 USART HMI 串口屏进行人机交互。

核心亮点:

  • 获海南省职业技能竞赛嵌入式赛道二等奖和三等奖
  • 16个 FreeRTOS 任务并行运行
  • 自定义 HMI 二进制协议 + ASCII 命令系统
  • 多种滤波算法:卡尔曼滤波、中值滤波、移动平均
参数
MCUGD32F407 (Cortex-M4F, 168MHz)
RTOSFreeRTOS V202212.01
Tick1000Hz (1ms)
Heap17KB (heap_4.c)
最高优先级5级
交互终端USART2 HMI (9600bps)
调试串口USART0 (115200bps)

系统架构

code
┌─────────────────────────────────────────────┐
│                  USART HMI 串口屏             │
│               (USART2, 9600bps)              │
└────────────────┬────────────────────────────┘
                 │ HMI 协议 (FE + ASCII)
┌────────────────┴────────────────────────────┐
│               FreeRTOS 调度器                 │
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐       │
│  │DHT11 │ │BH1750│ │DS18B │ │HX711 │        │
│  │任务   │ │任务   │ │20任务│ │任务   │        │
│  └──────┘ └──────┘ └──────┘ └──────┘       │
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐       │
│  │烟雾  │ │酒精  │ │PIR   │ │超声  │        │
│  │任务   │ │任务   │ │任务  │ │波任务│        │
│  └──────┘ └──────┘ └──────┘ └──────┘       │
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐       │
│  │步进  │ │舵机  │ │风扇  │ │门锁  │        │
│  │电机   │ │任务  │ │任务  │ │任务  │        │
│  └──────┘ └──────┘ └──────┘ └──────┘       │
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐       │
│  │蜂鸣  │ │LED   │ │Sys   │ │MPU   │        │
│  │器     │ │控制  │ │Mon   │ │6050  │        │
│  └──────┘ └──────┘ └──────┘ └──────┘       │
├─────────────────────────────────────────────┤
│         GD32F407 (Cortex-M4F, 168MHz)       │
└─────────────────────────────────────────────┘

硬件资源映射

传感器阵列

模块接口引脚说明
DHT11单总线PC7温湿度(含卡尔曼滤波)
BH1750I2CSCL:PE5, SDA:PE6光照强度
DS18B20单总线PD15高精度温度
HX711串行SCK:PC9, DOUT:PA8称重/压力
MQ-2 烟雾ADCPA1 (ADC0_IN1)烟雾浓度
MQ-3 酒精ADCPA1 (ADC0_IN1)酒精浓度(与烟雾共用)
PIR 红外GPIOPC8人体感应
HC-SR04 超声GPIO+EXTITrig:PA12, Echo:PA11距离测量
MPU6050硬件I2CSCL:PB10, SDA:PB11六轴姿态
RC522 RFID软件I2CSCL:PA8, SDA:PC9非接触式读卡

执行器

模块接口引脚说明
28BYJ-48 步进电机GPIO 4相PB2~PB5步进电机
SG90 舵机PWMPA0 (TIM4_CH0, 50Hz)角度控制
直流风扇PWMPD14 (TIM3_CH2, 10kHz)调速
电磁锁GPIOPD13高电平解锁
蜂鸣器GPIOPC12音乐播放
4路LEDGPIOPE12~PE15跑马灯
WS2812B RGB单总线PD12RGB灯珠(GRB)
点阵屏 74HC595SPIPC0~PC3文本/图形滚动

FreeRTOS 任务设计

系统采用抢占式调度,共 16 个任务:

任务优先级栈(Word)周期功能
HMI3256事件驱动串口指令解析分发
Buzzer312850ms蜂鸣器控制
Ultrasonic3512100ms超声波测距
StepMotor3256N/A步进电机相位
HX7113256200ms重量采集
Smoke3256N/A烟雾监测
Alcohol3256N/A酒精监测
DoorLock2256N/A门锁控制
LED2128500ms跑马灯
SysMon22561000ms系统监控
Servo2128N/A舵机控制
Fan2256N/A风扇调速
DS18B202512~1000ms温度采集
PIR2256N/A人体红外
DHT1125121000ms温湿度采集
BH17502512~350ms光照采集

优先级设计原则:

  • 优先级 3:外设交互/时间敏感任务(HMI、超声波、蜂鸣器等)
  • 优先级 2:常规采集与控制任务
  • 优先级 0/1:空闲与后台任务

HMI 通信协议

二进制控制帧

格式:帧头(0xFE) + 指令码(1B) + 数据(NB)

c
// 指令解析示例
switch (cmd) {
    case 0x08: ultrasonic_thread_start(); break;   // 启动超声波
    case 0x09: ultrasonic_thread_stop();  break;    // 停止超声波
    case 0x10: ds18b20_thread_start();    break;    // 启动DS18B20
    case 0x19: buzzer_thread_start();     break;    // 启动蜂鸣器
    case 0x23: step_motor_thread_start(); break;    // 启动步进电机
    case 0x25: step_motor_set_forward();  break;    // 步进电机正转
    case 0x26: step_motor_set_reverse();  break;    // 步进电机反转
    case 0x29: fan_thread_start();        break;    // 启动风扇
    case 0x46: door_lock_unlock_cmd();    break;    // 解锁
    case 0x61: smoke_thread_start();      break;    // 启动烟雾检测
    // ... 共30+条指令
}

ASCII 控制帧

格式:0xFF + ASCII指令

code
slider1=<0..100>    → 更新风扇速度
text=<str>           → 点阵屏显示文本

ISR 与任务间通信

code
USART2_IRQHandler
    → 以 0xAA 起始, 0x04 结束收包
    → xQueueSendFromISR()
        → uartQueue (8个槽位)
            → HMI Task (xQueueReceive + 解析)

传感器驱动要点

超声波测距(中断模式)

c
void Ultrasonic_Test(void) {
    // 发送 10us Trig 脉冲
    GPIO_BC(GPIOA) = GPIO_PIN_12;  delay_1us(2);
    GPIO_BOP(GPIOA) = GPIO_PIN_12;  delay_1us(10);
    GPIO_BC(GPIOA) = GPIO_PIN_12;
    
    TIMER_CAR(TIMER1) = 0;  // 清零计数器
}
// EXTI10_15 ISR 捕获 Echo 下降沿 → 读取 TIMER1 → 计算距离
// Distance = Time * 0.017,累加10次取均值

DHT11 温湿度(临界区保护)

c
// 单总线时序敏感,读数据前进入临界区
taskENTER_CRITICAL();
uint8_t data[5] = {0};
// 逐位读取...
taskEXIT_CRITICAL();
// 一维卡尔曼滤波平滑
kalman1d_update(&kf, value);  // Q=0.01, R=4.0

BH1750 光照(软件I2C + 卡尔曼)

c
// 软件模拟 I2C
MY_IIC_Start();
MY_IIC_Send_Byte(BH1750_ADDR);
// 读取16位光照值
// 卡尔曼滤波平滑 Lux
kalman1d_update(&kf, (float)lux);

MPU6050 六轴姿态

c
MPU6050_Init();  // I2C1 (PB10/PB11), 100kHz
MPU_Set_Rate(100);  // 100Hz采样率, 25Hz低通
// 循环读取 (100ms)
MPU_Get_Accelerometer(&ax, &ay, &az);
MPU6050_Get_Angle(&x, &y, &z, 1);  // 加速度计计算欧拉角
// 中值滤波 (窗口7) 平滑角度
median_update(&mf, angle);
HMI_send_to_slider("X.val", angle);

滤波算法

系统集成了多种信号滤波方法:

方法文件用途
卡尔曼滤波Utils/src/kalman1d.cDHT11温度、BH1750光照
中值滤波Utils/src/median_filter.cMPU6050角度(窗口=7)
移动平均超声波驱动内HC-SR04测距(10次均值)
c
// 一维卡尔曼滤波
typedef struct {
    float Q; // 过程噪声
    float R; // 测量噪声
    float x; // 状态估计
    float p; // 估计误差协方差
} Kalman1D;

float kalman1d_update(Kalman1D *kf, float z) {
    // 预测
    kf->p += kf->Q;
    // 更新
    float k = kf->p / (kf->p + kf->R);
    kf->x += k * (z - kf->x);
    kf->p *= (1 - k);
    return kf->x;
}

WS2812B RGB LED

单颗灯珠 (GRB 格式),PD12 数据引脚,DWT 精确微秒时序:

c
// 预设颜色闪烁模式
WS2812_BlinkPresetsStart(200);  // 200ms 步进,循环预设颜色

// 无极变色模式 (HSV彩虹循环)
WS2812_SmoothStart(60);  // 60ms 步进

// 按键2切换模式
if (mode == PRESET) {
    WS2812_SmoothStop();
    WS2812_BlinkPresetsStart(200);
} else {
    WS2812_BlinkPresetsStop();
    WS2812_SmoothStart(60);
}

蜂鸣器音乐播放器

独立任务播放谱面数组,支持多曲切换、暂停和提示音:

c
// 谱面数组示例
const uint8_t custom_music[] = { M1,4, M2,4, M3,4, ... };

// 曲目管理
static const uint8_t *s_tracks[] = { custom_music, song2, song3 };
static const uint16_t s_track_sizes[] = { 
    sizeof(custom_music), sizeof(song2), sizeof(song3) 
};

// 控制接口
buzzer_player_start();          // 开始播放
buzzer_player_next();           // 下一曲
buzzer_player_toggle_pause();   // 暂停/继续
buzzer_player_triple_beep_and_stop(); // 三响提示

配套 Windows 端音乐编辑工具(music_editor.py),支持可视化编辑谱面并导出 .cfrag C 数组片段。


Utils 工具库

模块功能
kalman1d.c一维卡尔曼滤波
median_filter.c窗口中值滤波 (最大窗口9)
gpio_utils.cGPIO/PWM统一封装,支持逻辑引脚映射
button_events.cFreeRTOS Tick 按键事件(单击/双击/长按)
c
// GPIO/PWM 一行初始化
GPIOU_register_pwm_pin("servo", GPIOA, GPIO_PIN_0, TIM4, TIMER_CH_0, AF2);
GPIOU_pwm_setup("servo", 50.0f);  // 50Hz
GPIOU_pwm_set_duty("servo", 7.5f); // 1.5ms 中位

// 按键事件
ButtonEvent evt = button_update(&btn);
if (evt == BUTTON_EVENT_SINGLE) { /* 单击 */ }
if (evt == BUTTON_EVENT_DOUBLE) { /* 双击 */ }
if (evt == BUTTON_EVENT_LONG)   { /* 长按 */ }

系统启动流程

c
int main(void) {
    // 1. 初始化 DWT + SysTick (ms/us延时)
    systick_config();
    
    // 2. 读取并缓存时钟频率
    uint32_t sysclk = SystemCoreClock;
    
    // 3. 初始化调试串口 (USART0, 115200, printf重定向)
    system_monitor_init();
    
    // 4. 创建 HMI 串口任务
    hmi_task_create();
    
    // 5. 启动调度器
    vTaskStartScheduler();
    
    // 不会执行到这里
    while(1);
}

项目结构

code
GD32andFREERTOS/
├── BSP/                    # 板级支持包
│   ├── beep/              # 蜂鸣器
│   ├── exti/              # 外部中断
│   ├── iic/               # I2C
│   ├── key/               # 按键驱动
│   ├── led/               # LED驱动
│   ├── oled/              # OLED驱动
│   ├── rs485/             # RS485
│   ├── timer/             # 定时器
│   └── ultrasonic/        # 超声波驱动
├── Firmware/               # GD32固件库
│   ├── CMSIS/GD/
│   ├── GD32F4xx_std_peripheral/
│   └── GD32F4xx_usb_library/
├── FreeRTOS/               # FreeRTOS内核
│   ├── inc/               # 头文件
│   ├── src/               # 源码
│   └── port/              # Cortex-M4F 移植
├── Modules/               # 业务模块
│   ├── inc/               # 头文件
│   └── src/               # 任务实现 + 驱动
├── Utils/                 # 工具库
│   ├── inc/
│   └── src/
├── USER/                  # 入口 + 中断
│   ├── main.c            # 系统入口
│   └── gd32f4xx_it.c     # 中断服务
├── Project/               # Keil 工程
│   └── TEST.uvprojx      # Keil MDK v5 工程
├── 文档/                  # 技术文档
└── 比赛用到的脚本/         # Python 工具
    ├── music_editor.py       # 音乐编辑器
    └── pin_configurator.py   # 引脚配置工具

开发环境

工具版本
IDEKeil MDK-ARM v5
编译器ARMCC v5.06
调试器ST-Link
Flash512KB (0x08000000)
SRAM128KB (0x20000000)

总结

这是一个完整的嵌入式系统项目,核心技术的体现:

  1. 多任务调度:16个任务抢占式运行,三级优先级分级
  2. 自定义通信协议:二进制帧 + ASCII帧,ISR安全队列传递
  3. 多传感器融合:DHT11/BH1750/DS18B20/HX711/MPU6050/RC522 + 烟雾/酒精/超声/PIR
  4. 多滤波算法:卡尔曼(Q/R可调)、中值滤波、移动平均
  5. 外设全覆盖:GPIO/I2C/SPI/ADC/UART/PWM/EXTI/TIMER/单总线
  6. Python工具链:音乐编辑器、引脚配置可视化工具
  7. 竞赛获奖:海南省嵌入式开发赛道二等奖和三等奖