(1)首先定义任务数、任务定时初值(任务轮询时间=定时初值*定时器中断时间)、任务定时计数器;
(2)在定时器中断服务函数中添加【复用函数】。
#define TASK_NUM 3 // 这里定义的任务数为3,表示有三个任务会使用此定时器定时。
uint16_t TaskCount[TASK_NUM] ; // 这里为三个任务定义三个变量来存放定时值
uint8_t TaskMark[TASK_NUM]; // 同样对应三个标志位,0--表示时间没到,1--表示定时时间到。
/**************************************************************************************
* FunctionName : TimerInterrupt()
* Description : 定时中断服务函数
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TimerInterrupt(void)
{
uint8_t i;
for (i=0; i
时间片轮询架构组成:【一个结构体+两个函数】
/**************************************************************************************
* FunctionName : TaskStruct
* Description : 任务结构体
* EntryParameter : None
* ReturnValue : None
* attention : 它包含了一个任务所需要的所有信息;
* 1:运行状态标志位:0-不运行;1-运行。
* 2:计数器TimerCountdown--
* 3:计数器数值填充器,预设的初值:TimerInitialValue(任务运行间隔时间)
* 4:任务对应的函数指针
**************************************************************************************/
typedef struct TaskComponents
{
uint8_t Run; // 程序运行的标记:0-不运行、1-运行
uint8_t TimerCountdown; // 计数器
uint8_t TimerInitialValue; // 任务运行间隔时间
void (*Task_hand)(); // 要运行的任务函数
}TaskComponents; // 任务定义
/**************************************************************************************
* FunctionName : TaskRemarks()
* Description : 任务标志处理
* EntryParameter : None
* ReturnValue : None
* attention : 这个函数是用来更新每个任务的计数器以及它们的运行标志位的,
它是写在单片机的定时器中断服务函数中的。
**************************************************************************************/
void TaskRemarks(void)
{
uint8_t i;
for (i = 0; i < TaskMax; i++) // 逐个任务时间处理
{
if(TaskComps[i].TimerCountdown) // 时间不为0
{
TaskComps[i].TimerCountdown--; // 减去一个节拍
if (TaskComps[i].TimerCountdown == 0) // 时间减完了
{
// 恢复计时器值,重新下一次
TaskComps[i].TimerCountdown= TaskComps[i].TimerInitialValue;
TaskComps[i].Run = 1; // 任务可以运行
}
}
}
}
/**************************************************************************************
* FunctionName : TaskProcess()
* Description : 任务处理--->判断什么时候该执行那一个任务
* EntryParameter : None
* ReturnValue : None
* * attention : 放在mian的while(1)即可
**************************************************************************************/
void TaskProcess(void)
{
uint8_t i;
for (i = 0; i < TaskMax; i++) // 逐个任务时间处理
{
if (TaskComps[i].Run) // 时间不为0
{
TaskComps[i].TaskHank(); // 运行任务
TaskComps[i].Run = 0; // 标志清0
}
}
}
/**************************************************************************************
* FunctionName : TaskStruct
* Description : 任务结构体
* EntryParameter : None
* ReturnValue : None
* attention : 它包含了一个任务所需要的所有信息;
* 1:运行状态标志位:0-不运行;1-运行。
* 2:计数器TimerCountdown--
* 3:计数器数值填充器,预设的初值:TimerInitialValue(任务运行间隔时间)
* 4:任务对应的函数指针
**************************************************************************************/
typedef struct TaskComponents
{
uint8_t Run; // 程序运行的标记:0-不运行、1-运行
uint8_t TimerCountdown; // 计数器
uint8_t TimerInitialValue; // 任务运行间隔时间
void (*Task_hand)(); // 要运行的任务函数
}TaskComponents; // 任务定义
初始化:{程序运行标记,计数器,任务运行间隔,任务函数}
#define InitStatus 0
static TaskComponents TaskComps[] =
{
{InitStatus, 60, 60, TaskDisplayClock}, // 显示时钟
{InitStatus, 20, 20, TaskKeySan}, // 按键扫描
{InitStatus, 30, 30, TaskDispStatus}, // 显示工作状态
// 这里继续添加任务。。。。
};
// 任务清单
typedef enum TaskList
{
TaskDisplayClock, // 显示时钟
TaskKeySan, // 按键扫描
TaskDispStatus, // 显示工作状态
// 这里继续添加任务。。。。
TaskMax // 总的可供分配的定时任务数目
}TaskList;
/**************************************************************************************
* FunctionName : TaskRemarks()
* Description : 任务标志处理
* EntryParameter : None
* ReturnValue : None
* attention : 这个函数是用来更新每个任务的计数器以及它们的运行标志位的,
它是写在单片机的定时器中断服务函数中的。
**************************************************************************************/
void TaskRemarks(void)
{
uint8_t i;
for (i = 0; i < TaskMax; i++) // 逐个任务时间处理
{
if(TaskComps[i].TimerCountdown) // 时间不为0
{
TaskComps[i].TimerCountdown--; // 减去一个节拍
if (TaskComps[i].TimerCountdown == 0) // 时间减完了
{
// 恢复计时器值,重新下一次
TaskComps[i].TimerCountdown= TaskComps[i].TimerInitialValue;
TaskComps[i].Run = 1; // 任务可以运行
}
}
}
}
/**************************************************************************************
* FunctionName : TaskProcess()
* Description : 任务处理--->判断什么时候该执行那一个任务
* EntryParameter : None
* ReturnValue : None
* * attention : 放在mian的while(1)即可
**************************************************************************************/
void TaskProcess(void)
{
uint8_t i;
for (i = 0; i < TaskMax; i++) // 逐个任务时间处理
{
if (TaskComps[i].Run) // 时间不为0
{
TaskComps[i].TaskHank(); // 运行任务
TaskComps[i].Run = 0; // 标志清0
}
}
}
/**************************************************************************************
* FunctionName : Timer1Callback()
* Description : 定时中断服务函数,回调函数
* ReturnValue : None
**************************************************************************************/
static void Timer1Callback(void)
{
TaskRemarks();
}
(1)初始化函数在While(1)外;
(2)任务处理函数在While(1)里。
timer_1_enable(32768/10,Timer1Callback);
参数32768表示1S,这里32768/10表示100ms。在实际操作中,中断的时间可以缩短一些,但是不能太短,频繁的中断效率也会低的。
/**************************************************************************************
* FunctionName : main()
* Description : 主函数
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
int main___(void)
{
InitSys(); // 初始化-打开定时器
//这里用的是100ms中断一次来做实验
timer_1_enable(32768/10,Timer1Callback);
while (1)
{
TaskProcess(); // 任务处理
}
}
/**************************************************************************************
* FunctionName : TaskDisplayClock()
* Description : 显示任务
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskDisplayClock(void)
{
printf("完成任务:TaskDisplayClock()");
}
/**************************************************************************************
* FunctionName : TaskKeySan()
* Description : 扫描任务
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskKeySan(void)
{
printf("完成任务:TaskKeySan()");
}
/**************************************************************************************
* FunctionName : TaskDispStatus()
* Description : 工作状态显示
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskDispStatus(void)
{
printf("完成任务:TaskDispStatus()");
}
// 这里添加其他任务。。。。。。。。。
单片机程序架构(一)时间片轮询架构_单片机时间触发器程序架构-CSDN博客
单片机的程序架构——时间片轮询【学习笔记】_单片机 时间片轮询架构-CSDN博客