這個代碼是從網(wǎng)上看到,經(jīng)過少量修改得到的,如果有侵刪請告知。
- //===========簡易任務(wù)調(diào)度器==============
- #define TASK_MAX 2 //任務(wù)的數(shù)量記得匹配一下
- typedef struct _TASK_COMPONENTS
- {
- unsigned char TaskNumber; //表示任務(wù)的編號
- unsigned char Run; // 0表示任務(wù)不運行,1表示任務(wù)運行
- unsigned int Timer; // 表示任務(wù)的執(zhí)行間隔時間
- unsigned int ItvTime; // 參數(shù)傳遞作用,數(shù)值上等于Timer
- void (*TaskHook)(void); //任務(wù)函數(shù)
- }TASK_COMPONENTS;
- static TASK_COMPONENTS TaskComps[]= //任務(wù)的編號,從0開始
- {
- {0,0,1000,1000, Task1}, //因為定時器是1ms的,也就是這個任務(wù)的執(zhí)行間隔時間是200ms
- {1,0,10, 10, Task2}, //****按照格式可以補充你的任務(wù)****/
- };
- void TaskHangup(unsigned char Task_Num)//任務(wù)掛起函數(shù),參數(shù)就是你的任務(wù)編號
- {
- TaskComps[Task_Num].Run=0;
- }
- void TaskRecovery(unsigned char Task_Num)//任務(wù)恢復(fù)函數(shù),參數(shù)就是你的任務(wù)編號
- {
- TaskComps[Task_Num].Run=1;
- }
- void TaskRemarks(void) //放在你的定時器中斷里面 定時器需要設(shè)定1ms中斷一次
- {
- unsigned char i;
- for (i=0; i<TASK_MAX; i++) // 逐個任務(wù)時間處理
- {
- if (TaskComps[i].Timer) // 時間不為0
- {
- TaskComps[i].Timer--; // 減去一個節(jié)拍
- if ((TaskComps[i].Timer == 0) ||(TaskComps[i].Timer>0XFFF0)) // 時間減完了 [/size][/indent][size=4]//如果任務(wù)執(zhí)行時間比較長,可能當時間片減到0的時候任務(wù)還在執(zhí)行,然后減下去就溢出,是0XFFFF
- //所以用[/size][size=4]0XFFF0[/size][size=4]這個值保證溢出的時候也能執(zhí)行下面的語句
- {
- TaskComps[i].Timer = TaskComps[i].ItvTime; // 恢復(fù)計時器值,從新下一次
- TaskComps[i].Run = 1; // 任務(wù)可以運行
- }
- }
- }
- }
- void TaskProcess(void)//放在你的while(1)循環(huán)里面
- {
- unsigned char i;
- for (i=0; i<TASK_MAX; i++) // 逐個任務(wù)判斷是否達到執(zhí)行條件
- {
- if (TaskComps[i].Run) // 達到執(zhí)行條件
- {
- TaskComps[i].Run = 0; // 標志清0 把這句話放下面會出現(xiàn)異常 原因暫未查明
- TaskComps[i].TaskHook(); // 運行任務(wù)
- }
- }
- MCU_IDLE();//進入低功耗模式
- }[/size]</font>
復(fù)制代碼 一些說明:
1、MCU_IDLE();//進入低功耗模式 32和51的低功耗函數(shù)是不一樣的,這里只是提供一種低功耗的思路,比如51低功耗函數(shù)直接操作PCON寄存器,定時器中斷會喚醒,喚醒后會執(zhí)行TaskRemarks函數(shù),判斷任務(wù)時間是否到了,到了標志位置1。
2、Task1等函數(shù)具體可以更換為自己的任務(wù)函數(shù)名稱,但是在這個文件內(nèi)使用的話記得加extern聲明一下是外部函數(shù)。
3、這個調(diào)度器實際上就是一個定時器做事件的時間基準,建議任務(wù)函數(shù)內(nèi)部的延時時間不要大于任務(wù)執(zhí)行的間隔時間。因為實際的執(zhí)行過程一定是任務(wù)0先執(zhí)行(即使里面有長延時函數(shù)),接著執(zhí)行任務(wù)1,任務(wù)2等。
總結(jié):該調(diào)度器只是簡單按照任務(wù)次序輪詢,無法按照任務(wù)執(zhí)行的間隔時間做實時切換。對于大部分對任務(wù)執(zhí)行時間精確度要求不高的場合,是比較好用的。這樣的架構(gòu)也會使代碼相對簡潔一些。
|