【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]