一、关于软件定时器模拟任务运行总结

一、说明:

示意图

总结:

通过回调函数,与任务块在定时器中断里进行循环检测,当到达设定时间,就置为ready,调用回调,执行对应的任务。

这里使用一个例子:

串口输出,

led,iwdg,

显示信息,

来反映这个模型。

c 复制代码
// ==================== 任务调度相关全局变量 ====================
volatile uint32_t system_tick_ms = 0;     // 系统时间计数器(每1ms+1)

// 任务控制块结构体
typedef struct {
    void (*task_func)(void);   // 任务函数指针
    uint32_t period_ms;        // 任务周期(毫秒)
    uint32_t remain_ms;        // 当前倒计时剩余值
    uint8_t ready_flag;        // 就绪标志(1=可执行)
    uint8_t is_running;        // 正在执行标志(防止重入)
    uint32_t exec_count;       // 任务执行次数统计(用于状态显示)
} Task_Control_Block;


// 任务列表(4个任务)
#define TASK_NUM 4
Task_Control_Block task_list[TASK_NUM] = {
    { .task_func = Task_LED_Blink,          .period_ms = 100,  .remain_ms = 100, .ready_flag = 0, .is_running = 0, .exec_count = 0 },
    { .task_func = Task_UART_Communication, .period_ms = 200,  .remain_ms = 200, .ready_flag = 0, .is_running = 0, .exec_count = 0 },
    { .task_func = Task_FeedWatchdog,       .period_ms = 50,   .remain_ms = 50,  .ready_flag = 0, .is_running = 0, .exec_count = 0 },
    { .task_func = Task_StatusDisplay,      .period_ms = 1000, .remain_ms = 1000,.ready_flag = 0, .is_running = 0, .exec_count = 0 }
};



/**
 * @brief 中断服务更新函数(由TIM4中断每1ms调用一次)
 *        仅负责递减计数器、置位就绪标志,绝不执行任务函数
 */
void Timer_Service_Update(void) {
    system_tick_ms++;  // 系统时间累加
    for (uint8_t i = 0; i < TASK_NUM; i++) {
        // 只处理未就绪且未运行的任务(避免干扰正在执行的任务)
        if (!task_list[i].ready_flag && !task_list[i].is_running) {
            if (task_list[i].remain_ms > 0) {
                task_list[i].remain_ms--;
            }
            if (task_list[i].remain_ms == 0) {
                task_list[i].ready_flag = 1;                       // 置位就绪
                task_list[i].remain_ms = task_list[i].period_ms;   // 重载周期
            }
        }
    }
}

/**
 * @brief 主循环调度函数(在while(1)中反复调用)
 *        轮询就绪任务,按数组顺序执行
 */
void Scheduler_Run(void) {
    for (uint8_t i = 0; i < TASK_NUM; i++) {
        if (task_list[i].ready_flag && !task_list[i].is_running) {
            task_list[i].is_running = 1;
            task_list[i].ready_flag = 0;    // 清除就绪标志

            // 执行任务
            task_list[i].task_func();
            task_list[i].exec_count++;      // 统计执行次数

            task_list[i].is_running = 0;
        }
    }
}
main()
{
  while (1)
  { // 启动TIM的1ms中断

    Scheduler_Run();   // 主循环调度
    // 空闲时可执行低优先级后台任务或进入低功耗模式

  }
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM4) {
        Timer_Service_Update();   // 每1ms调用一次更新函数
    }
}

运行结果:

源码:

https://gitee.com/c_y_l_N_H/tmp_pit/tree/master

相关推荐
智闲电子设计37 分钟前
STM32 硬件过流保护实战:比较器直连 BKIN,纳秒级关断不靠软件
stm32·单片机·嵌入式硬件
嵌入式阿蔡1 小时前
存储_14:嵌入式存储测试岗面试——可靠性/兼容/车规面试题与项目话术
单片机·嵌入式硬件·面试·嵌入式·存储
Brilliantwxx3 小时前
【PCB】(入门篇) 电子入门系列|从电路分析到 PCB 设计
stm32·单片机·嵌入式硬件
俊基科技10 小时前
A-59U工业级多模语音处理模块在矿山矿井通信与呼叫报警系统中的应用
嵌入式硬件·嵌入式开发·硬件开发·ai降噪·回音消除·拾音降噪
周周记笔记12 小时前
GD32F450xx MCU Datasheet 解读:硬件测试工程师的测试方法论
单片机·嵌入式硬件
潘潘的嵌入式日记13 小时前
I²C 从机接收总被覆盖?双缓冲要在 STOP 时交接
c语言·开发语言·单片机
AOI小白新手上路15 小时前
江科协51单片机16-1 AD/DA ADC 三通道综合显示(LCD1602 版)改造说明
单片机·嵌入式硬件·51单片机
HUI-47416 小时前
EG1135|SSOP‑16 同步整流降压控制器,大功率外置 MOS 降压优选
单片机·嵌入式硬件·硬件工程
单片机仿真设计16 小时前
【proteus仿真】基于 STM32 单片机恒温箱控制系统设计(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus·毕设