基于时间触发的时间片裸机任务

时间触发的任务

1、资源要求:定时器1个
2、工作逻辑:
2.1、定时器周期查询任务时间,如果时间到达设定值,就置位任务标志。
2.2、主循环查询任务标志,如果置位就执行对应任务。

任务头文件

直接上代码,每行代码都有注释。
使用的时候,按头文件的《使用方法》操作即可。

/*
************************************************************************
* 功能:时间片任务处理
* 使用方法:
* 1、声明任务函数
* 2、填充《static taskType_T g_taTaskTab[]》任务列表
* 3、定时器周期调用《Task_Schedule()》
* 4、主循环调用《Task_Process()》
* 5、编写任务函数
************************************************************************
*/


#ifndef __TASK_H
#define __TASK_H

#include "main.h"

#define  ARRAYSIZE(a) (sizeof(a)/sizeof((a)[0]))	/*统计任务数量*/

/*任务属性定义*/
typedef struct 
{
	void (*Func)(void);		/*任务函数*/	
	uint16_t enableFlag;	/*运行标志*/
	uint16_t time;			/*运行时间*/
	uint16_t intervalTime;	/*间隔时间*/
}taskType_T;


void Task_Schedule(void);	/*任务调度函数,定时器中断调用*/
void Task_Process(void);	/*任务处理函数,主循环调用*/

/*以下任务函数声明*/
void Data_Filter(void);
void Msg_Print(void);

#endif

任务文件

#include "task.h"

/*
************************************************************************
* 功能:初始化任务列表
* 说明:需要初始化:声明函数,运行时间,间隔时间三个参数
************************************************************************
*/
static taskType_T g_taTaskTab[] =
{
	{Data_Filter,0,100},
	{Msg_Print,0,500},
};

/*
************************************************************************
* 功能:任务处理函数
* 说明:查询任务置位标志,如果可以执行则执行,执行完毕后,复位标志
************************************************************************
*/
void Task_Process(void)
{
	uint16_t i;
	for(i=0; i<ARRAYSIZE(g_taTaskTab);i++)
	{
		if(g_taTaskTab[i].enableFlag != 0)	/*任务可以运行*/
		{
			g_taTaskTab[i].Func();			/*运行任务*/
			g_taTaskTab[i].enableFlag = 0;	/*任务禁止运行*/
		}
	}
}
/*
************************************************************************
* 功能:任务调度函数
* 说明:周期调用,查询任务时间,如果达到间隔时间,则置位任务标志
************************************************************************
*/
void Task_Schedule(void)
{
    for (uint8_t i=0; i<ARRAYSIZE(g_taTaskTab); i++)                
    {
         if (g_taTaskTab[i].time)                              /* 时间不为0*/
        {
            g_taTaskTab[i].time--;                             /*减去一个节拍*/
        }
		else
		{
			g_taTaskTab[i].time = g_taTaskTab[i].intervalTime; /*恢复计时器值,重新下一次*/
			g_taTaskTab[i].enableFlag = 1;                     /* 任务可以运行*/	
		}
   }
}



使用

1、在定时器中断任务中调用Task_Schedule();定时器时间根据实际情况自己定义。

Task_Schedule();
2、在主函数中调用Task_Process();
void main(void)
{
	while(1)
	{
	Task_Process();
}
}

结语

1、时间片任务使用简单,但是要求每个任务的执行时间不能超过间隔时间,否则运行时间会不不准。
2、无任务通讯功能,每个任务间的通讯需要使用全局变量来处理。

你可能感兴趣的:(单片机,c语言)