单片机的程序架构——时间片轮询【学习笔记】

    科技2022-07-10  155

    单片机的程序架构

    1.顺序执行2.时间片轮寻:==2.0 一个定时器的复用:====2.1 时间片轮询架构:====2.2 具体实现:==2.2.1定义 任务结构体2.2.2初始化 任务结构体2.2.3定义 任务清单&任务数目 枚举类型2.2.4编写 定时器中断函数&任务处理函数2.2.5编写main函数2.2.6编写你的任务函数 ==2.3 注意点== 3.操作系统:

    1.顺序执行

    /************************************************************************************** * FunctionName : main() * Description : 主函数 * EntryParameter : None * ReturnValue : None **************************************************************************************/ int main(void) { uint8 keyValue; InitSys(); // 初始化 while (1) { TaskDisplayClock(); keyValue = TaskKeySan(); switch (keyValue) { case x: TaskDispStatus(); break; ... default: break; } } }

    2.时间片轮寻:

    2.0 一个定时器的复用:
    【中断过于频繁效率就低,中断太长,实时性差】——设置合适的定时器中断时间 ①首先定义任务数、任务定时初值(任务轮询时间=定时初值*定时器中断时间)、任务定时计数器。②在定时器中断服务函数中添加【复用函数】 #define TASK_NUM (3) // 这里定义的任务数为3,表示有三个任务会使用此定时器定时。 uint16 TaskCount[TASK_NUM] ; // 这里为三个任务定义三个变量来存放定时值 uint8 TaskMark[TASK_NUM];// 同样对应三个标志位,为0表示时间没到,为1表示定时时间到。 /************************************************************************************** * FunctionName : TimerInterrupt() * Description : 定时中断服务函数 * EntryParameter : None * ReturnValue : None **************************************************************************************/ void TimerInterrupt(void) { uint8 i; for (i=0; i<TASKS_NUM; i++) { if (TaskCount[i]) { TaskCount[i]--; if (TaskCount[i] == 0) { TaskMark[i] = 0x01; } } } }

    定时中断服务函数中:对任务逐个判断 定时计数到了没有 & 置标志为1 & 定时计数初值重置

    如果定时值为0了,表示没有使用此定时器或此定时器已经完成定时,已经处理。

    如果定时值不为0,定时器减一, 这时为零时,相应标志位值1,表示此任务的定时值到了

    2.1 时间片轮询架构:
    两个函数+一个结构体======》时间片轮询架构 // 任务结构 typedef struct _TASK_COMPONENTS { uint8 Run; // 程序运行标记:0-不运行,1运行 uint8 Timer; // 计时器 uint8 ItvTime; // 任务运行间隔时间【AKA计时器初始值值】 void (*TaskHook)(void); // 要运行的任务函数 } TASK_COMPONENTS; // 任务定义 /************************************************************************************** * FunctionName : TaskRemarks() * Description : 任务标志处理 * EntryParameter : None * ReturnValue : None * attention : ***在定时器中断中调用此函数即可*** **************************************************************************************/ void TaskRemarks(void) { uint8 i; for (i=0; i<TASKS_MAX; i++) // 逐个任务时间处理 { if (TaskComps[i].Timer) // 时间不为0 { TaskComps[i].Timer--; // 减去一个节拍 if (TaskComps[i].Timer == 0) // 时间减完了 { TaskComps[i].Timer = TaskComps[i].ItvTime; // 恢复计时器值,从新下一次 TaskComps[i].Run = 1; // 任务可以运行 } } } } /************************************************************************************** * FunctionName : TaskProcess() * Description : 任务处理|判断什么时候该执行那一个任务 * EntryParameter : None * ReturnValue : None * * attention : ***放在mian的while(1)即可*** **************************************************************************************/ void TaskProcess(void) { uint8 i; for (i=0; i<TASKS_MAX; i++) // 逐个任务时间处理 { if (TaskComps[i].Run) // 时间不为0 { TaskComps[i].TaskHook(); // 运行任务 TaskComps[i].Run = 0; // 标志清0 } } }
    2.2 具体实现:
    2.2.1定义 任务结构体
    // 任务结构 typedef struct _TASK_COMPONENTS { uint8 Run; // 程序运行标记:0-不运行,1运行 uint8 Timer; // 计时器 uint8 ItvTime; // 任务运行间隔时间【AKA计时器初始值值】 void (*TaskHook)(void); // 要运行的任务函数 } TASK_COMPONENTS; // 别名
    2.2.2初始化 任务结构体
    static TASK_COMPONENTS TaskComps[] = { {0, 60, 60, TaskDisplayClock}, // 显示时钟 {0, 20, 20, TaskKeySan}, // 按键扫描 {0, 30, 30, TaskDispStatus}, // 显示工作状态 // 这里添加你的任务。。。。 };
    2.2.3定义 任务清单&任务数目 枚举类型
    // 任务清单 typedef enum _TASK_LIST { TAST_DISP_CLOCK, // 显示时钟 TAST_KEY_SAN, // 按键扫描 TASK_DISP_WS, // 工作状态显示 // 这里添加你的任务。。。。 TASKS_MAX // 总的可供分配的定时任务数目 } TASK_LIST;
    2.2.4编写 定时器中断函数&任务处理函数
    /************************************************************************************** * FunctionName : TaskRemarks() * Description : 任务标志处理 * EntryParameter : None * ReturnValue : None * attention : ***在定时器中断中调用此函数即可*** **************************************************************************************/ void TaskRemarks(void) { uint8 i; for (i=0; i<TASKS_MAX; i++) // 逐个任务时间处理 { if (TaskComps[i].Timer) // 时间不为0 { TaskComps[i].Timer--; // 减去一个节拍 if (TaskComps[i].Timer == 0) // 时间减完了 { TaskComps[i].Timer = TaskComps[i].ItvTime; // 恢复计时器值,从新下一次 TaskComps[i].Run = 1; // 任务可以运行 } } } } /************************************************************************************** * FunctionName : TaskProcess() * Description : 任务处理|判断什么时候该执行那一个任务 * EntryParameter : None * ReturnValue : None * * attention : ***放在mian的while(1)即可*** **************************************************************************************/ void TaskProcess(void) { uint8 i; for (i=0; i<TASKS_MAX; i++) // 逐个任务时间处理 { if (TaskComps[i].Run) // 时间不为0 { TaskComps[i].TaskHook(); // 运行任务 TaskComps[i].Run = 0; // 标志清0 } } }
    2.2.5编写main函数
    初始化函数在while(1)外任务处理函数在while(1)里 /************************************************************************************** * FunctionName : main() * Description : 主函数 * EntryParameter : None * ReturnValue : None **************************************************************************************/ int main(void) { InitSys(); // 初始化-打开定时器 while (1) { TaskProcess(); // 任务处理 } }
    2.2.6编写你的任务函数
    /************************************************************************************** * FunctionName : TaskDisplayClock() * Description : 显示任务 * EntryParameter : None * ReturnValue : None **************************************************************************************/ void TaskDisplayClock(void) { } /************************************************************************************** * FunctionName : TaskKeySan() * Description : 扫描任务 * EntryParameter : None * ReturnValue : None **************************************************************************************/ void TaskKeySan(void) { } /************************************************************************************** * FunctionName : TaskDispStatus() * Description : 工作状态显示 * EntryParameter : None * ReturnValue : None **************************************************************************************/ void TaskDispStatus(void) { } // 这里添加其他任务。。。。。。。。。
    2.3 注意点

    任务与任务间数据传递时,数据传递要采用全局变量

    3.操作系统:

    FreeRTOS、鸿蒙os~~~【略】

    >>>这是一篇学习笔记,感谢博主:@Good__life
    Processed: 0.025, SQL: 8