經(jīng)典單片機(jī)C51多任務(wù)代碼(改進(jìn)版)
if(RWCH_BZ==0)
{//棧調(diào)整代碼
SP+=2;//第一次切換程序時(shí)原棧沒有(POP PSW 和POP ACC 數(shù)據(jù)調(diào)整一下,為什么請(qǐng)查匯編代碼)
//為什么要加上面代碼的分析
//中斷中其實(shí)隱含了以下代碼
//PUSH ACC
//PUSH PSW
//----------------本文引用地址:http://2s4d.com/article/201611/323535.htm
//中斷內(nèi)的實(shí)際代碼
//----------------
//下面兩句的數(shù)據(jù)在每個(gè)任務(wù)第一次切換時(shí)任務(wù)棧內(nèi)其實(shí)并沒有它的數(shù)據(jù),如果不調(diào)整,這兩句將會(huì)把返回地址數(shù)據(jù)給POP掉
//所以進(jìn)行SP+2處理才會(huì)正常返回切換后的任務(wù),從而騙過CPU
//POP PSW
//POP ACC
//RET
}
//============================================
//setb et1
ET0=1;//開中斷
//setb tr1
TR0=1;//開定時(shí)器
}
//===================================
//=======================================================================
/*
//網(wǎng)絡(luò)原碼
#include
#define MAX_TASKS 2 //任務(wù)槽個(gè)數(shù).必須和實(shí)際任務(wù)數(shù)一至
#define MAX_TASK_DEP 12 //最大棧深.最低不得少于2個(gè),保守值為12.
unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP];//任務(wù)堆棧.
unsigned char task_id; //當(dāng)前活動(dòng)任務(wù)號(hào)
unsigned char idata task_sp[MAX_TASKS];
//任務(wù)切換函數(shù)(任務(wù)調(diào)度器)
void task_switch(){
task_sp[task_id] = SP;
if(++task_id == MAX_TASKS)
task_id = 0;
SP = task_sp[task_id];
}
//任務(wù)裝入函數(shù).將指定的函數(shù)(參數(shù)1)裝入指定(參數(shù)2)的任務(wù)槽中.如果該槽中原來就有任務(wù),則原任務(wù)丟失,但系統(tǒng)本身不會(huì)發(fā)生錯(cuò)誤.
void task_load(unsigned int fn, unsigned char tid){
task_sp[tid] = task_stack[tid] + 1;
task_stack[tid][0] = (unsigned int)fn & 0xff;
task_stack[tid][1] = (unsigned int)fn >> 8;
}
//從指定的任務(wù)開始運(yùn)行任務(wù)調(diào)度.調(diào)用該宏后,將永不返回.
#define os_start(tid) {task_id = tid,SP = task_sp[tid];return;}
void task1(){
static unsigned char i;
while(1){
i++;
task_switch();//編譯后在這里打上斷點(diǎn)
}
}
void task2(){
static unsigned char j;
while(1){
j+=2;
task_switch();//編譯后在這里打上斷點(diǎn)
}
}
void main(){
//這里裝載了兩個(gè)任務(wù),因此在定義MAX_TASKS時(shí)也必須定義為2
task_load(task1, 0);//將task1函數(shù)裝入0號(hào)槽
task_load(task2, 1);//將task2函數(shù)裝入1號(hào)槽
os_start(0);
}
*/
//=======================================================================
評(píng)論