2010年2月18日 星期四

8051簡單多工3:簡易延時

這個簡易延時,就是跳過數次執行後再回復所要執行的函式。可以做為微量延時用,也是Bee用來控制LCM的主要方法。
但它並不精準,只能保證大於某一個時間。
它新加了以下程式:
unsigned char Task_Skip_Count[TASK_NUM]={0,0,0,0};
void (*TaskResumeFunc[TASK_NUM])(void) = {Dummy,Dummy,TestSkip0,LED_Light};

void Task_Skip(void)
{
    if ( Task_Skip_Count[TaskID] ){
        Task_Skip_Count[TaskID]--;
        if (! Task_Skip_Count[TaskID]) TaskFunc[TaskID]=TaskResumeFunc[TaskID];
    }
}

void Task_Skip_Next(void (*p_func)(void))
{
    TaskResumeFunc[TaskID]=p_func;
}

void Task_Set_Skip(unsigned char n)
{
    if (! n ) n = 1;
    TaskFunc[TaskID] = Task_Skip; // to sleep
    Task_Skip_Count[TaskID] = n;
}

各函式功能說明:
TaskSkip()就是實際執行計數用函式,在各Task未回復到使用者的程式前,就是先用它頂進去做計數用。
Task_Skip_Next()設定延時結束時,要回復的函式。先存於TaskResumeFunc[TASK_NUM]變數中。
Task_Set_Skip()設定跳過執行的次數。
因為後二個太常用一起用,所以可以用一個巨集取代。
#define TASK_SKIP_N_NEXT(n,p_func)        Task_Skip_Next(p_func);Task_Set_Skip(n);

在使用上因為涉及時間控制,但各處理器速度不同。所以只能實際量測。
Bee是先用一次簡單延時再觸發8051的腳位,量出時間,才確定要給多少值。
要是那次有別的工作用了比較長的時間,那就不保證,所以只能確定至少有多長。
像Bee用的LCM其命令之間需要73us的狀況,差不多設定跳過9次就足夠了。好在多的時間不太會影響。

另外程式開發完成後最好再量一次,因為工作多了,會和開發中的延時狀況不同,Bee的LCM程式在開發完成後發現延時多了,結果又降了一次。

有人會問,使用這種延時有什麼好處?
我只能說,可以讓多組這樣的程式一起跑,不會因一組延時就卡死。這就是一種多工的方法。


沒有留言:

張貼留言