8051U学习打卡第六集:定时器任务调度实验
1. 定时器任务调度讲解
这一节课的内容就和RTOS挂一点钩了,对于学习过FreeRTOS的人表示很友好

所谓任务调度,就是在你有多个需要定时任务,但是每个任务时间又不一样所需要用到的功能;
- task0, 要求50ms执行一次
- task1, 要求1s执行一次
- task2, 要求10ms执行一次
- .......
如上所示,有多个不同的任务并且定时时间还不一样,具体干什么我们先不管,当然,为了不计成本的完成任务情况下你也可以选择使用定时器多的MCU进行多定时器同时开启中断的方法来完成,如定时器0专门负责task0,定时器1专门负责task1,定时器2专门负责task2,以此类推......;但是这样就会导致成本高、代码维护困难、MCU功耗更高,所以采取了任务调度的方法来完成这个任务
任务调度最大优点就是可以节省单片机资源,达到节省功耗,提升运行效率的作用。还是上面的例子,任务调度可以使用一个定时器来完成多个任务,这比多定时器开启的资源消耗明显小很多。
2. STC官方Task文件代码
static TASK_COMPONENTS Task_Comps[] =
{
//状态 计数 周期 函数
{0, 500, 500, Sample_LED0}, /* task 1 Period: 500ms */
{0, 1000, 1000, Sample_LED2}, /* task 2 Period: 1000ms */
{0, 2000, 2000, Sample_LED4}, /* task 3 Period: 2000ms */
{0, 500, 500, Sample_RTC}, /* task 4 Period: 500ms */
/* Add new task here */
};
如上面代码所示,一个结构体里面包含了一个任务所需要的全部元素,状态,计时时间,周期和函数名
//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
u8 i;
for(i = 0; i < Tasks_Max; i++)
{
if(Task_Comps[i].TIMCount) /* If the time is not 0 */
{
Task_Comps[i].TIMCount--; /* Time counter decrement */
if(Task_Comps[i].TIMCount == 0) /* If time arrives */
{
/*Resume the timer value and try again */
Task_Comps[i].TIMCount = Task_Comps[i].TRITime;
Task_Comps[i].Run = 1; /* The task can be run */
}
}
}
}
Task_Marks_Handler_Callback(void)函数官方说明的比较简单,根据代码可以知道这个函数的主要作用是让任务开始计时,以达到到固定时间任务可以运行和停止的效果,为了确保计时的准确性,一般将它放在**中断函数里面
//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
u8 i;
for(i = 0; i < Tasks_Max; i++)
{
if(Task_Comps[i].Run) /* If task can be run */
{
Task_Comps[i].Run = 0; /* Flag clear 0 */
Task_Comps[i].TaskHook(); /* Run task */
}
}
}
Task_Pro_Handler_Callback()函数就比较容易理解,它只有两个作用,一个是运行任务,另一个就是将任务的运行标志位置零,防止重复运行;它一般放在主函数里面即可,因为如果放在中断函数里面,当中断函数运行任务时,再次触发中断可能会程序跑飞
3.效果