按键按一下,LED移动一下,都是正常运行的
以上就是我们定时器任务调度的功能
当然没有操作系统哪么厉害,但也有点意思
不管哪一个任务在执行,一个串口打印任务,另一个是一个按键切换任务
这个是LED灯指示的任务,他们这三个任务都是相互独立的,他们不会相互影响
他们都是能独立运行。不会相互影响!!!
下面看文件的创建:
文件的创建(c和.h)
创建程序文件三步,把硬件需要的初始化弄一个config.c新建文件并保存.
添加到工程
添加引用路径
一般一个.c和一个1文件执行一个外设或者一个任务或功能,这样可以让代
看上去清爽,简洁明了
看上去要配对:
过程不好记录,憨憨的跟着冲哥走就OK!
接下来是今天的最重要的部分:
结构体数组的周期性任务调度
A LED1 Q:3秒闪一次;LED2 0.6秒闪一次,LED3 0.9秒闪一次1都有定时器1'ms加的变量,
2都有一个设定的计数目标,
3都有需要执行的功能,
4.定时时间到了才能执行
重点看结构体:
这个结构体,可以先看成有固定格式的数组:
先看这个结构体:
先在*.h里定义:
typedef struct
{
u8 Run; //任务状态:Run/Stop
u16 TIMCount; //定时计数器
u16 TRITime; //重载计数器
void (*TaskHook) (void); //任务函数
} TASK_COMPONENTS; // 这里TASK_COMPONENTS是我们定义的结构体的名字
static 是局部静态变量:通常定义在函数内部。与普通局部变量不同,它在函数调用
[*]结束后不会被销毁,其值会保持不变,直到下一次函数调用。它只在该函数
[*]内可见。
然后在.c里调用
static TASK_COMPONENTS Task_Comps[]= //定义局部静态结构体变量Task_Comps[]
{
//状态计数周期函数
{0, 300, 300, LED0_Blink}, /* task 1 Period: 300ms */
{0, 600, 600, LED1_Blink}, /* task 1 Period: 600ms */
{0, 900, 900, LED2_Blink}, /* task 1 Period: 600ms */
{0, 10, 10, KEY_Task}, /* task 1 Period: 600ms */
};
STC官方例程:
27-通过定时器周期性调度任务综合例程,简单实用的任务调度系统,推荐
是个非常典型的周期性调度任务,务必花时间搞懂!
u8 Tasks_Max = sizeof (Task_Comps)/sizeof (Task_Comps): //这里算出有多少个任务
//========================================================================
// 函数: 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.Run) /* If task can be run */
{
Task_Comps.Run = 0; /* Flag clear 0 */
Task_Comps.TaskHook(); /* Run task */
}
}
}
这意思是只要Task_Comps.Run=1,就先把它清零,然后执行对应的函数
那下面这个函数是干涉么?
//========================================================================
// 函数: 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.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 */
}
}
}
}
看看我加的注释:
u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);//算出有几行(几个任务)
//========================================================================
// 函数: 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.TIMCount) // If the time is not 0假如不为0
{
Task_Comps.TIMCount--; // Time counter decrement 计数变量--
if(Task_Comps.TIMCount == 0) // If time arrives 假如计数变量为0
{
/*Resume the timer value and try again */
Task_Comps.TIMCount = Task_Comps.TRITime; //d对应变量重新装载初值
Task_Comps.Run = 1; //The task can be run Run标志位置1
}
}
}
}