聪聪哥哥 发表于 2025-9-11 07:47

【HC32F0653】测评01:调试基本定时器B作为基本时钟

本帖最后由 聪聪哥哥 于 2025-9-11 08:01 编辑

在C语言里,任务调度指的是对多个任务(也被叫做线程或者进程)的执行顺序进行管理,以此来达成高效利用系统资源的目的。下面为你详细介绍任务调度的相关概念和实现方法。
一:任务调度的概念思想:
抢占式调度:在这种调度方式下,操作系统能够依据任务优先级,强行暂停当前正在执行的任务,转而执行其他任务。
非抢占式调度:采用这种调度方式时,任务只有在主动放弃 CPU 控制权的情况下,其他任务才有机会执行。
实时调度:实时调度的核心是保证任务能在严格的时间限制内完成,它又可以细分为硬实时调度和软实时调度。
优先级调度:优先级调度会为每个任务分配一个优先级,系统会优先执行优先级较高的任务。
二:任务调度的关键要点
上下文切换:在任务切换时,需要保存当前任务的状态(例如寄存器值),并恢复下一个任务的状态。
临界区保护:对于共享资源,要使用互斥锁、信号量等机制来避免竞态条件。
任务同步:可以通过信号量、事件标志组等方式实现任务间的同步。
堆栈管理:每个任务都有自己独立的堆栈,必须确保堆栈大小足够,防止溢出。
常用的任务调用有Free Rtos,OS,RT-threard等等实时操作系统专为嵌入式系统设计,提供了强大的任务调度功能,这里和大家分享一个简单任务调度器。创建任务队列。然后按照一定时间间隔来处理任务。
二:这里使用基本定时器B作为系统
2.1 基本概述
HC32F0653 内部集成 3 个基本定时器 (BTIM),每个 BTIM 完全独立且功能完全相同,各包含一个16bit 自动重装载计数器并由一个可编程预分频器驱动。BTIM 支持内部计数模式、外部计数模式、触发启动模式和门控计数模式 4种工作模式,支持更新事件和触发事件发生时产生中断。不同工作模式下均可由复位输入信号控制计数器复位。
2.2 主要特征
16bit 自动重载递增计数器
可编程预分频器支持1、2、3、4、.、65536 分频
支持单次计数模式和连续计数模式
触发输入信号(TRGI)控制定时器实现多种从模式
用于外设间同步的触发输出信号(TRGO)
复位信号(RSTI)控制计数器
复位更新事件和触发事件发生时产生中断
2.3 基本框图:

三:软件代码如下:
3.1 标记任务回调
//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2025-07-09
//========================================================================
void Task_Marks_Handler_Callback(void)
{
      char i;
      for(i=0; i<Tasks_Max; i++)
      {
                if(Task_Comps.TIMCount)    /* If the time is not 0 */
                {
                        Task_Comps.TIMCount--;/* Time counter decrement */
                        if(Task_Comps.TIMCount == 0)/* If time arrives */
                        {
                              /*Resume the timer value and try again */
                              Task_Comps.TIMCount = Task_Comps.TRITime;
                              Task_Comps.Run = 1;    /* The task can be run */
                        }
                }
      }
}3.2 处理任务回调函数:
//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2025-07-09
//========================================================================
void Task_Pro_Handler_Callback(void)
{
      char i;
      for(i=0; i<Tasks_Max; i++)
      {
                if(Task_Comps.Run) /* If task can be run */
                {
                        Task_Comps.Run = 0;    /* Flag clear 0 */
                        Task_Comps.TaskHook();/* Run task */
                }
      }
}3.3  添加任务函数如下:
//========================================================================
// 函数: TASK_COMPONENTS
// 描述: 添加任务列表
// 参数: None.
// 返回: None.
// 版本: V1.0, 2025-07-09
//========================================================================
static TASK_COMPONENTS Task_Comps[]=
{
      {0, 1000,1000, task_1000ms},                        /* task 1 Period: 1000ms */
{0, 100,100,   task_100ms},                            /* task 2 Period: 500ms */
{0, 10,10,   task_10ms},                              /* task 3 Period: 10ms */
{0, 200,200,   task_200ms},                              /* task 3 Period: 10ms */
};3.4 定时器B初始化函数如下:
void Timer_Init(void)
{
      BTIM_BaseConfig_t config;      // BTIM基础配置结构体
    NVIC_InitTypeDef initConfig;   // NVIC中断配置结构体
   
    // 使能BTIM外设时钟
    RCC_APBPeriphEnable(RCC_APB_PERIPH_BTIM, ENABLE);
   
    // 配置定时器基础参数
    config.period = ARR;             // 设置自动重装值
    config.division = PSC;         // 设置预分频值
    BTIM_ConfigTimeBase(BTIM0, &config);
   
    // 使能BTIM0更新中断
    BTIM_InterruptEnable(BTIM0, BTIM_INT_UPDATE, ENABLE);
   
    // 配置NVIC中断
    initConfig.NVIC_IRQChannel = BTIM0_IRQn;                  // 设置中断通道
    initConfig.NVIC_IRQChannelCmd = ENABLE;                      // 使能中断通道
    initConfig.NVIC_IRQChannelPreemptionPriority = 1;            // 设置抢占优先级
    initConfig.NVIC_IRQChannelSubPriority = 1;                   // 设置子优先级
    NVIC_Init(&initConfig);
   
    // 使能BTIM0计数器
    BTIM_CEnable(BTIM0, ENABLE);
   
    // 初始化定时完成标志位
    t_1MS_done = 0;
}3.5 分别在主函数中和定时器B的中断函数中调用回调函数:
void BTIM0_IRQHandler(void)
{
      // 检查是否为更新中断
      if(BTIM_ReadIntFlag(BTIM0, BTIM_INT_UPDATE) != RESET)
    {
      // 清除更新中断标志位
      BTIM_ClearIntFlag(BTIM0, BTIM_INT_UPDATE);
      // 设置1毫秒定时完成标志
//      t_1MS_done = 1;
                        Task_Marks_Handler_Callback();
    }
}while (TRUE) {
                        Task_Pro_Handler_Callback();
}四:实物验证如下:
页: [1]
查看完整版本: 【HC32F0653】测评01:调试基本定时器B作为基本时钟