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

一、说明:

示意图

总结:

通过回调函数,与任务块在定时器中断里进行循环检测,当到达设定时间,就置为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

相关推荐
碧海银沙音频科技研究院4 小时前
炬芯ATS3089X手表的HFP通话不自动路由到设备BT的问题解决
网络·人工智能·嵌入式硬件·算法
youcans_9 小时前
【STM32C5教程】(3)GPIO 按键输入实验
stm32·单片机·嵌入式硬件
俊基科技10 小时前
回音消不掉、底噪压不住、主板还对不上口?——A-59P 多功能语音处理模组技术解析
嵌入式硬件·回音消除·ai降噪模块
北京盛世宏博11 小时前
通信异常深度排查:以太网温湿度设备 TCP 粘包、UDP 丢包根治方案
单片机·网络协议·tcp/ip·udp·以太网·传感器·温湿度
蓝天居士11 小时前
PY32F系列MCU在串口接收时跑飞的根因分析(2)
单片机·嵌入式硬件
wuyk55514 小时前
嵌入式驱动开发:量产级工程化实战(第9篇)——低功耗下的通信可靠性
c语言·驱动开发·stm32·单片机·嵌入式硬件
创界工坊工作室15 小时前
24-基于单片机的仓鼠养殖环境监控系统设计
stm32·单片机·嵌入式硬件·proteus
碧海银沙音频科技研究院15 小时前
基于炬芯ATS录音卡BLE控制协议
人工智能·嵌入式硬件·算法·语音识别
comyccccc16 小时前
PCB走线设计秘籍:从载流到3D预览全解析学习笔记
单片机·嵌入式硬件
俊基科技16 小时前
A-59 工业级 AI 语音处理模组:100 dB 消回音 + 神经网络降噪的工程实践
嵌入式硬件·神经网络·硬件开发·语音模块·回音消除·拾音降噪