這是基本延時功能,但要各組Task都可以使用。LED閃爍最常用了。
新加程式碼如下:
idata unsigned char Task_Delay_Count[TASK_NUM]={0,0,0,0};
void Dummy(void)
{
return;
}
void Task_Delay_Next(void (*p_func)(void))
{
TaskResumeFunc[FuncID]=p_func;
}
void Task_Delay_Ms(unsigned char n)
{
if (! n ) n = 1;
TaskFunc[FuncID] = Dummy; // to sleep
Task_Delay_Count[FuncID] = n;
}
void Timer0_ISR (void) interrupt INTERRUPT_TIMER0
{
unsigned char i;
TL0 = 0x80;
TH0 = 0x44; // set delay for 1 ms
for ( i=0; i<TASK_NUM; i++)
{
if ( Task_Delay_Count[i] ) {
Task_Delay_Count[i]--;
if (! Task_Delay_Count[i]) TaskFunc[i]=TaskResumeFunc[i]; // wake up function
}
}
}
各函式功能說明:
Dummy()使用中斷延時,原本的函式就會用這個取代。
Task_Delay_Next()設定延時完畢後要執行的函式。
Task_Delay_Ms()設定延時時間。
Timer0_ISR()中斷程式。
大家可以比較一下和上篇的差異,其實主要的功能是一樣的,只是改由中斷做。
只有一個問題可能在使用時會遇到,那就是設定延時的變數Bee是用unsigned char,所以只能延時255ms。
因為Bee剛好就用這麼多,要加長就改一下變數型態就可以了。
Bee大大 您好
回覆刪除請問如果idata unsigned char Task_Delay_Count[TASK_NUM]={0,0,0,0};
改成16 bit idata unsigned short Task_Delay_Count[TASK_NUM]={0,0,0,0};
那麼
void Task_Delay_Ms(unsigned char n)
{
if (! n ) n = 1; TaskFunc[FuncID] = Dummy; // to sleep
Task_Delay_Count[FuncID] = n;
}
須要改成
void Task_Delay_Ms(unsigned char n)
{
if (! n ) n = 1;
TaskFunc[FuncID] = Dummy; // to sleep
EA=0;
Task_Delay_Count[FuncID] = n;
EA=1;
} 嗎?
謝謝!
[版主回覆02/19/2010 12:22:56]沒錯,是要這樣改。我沒有注意到。
不然low byte剛好是1,可能會產生問題。
如果是compiler先填high byte還好,但這點不保證。還是保護起來會比較正常。
版主你好 最近正在學習你的簡單版RTOS 覺得收益良多 想請問說 timer作用是讓原本的執行續插入一個工作嗎?
回覆刪除這個仍不算RTOS。這個timer只是移出執行,等時間到再移回來推入執行矩陣。
刪除