跳到正文
XiaoGao 的个人博客

NO.21 · 嵌入式开发

STM32F407 智能定时用电控制器:四状态机 + 1ms 分时调度

STM32F407 智能定时用电控制器实战——四状态机互斥保护、SysTick 1ms 分时任务调度、寄存器级 USART 驱动、数码管动态扫描、20ms 按键消抖与温度失效保护。

发布 DATE
字数 WORDS
1,171
阅读 READ
3 分钟

倒计时控制继电器通断负载,听起来简单,做扎实却不容易。这个项目基于 STM32F407VE,用一套 1ms 分时任务调度把倒计时、数码管扫描、按键消抖、串口解析、蜂鸣器节奏和温度保护全部塞进裸机主循环,从未使用中断——时序可推演、行为可预测。

功能全景

1
2
按键 + 串口双通道设置 → 四位数码管 MM.SS 实时显示 → 启动后继电器吸合
→ 每秒短鸣 + LED 快闪 → 倒计时归零报警(蜂鸣器周期鸣叫)→ 一键停止/复位

四状态机设计

状态 行为
设置 可调整时间;继电器断开 / LED 熄灭 / 蜂鸣器静音
运行 每秒倒计时递减;继电器吸合 / LED 快闪 / 每秒短鸣
暂停 倒计时冻结;继电器断开 / LED 熄灭 / 蜂鸣器静音
报警 时间到;继电器断开 / LED 闪烁 / 周期鸣叫,K4/K5/B 停止

状态边界清晰:仅 run 递减且继电器吸合,set/pause 每周期强制复位输出,alarm 仅响应停止键——把状态误操作在逻辑层面清零。上电默认进入设置状态、默认 60 秒,倒计时归零自动断开继电器,防止负载超时运行。

1ms 分时调度

1
2
3
4
5
6
7
8
9
10
app_timer_1ms_task()                                [SysTick 每 1ms 触发]
├── system_ms++ 系统毫秒计数
├── 每 100ms → temperature_control_safe_task() 温度保护复查
├── display_scan() 数码管扫描一位(4ms 一轮)
├── key_scan() → key_process() 按键采样(20ms 消抖)
├── usart_receive_check() → usart_process() 串口轮询与命令解析
├── 每 1000ms → run 状态倒计时递减
├── run_beep_task() / alarm_beep_task() 蜂鸣器节奏调度
├── LED 翻转调度(run 40ms / alarm 120ms)
└── display_update_buffer() 刷新显示缓存

单一 1ms 心跳分频出 100ms 和 1000ms 多级节拍,全程无阻塞延时。

关键技术点

寄存器级串口驱动

USART1(PA9/PA10,AF7)直接操作 MODER/OTYPER/AFR/BRR 寄存器完成初始化;波特率用分数分频公式计算,fraction 带四舍五入与满 16 进位修正,84MHz → 9600bps 精确得到 BRR = 0x222E;收发查询 TXE/RXNE 标志,不占中断资源。

硬件 PWM 蜂鸣器

TIM4_CH1(PD12)1MHz 时基 + PWM1 模式:频率 = 1MHz/ARR 控制音调(100Hz~10kHz 越界钳位),占空比控制音量。变调时对比较值做防溢出钳位,切换平滑。

数码管动态扫描

共阴极四位管:PB8PB15 段选、PC0PC3 位选,1ms 点亮一位、4ms 刷新一轮。扫描流程”先消隐后输出”,杜绝换位瞬间的”鬼影”。

20ms 按键消抖

5 键逐 1ms 采样,电平连续稳定 20 个周期才确认;仅在稳定键值”变化”时上报一次(边沿触发),长按零重复。

时间边界防溢出

+1min 上限 98:00、+10s 上限 99:49、-10s 下限 00:10 的钳位设计,杜绝 uint16 溢出与两位数显示越界。

温度失效保护

TIM3_CH1/PB4 温度闭环输出强制关闭:停计数 → 关通道 → CCR1 清零 → 引脚拉低。上电立即执行,运行中每 100ms 复查,保证任何状态下都不会误动作。

串口命令协议(9600 8N1)

命令 功能
S 启动 / 暂停(与 K3 同一入口)
R 复位
Q 查询状态:time=01:30 set, relay off, temp safe
M / T / A +1 分钟 / +10 秒 / -10 秒
B 停止报警
Dmmss 设置时间,如 D0130 = 01:30

串口命令复用按键处理函数,按键与串口行为完全一致,消除双通路逻辑分叉。非法输入(秒 ≥ 60、零时长、运行中设置)逐项拒绝并回执原因。

蜂鸣器与 LED 提示编码

事件 蜂鸣器 LED
启动 / 每秒递减 短鸣 120ms @ 2700Hz 40ms 周期翻转
倒计时归零报警 120ms 鸣 / 120ms 停 @ 4200Hz 120ms 周期翻转
设置 / 暂停 静音 熄灭

零硬件成本,靠节奏编码提升状态可读性。

工程分层

1
2
3
4
5
6
7
8
9
10
APL 应用入口层     main.c(初始化 → 1ms 调度循环)
HAL 硬件抽象层 board_config.h(引脚集中定义)
├─ app_timer.c 四状态机 / 倒计时 / 按键与串口处理
├─ tim.c 1MHz 时基 + __weak 回调框架
├─ bsp_output.c LED / 蜂鸣器 / 继电器
├─ bsp_display.c 数码管动态扫描
├─ bsp_key.c 按键扫描与消抖
├─ bsp_usart.c 寄存器级收发
└─ temp_safe.c 温度失效保护
SPL / CMSIS ST 官方库(CMSIS V4.2 + SPL V1.5.0)

全工程无中断、无 DMA、无 RTOS,引脚集中定义、Doxygen 全量注释,是裸机任务调度与嵌入式工程化实践的好参考。

仓库

    ↑↓ 选择↵ 打开>theme · >random · >top · >archive