使用定时器开启定时中断1ms。可直接复制粘贴板使用这个代码
使用结构体数组创建任务列表;
// 假设的任务数量
#define NUM_TASKS 10
// 任务状态枚举
typedef enum {
TASK_SHOTDOWN, //任务不开启
TASK_READY, //需要开启的任务
TASK_FINISHED //执行任务
} TaskState;
// 任务结构体
typedef struct {
uint16_t up_count; //时间片计数器
uint16_t ticks; //定时时间
TaskState state; //任务状态
void (*taskFunction)(void); // 任务函数指针
} Task;
// 任务列表
Task tasks[NUM_TASKS] = {
{ .up_count = 0, .ticks = 2, .state = TASK_SHOTDOWN, .taskFunction = task_2ms },
{ .up_count = 0, .ticks = 5, .state = TASK_SHOTDOWN, .taskFunction = task_5ms },
{ .up_count = 0, .ticks = 10, .state = TASK_READY, .taskFunction = task_10ms },
{ .up_count = 0, .ticks = 20, .state = TASK_READY, .taskFunction = task_20ms },
{ .up_count = 0, .ticks = 50, .state = TASK_READY, .taskFunction = task_50ms },
{ .up_count = 0, .ticks = 100, .state = TASK_READY, .taskFunction = task_100ms },
{ .up_count = 0, .ticks = 200, .state = TASK_READY, .taskFunction = task_200ms },
{ .up_count = 0, .ticks = 500, .state = TASK_READY, .taskFunction = task_500ms },
{ .up_count = 0, .ticks = 1000, .state = TASK_SHOTDOWN, .taskFunction = task_1000ms },
{ .up_count = 0, .ticks = 2000, .state = TASK_SHOTDOWN, .taskFunction = task_2000ms },
};
创建任务函数,需要执行的代码放到任务函数里面就行
// 假设的任务函数
void task_2ms(void) {
// Task 2 implementation
// ...
}
void task_5ms(void) {
// Task 0 implementation
// ...
}
void task_10ms(void) {
// Task 1 implementation
// ...
}
在定时器中断里执行任务标志
//在中断里面执行,设置中断1ms
void tasks_ticks(void)
{
uint8_t i;
for(i=0; i<NUM_TASKS; i++) //每一个任务时间分别处理
{
if(tasks[i].state == TASK_READY) //判断任务是否开启
{
if(++tasks[i].up_count == tasks[i].ticks) //达到定时时间
{
tasks[i].state = TASK_FINISHED; //执行任务标志
tasks[i].up_count = 0; //计数时间清零
}
}
}
}
在主函数查询任务是否要执行
//放在主函数while中查询任务是否要执行
void tasks_execution(void)
{
uint8_t i;
for(i=0; i<NUM_TASKS; i++)
{
if(tasks[i].state == TASK_FINISHED) //分别判断每一个任务是否需要执行
{
tasks[i].state = TASK_READY; //执行任务标志清除
tasks[i].taskFunction(); // 执行任务函数
}
}
}
在50ms的任务里,发送串口测试。可以看到收到的串口数据前面的时间戳是50ms;