一、设置方法所需结构体
typedef struct TASK_COMPONENTS { unsigned char Run; // 程序运行标记:0-不运行,1-运行 ,这里是程序会不会运行 unsigned char Timer; // 计时器, 这个是用于在定时器中减减的 unsigned char ItvTime; // 任务运行间隔时间, 这个是用于更新参数的 void (*TaskHook)(void); // 要运行的任务函数 函数指针 } TASK_COMPONENTS; // 任务定义
二、构建任务表
/************************************************************************************** * Variable definition 这里添加你的任务。。。。 **************************************************************************************/ static TASK_COMPONENTS TaskComps[] = { {0, 0,2, RGB_MODE1}, //任务一 {0, 0,1000, Led}, //任务二 };
三、任务标志检测,在定时器中断中调用
/************************************************************************************** * FunctionName : TaskRemarks() //放到定时器中 * Description : 任务标志处理 **************************************************************************************/ void TaskRemarks(void) //要放到 timer中断中 { uchar i; uchar TaskMax = sizeof(TaskComps)/sizeof(TASK_COMPONENTS); for(i = 0; i < TaskMax; i++) { if(TaskComps[i].Timer) // 时间不为0 , 可是我有一个问题, 什么时候用 . 什么时候用 -> { TaskComps[i].Timer--; } else { if(TaskComps[i].Timer == 0) //如果计时到 { TaskComps[i].Timer = TaskComps[i].ItvTime; // 恢复计时器值,从新下一次 TaskComps[i].Run = 1; // 任务可以运行, 任务的延迟已经过了, 可以继续运行了 } } } }
四、任务处理,在while(1)中调用
/************************************************************************************** * FunctionName : TaskProcess() **************************************************************************************/ void TaskProcess(void) { uchar i; uchar TaskMax = sizeof(TaskComps)/sizeof(TASK_COMPONENTS); for (i=0; i<TaskMax; i++) // 逐个任务时间处理 { if(TaskComps[i].Run) //如果任务可以运行 { TaskComps[i].TaskHook(); // 运行任务, 这个是一个函数, 在运行完这个函数后, 我们下一步操作就是清除标志位 TaskComps[i].Run = 0; // 标志清0 } } }
完整程序
#include "WS51F0030.h" #include "RGB.h" #define Time0Def 65536-2668 //2ms #define uchar unsigned char #define uint unsigned int void Led(void) { P14 = ~P14; } typedef struct TASK_COMPONENTS { unsigned char Run; // 程序运行标记:0-不运行,1-运行 ,这里是程序会不会运行 unsigned char Timer; // 计时器, 这个是用于在定时器中减减的 unsigned char ItvTime; // 任务运行间隔时间, 这个是用于更新参数的 void (*TaskHook)(void); // 要运行的任务函数 函数指针 } TASK_COMPONENTS; // 任务定义 /************************************************************************************** * Variable definition 这里添加你的任务。。。。 **************************************************************************************/ static TASK_COMPONENTS TaskComps[] = { {0, 0,2, RGB_MODE1}, {0, 0,1000, Led}, }; //2. 任务运行标志出来,此函数就相当于中断服务函数,需要在定时器的中断服务函数中调用此函数,这里独立出来,便于移植和理解。 /************************************************************************************** * FunctionName : TaskRemarks() //放到定时器中 * Description : 任务标志处理 **************************************************************************************/ void TaskRemarks(void) //要放到 timer中断中 { uchar i; uchar TaskMax = sizeof(TaskComps)/sizeof(TASK_COMPONENTS); for(i = 0; i < TaskMax; i++) { if(TaskComps[i].Timer) // 时间不为0 , 可是我有一个问题, 什么时候用 . 什么时候用 -> { TaskComps[i].Timer--; // 减去一个节拍 } else { if(TaskComps[i].Timer == 0) //如果计时到 { TaskComps[i].Timer = TaskComps[i].ItvTime; // 恢复计时器值,从新下一次 TaskComps[i].Run = 1; // 任务可以运行, 任务的延迟已经过了, 可以继续运行了 } } } } //3. 任务处理:实现任务管理操作, 用于循环判断哪个任务需要运行了 /************************************************************************************** * FunctionName : TaskProcess() **************************************************************************************/ void TaskProcess(void) { uchar i; uchar TaskMax = sizeof(TaskComps)/sizeof(TASK_COMPONENTS); for (i=0; i<TaskMax; i++) // 逐个任务时间处理 { if(TaskComps[i].Run) //如果任务可以运行 { TaskComps[i].TaskHook(); // 运行任务, 这个是一个函数, 在运行完这个函数后, 我们下一步操作就是清除标志位 TaskComps[i].Run = 0; // 标志清0 } } } void delay_1ms(void) { int j; for(j=0; j<17700; ++j); } /*************************** *系统时钟初始化 ***************************/ void System_Init(void) { delay_1ms(); SCCON = 0x00;//使能HRC HRCON |= 0x80; delay_1ms(); SCCON = 0x00;//使能HRC HRCON |= 0x80; delay_1ms(); } /***************************************************** *全局中断打开 *****************************************************/ void ISR(void) { EA = 1; } /***************************************************** * 中断服务函数 1ms *****************************************************/ void timer0_isr (void) interrupt 1 { TL0 = Time0Def & 0xff; //初始值低字节,TL0 的高 3 位是无效的 TH0 = Time0Def >> 8; //初始值高字节(1ms@16MHz) 0.993ms TaskRemarks(); } /***************************************************** *函数功能:Timer0初始化配置 *****************************************************/ void Timer0_Init(void) { ET0 = 0; TL0 = Time0Def & 0xff; //初始值低字节,TL0 的高 3 位是无效的 TH0 = Time0Def >> 8; //初始值高字节(1ms@16MHz) 0.993ms TMOD = 0x01; //定时器,时钟为系统时钟 12 分频 ET0 = 1; //开中断 定时器 0 中断使能控制位 TR0 = 1; //启动定时器 } void Gpio_Init(void) { P14F = 0x02; //LED P05F = 0x02; } int main(void) { uint i = 0; System_Init(); Gpio_Init(); Timer0_Init(); ISR(); while(1) { TaskProcess(); } }
标签:TaskComps,TASK,轮询,Timer,裸机,单片机,任务,COMPONENTS,void From: https://www.cnblogs.com/yuanyongfei/p/16810612.html