#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define tasknumsize 3
uint idata wait[tasknumsize];
uchar taskrdy=0xff,curtask,nxttask;
void cswitch();
void waitdly(uint dly);
void taskA()
{
uchar temp,i;
while(1)
{
temp=0x01;
for(i=0;i<8;i++)
{
P1=temp;
temp=temp<<1;
waitdly(10);
}
}
}
void taskB()
{
while(1)
{
P2+=1;
waitdly(20);
}
}
void taskC()
{
while(1)
{
P3+=2;
waitdly(30);
}
}
void init()
{
TMOD=0x01;//方式1,16位模式,不会自动清零。
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
EA=1;
ET0=1;
}
void * const func[]={taskA,taskB,taskC};
uchar tasknum=0;
uchar stk[3*2];
main()
{
uchar num,j;
tasknum=0;
for(;num<3;num++,j+=2)
{
stk[j]=((uint)(func[num]))%256;
stk[j+1]=((uint)(func[num]))/256;
}
init();
taskA();
}
void cswitch()
{
uchar idata *ssp;
uchar temp;
ssp=(uchar *)SP-3; //这里是改变waitdly()函数的返回指针来实现任务的切换的
tasknum=curtask;
stk[tasknum*2]=*ssp++; //保存当前任务的返回指针
stk[tasknum*2+1]=*ssp;
ssp--;
temp=taskrdy;
for(nxttask=0;nxttask<tasknumsize;nxttask++)
{
if((temp & 0x80)!=0)
break;
temp=temp<<1;
}
tasknum=nxttask;
*ssp++=stk[tasknum*2]; //使将要运行任务的返回指针放入堆栈中,进行任务切换.
*ssp=stk[tasknum*2+1];
curtask=nxttask;
}
void waitdly(uint dly)
{
wait[curtask]=dly;
while(wait[curtask]!=0)
{
taskrdy &= ~(0x80>>curtask); //挂起当前任务
cswitch();
}
}
void timer0() interrupt 1
{
uchar t;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
for(t=0;t<tasknumsize;t++)
{
if(wait[t]>0)
{
wait[t]--;
if(wait[t]==0)
taskrdy |= (0x80>>t);//使任务进入就绪态
}
}
}
注意:本程序只是展示如何实现,其中还存在问题并不很完美. 呵呵