[APM32F4] 【APM32F402R Micro-EVB】02: 添加时间任务调度

[复制链接]
聪聪哥哥 发表于 2025-8-24 17:49 | 显示全部楼层 |阅读模式
本帖最后由 聪聪哥哥 于 2025-8-22 19:44 编辑

在C语言里,任务调度指的是对多个任务(也被叫做线程或者进程)的执行顺序进行管理,以此来达成高效利用系统资源的目的。下面为你详细介绍任务调度的相关概念和实现方法。
一:任务调度的概念思想:
抢占式调度:在这种调度方式下,操作系统能够依据任务优先级,强行暂停当前正在执行的任务,转而执行其他任务。
非抢占式调度:采用这种调度方式时,任务只有在主动放弃 CPU 控制权的情况下,其他任务才有机会执行。
实时调度:实时调度的核心是保证任务能在严格的时间限制内完成,它又可以细分为硬实时调度和软实时调度。
优先级调度:优先级调度会为每个任务分配一个优先级,系统会优先执行优先级较高的任务。

二:任务调度的关键要点
上下文切换:在任务切换时,需要保存当前任务的状态(例如寄存器值),并恢复下一个任务的状态。
临界区保护:对于共享资源,要使用互斥锁、信号量等机制来避免竞态条件。
任务同步:可以通过信号量、事件标志组等方式实现任务间的同步。
堆栈管理:每个任务都有自己独立的堆栈,必须确保堆栈大小足够,防止溢出。

常用的任务调用有Free Rtos,OS,RT-threard等等实时操作系统专为嵌入式系统设计,提供了强大的任务调度功能,这里和大家分享一个简单任务调度器。创建任务队列。然后按照一定时间间隔来处理任务。


这里我是用的极海MCU的高级定时器1完成的任务调度;
三:极海高级定时器的知识分享:
3.1 基础知识
高级定时器以时基单元为核心,拥有输入捕获、输出比较和刹车输入等功能,含有一个 16 位的自动装载计数器。高级定时器相比较其它定时器增加了互补输出、重复计数以及可编程的死区插入等功能,更加适合用于电机的控制。
3.2 定时器的特点:
(1)时基单元
                 计数器:16 位计数器,可以向上计数,向下计数,中央对齐计数
                 预分频器:16位可编程预分频器
                 重复计数器:16位的重复计数器
                 自动重装载功能
(2)时钟源选择
                 内部时钟
                 外部输入
                 外部触发
                 内部触发
(3)输入捕获功能
                计数功能
                PWM 输入模式(脉冲宽度、频率、占空比测量)
                编码器接口模式
(4) 输出比较功能
                PWM 输出模式
                强制输出模式
                单脉冲模式
                互补输出和死区插入
(5)定时功能
(6)刹车功能
(7)定时器的主/从模式控制器
·              定时器之间可以同步和级联
               支持多种从模式、同步信号
(8)中断输出和 DMA 请求事件
               更新事件(计数器上/下溢出,计数器初始化)
               触发事件(计数器启动、停止、内/外部触发)
               捕获/比较事件
               刹车信号输入事件
3.3 定时器的结构框图
02-1.png

四:通用定时器的编写流程如下:
1:使能定时器1时钟。
2:初始化定时器,配置ARR,PSC,中断时间1ms。
3:开启定时器1中断,配置NVIC中断优先级。
4:使能定时器1,定时器开始功能。
5: 编写中断服务函数。

五:程序编写流程:
5.1 定时器1初始化
  1. /**
  2. * @brief   TMR configuration
  3. *
  4. * @param   None
  5. *
  6. * @retval  None 1ms 中断
  7. */
  8. void TMR_Config(void)
  9. {
  10.     TMR_BaseConfig_T tmrBaseConfig;

  11.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);

  12.     /* TMR clock source frequency = 120MHz */
  13.     tmrBaseConfig.countMode = TMR_COUNTER_MODE_UP;
  14.     tmrBaseConfig.clockDivision = TMR_CLOCK_DIV_1;
  15.     tmrBaseConfig.period = 19;
  16.     tmrBaseConfig.division = 5999;
  17.     tmrBaseConfig.repetitionCounter = 0;
  18.     TMR_ConfigTimeBase(TMR1, &tmrBaseConfig);

  19.     TMR_EnableInterrupt(TMR1, TMR_INT_UPDATE);
  20.     NVIC_EnableIRQRequest(TMR1_UP_IRQn, 0x1, 0xF);

  21.     TMR_Enable(TMR1);
  22. }
5.2 定义定时器1的中断处理函数:
  1. /**
  2. * @brief   TMR update interrupt server
  3. *
  4. * @param   None
  5. *
  6. * @retval  None
  7. */
  8. void TMR_update_Irs(void)
  9. {
  10.     if (TMR_ReadIntFlag(TMR1, TMR_INT_UPDATE))
  11.     {
  12.                                 Task_Marks_Handler_Callback();
  13.         TMR_ClearIntFlag(TMR1, TMR_INT_UPDATE);
  14.     }
  15. }


5.3 编写任务标记的回调函数
  1. //========================================================================
  2. // 函数: Task_Handler_Callback
  3. // 描述: 任务标记回调函数.
  4. // 参数: None.
  5. // 返回: None.
  6. // 版本: V1.0, 2025-08-08
  7. //========================================================================
  8. void Task_Marks_Handler_Callback(void)
  9. {
  10.         char i;
  11.         for(i=0; i<Tasks_Max; i++)
  12.         {
  13.                 if(Task_Comps[i].TIMCount)    /* If the time is not 0 */
  14.                 {
  15.                         Task_Comps[i].TIMCount--;  /* Time counter decrement */
  16.                         if(Task_Comps[i].TIMCount == 0)  /* If time arrives */
  17.                         {
  18.                                 /*Resume the timer value and try again */
  19.                                 Task_Comps[i].TIMCount = Task_Comps[i].TRITime;  
  20.                                 Task_Comps[i].Run = 1;    /* The task can be run */
  21.                         }
  22.                 }
  23.         }
  24. }
5.4 定义任务处理回调函数
  1. //========================================================================
  2. // 函数: Task_Pro_Handler_Callback
  3. // 描述: 任务处理回调函数.
  4. // 参数: None.
  5. // 返回: None.
  6. // 版本: V1.0, 2025-08-08
  7. //========================================================================
  8. void Task_Pro_Handler_Callback(void)
  9. {
  10.         char i;
  11.         for(i=0; i<Tasks_Max; i++)
  12.         {
  13.                 if(Task_Comps[i].Run) /* If task can be run */
  14.                 {
  15.                         Task_Comps[i].Run = 0;    /* Flag clear 0 */
  16.                         Task_Comps[i].TaskHook();  /* Run task */
  17.                 }
  18.         }
  19. }
5.5 定义时间任务处理函数:
  1. //========================================================================
  2. // 函数: TASK_COMPONENTS
  3. // 描述: 添加任务列表
  4. // 参数: None.
  5. // 返回: None.
  6. // 版本: V1.0, 2025-08-08
  7. //========================================================================
  8. static TASK_COMPONENTS Task_Comps[]=
  9. {
  10.         {0, 1000,1000, task_1000ms},                          /* task 1 Period: 1000ms */
  11.   {0, 500,500,   task_500ms},                            /* task 2 Period: 500ms */
  12.   {0, 50,50,   task_10ms},                            /* task 2 Period: 500ms */
  13. };
5.6 编写 串口输出任务和LED闪烁任务
  1. //========================================================================
  2. // 函数: void task_500ms(void)
  3. // 描述: 500 任务.
  4. // 参数: None.
  5. // 返回: None.
  6. // 版本: V1.0, 2025-08-08
  7. //========================================================================
  8. void task_500ms(void)
  9. {
  10.         BOARD_LED_Toggle(LED2);
  11. }
  12. //========================================================================
  13. // 函数: void task_1000ms(void)
  14. // 描述: 1000ms 任务.
  15. // 参数: None.
  16. // 返回: None.
  17. // 版本: V1.0, 2025-08-08
  18. //========================================================================
  19. void task_1000ms(void)
  20. {
  21.         printf("21论坛测评APM32F402 测评活动 by:聪聪哥哥 \r\n");
  22. }        
六:实测图片如下所示:
02-2.jpg
使用高级定时器作为系统的时基,还是有些浪费,可以使用基本定时器做就可以。感兴趣的可以自己移植一下。
神秘低语 发表于 2025-8-25 18:18 | 显示全部楼层
这种时间片调用的方式,如何传入参数啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

93

主题

238

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部