1. LED闪烁模块化设计
任务目标
将LED闪烁功能封装为独立模块,通过简洁接口控制,使主循环无需关心闪烁时序细节,实现功能模块与主循环的解耦。本案例以STM32标准外设库为背景,核心逻辑与具体MCU无关,可移植至任何平台。
模块接口设计
模块对外仅暴露三个函数,内部状态完全私有:
LED_Flash_Init(void):初始化LED引脚与内部状态;LED_Flash_Update(void):周期调用,内部处理闪烁时序;LED_Flash_SetEnable(uint8_t en):使能/禁止闪烁。
关键完整代码
/* led_flash.h */
#ifndef LED_FLASH_H
#define LED_FLASH_H
#include <stdint.h>
void LED_Flash_Init(void);
void LED_Flash_Update(void);
void LED_Flash_SetEnable(uint8_t en);
#endif
/* led_flash.c */
#include "led_flash.h"
/* 硬件抽象:实际项目中替换为对应寄存器操作 */
#define LED_PORT_INIT() do { /* GPIO_Init */ } while(0)
#define LED_SET_ON() do { /* GPIO_SetBits */ } while(0)
#define LED_SET_OFF() do { /* GPIO_ResetBits */ } while(0)
/* 内部状态 */
static uint8_t s_enabled = 0;
static uint8_t s_led_on = 0;
static uint32_t s_tick_counter = 0;
/* 闪烁周期:500ms翻转一次 */
#define FLASH_HALF_PERIOD_TICKS 500u
void LED_Flash_Init(void)
{
LED_PORT_INIT();
LED_SET_OFF();
s_enabled = 0;
s_led_on = 0;
s_tick_counter = 0;
}
void LED_Flash_SetEnable(uint8_t en)
{
if (en) {
s_enabled = 1;
s_tick_counter = 0; /* 重新从亮开始 */
s_led_on = 1;
LED_SET_ON();
} else {
s_enabled = 0;
LED_SET_OFF();
}
}
void LED_Flash_Update(void)
{
if (!s_enabled) {
return;
}
if (++s_tick_counter >= FLASH_HALF_PERIOD_TICKS) {
s_tick_counter = 0;
s_led_on = !s_led_on;
if (s_led_on) {
LED_SET_ON();
} else {
LED_SET_OFF();
}
}
}
主循环集成方式
#include "led_flash.h"
int main(void)
{
LED_Flash_Init();
LED_Flash_SetEnable(1); /* 启动闪烁 */
while (1) {
/* 每1ms调用一次 */
LED_Flash_Update();
/* 其他任务代码,无需关心LED时序 */
}
}
运行与验证
依赖说明:代码中LED_PORT_INIT()、LED_SET_ON()、LED_SET_OFF()为硬件抽象宏,实际使用时替换为目标平台的GPIO初始化与电平控制语句(如STM32的GPIO_Init()与GPIO_SetBits()/GPIO_ResetBits())。
验证方法:
- 将上述文件加入工程,替换硬件抽象宏为实际GPIO操作;
- 主循环以1ms周期调用
LED_Flash_Update(); - 编译下载后,观察LED应以1Hz频率(每500ms翻转一次)持续闪烁;
- 调用
LED_Flash_SetEnable(0)后LED立即熄灭,调用LED_Flash_SetEnable(1)后重新从亮开始闪烁。
通过判定:LED按预期频率闪烁,且主循环中其他任务不受闪烁时序影响,即证明模块化解耦成功。