您的位置:首页 > 其它

各任务间的堆栈空间变换

2015-08-28 15:55 399 查看
#include<reg51.h>

#define uint unsigned int

#define uchar unsigned char

#define tasknumsize 3

#define ramsize 128

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(50);

}

}

void * const func[tasknumsize]={taskA,taskB,taskC};

uchar idata *stk[tasknumsize+1];

void initstarttask()

{

uchar idata *sspp,i;

sspp=(uchar idata *)SP+1; //需要指向堆栈的下一个空位处,51为满增堆栈.

stk[0]=(uchar idata *)SP+1;

stk[tasknumsize] = (uchar idata *)(ramsize);

*sspp++=((uint)(func[0]))%256;

*sspp=((uint)(func[0]))/256;

SP=(uchar)sspp;

sspp=(uchar idata *)(ramsize-1);

for(i=tasknumsize-1;i>0;i--)

{

*sspp--=((uint)(func[i]))/256;

stk[i]=sspp;

*sspp--=((uint)(func[i]))%256;

}

}

void inittimer0()

{

TMOD=0x01;//方式1,16位模式,不会自动清零。

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

TR0=1;

EA=1;

ET0=1;

}

main()

{

inittimer0();

initstarttask(); //main函数中最后调用的这个函数是不会将函数的返回地址压入到堆栈中

}

void cswitch()

{

uchar idata *sp1,idata *sp2;

uchar temp,svsp,i;

temp=taskrdy;

for(nxttask=0;nxttask<tasknumsize;nxttask++)

{

if((temp & 0x80)!=0)

break;

temp=temp<<1;

}

if(nxttask==tasknumsize)

nxttask=0;

svsp=(uchar)SP;

sp1=(uchar *)SP+1;

sp2=stk[curtask+1];

temp=(uchar)stk[nxttask+1];

if(nxttask>curtask)

{

while(sp2!=(uchar idata *)temp) //堆栈空间变换

{

*sp1++=*sp2++;

}

SP=(uchar)sp1-1;

temp=stk[curtask+1]-(uchar idata *)svsp-1;

for(i=curtask+1;i<nxttask+1;i++)

{

stk[i]-=temp;

}

}

if(nxttask<curtask)

{

sp1--;sp2--;

while(sp1!=((uchar idata *)temp-1))    //堆栈空间变换

{

*sp2--=*sp1--;

}

SP=(uchar)stk[nxttask+1]-1;

temp=stk[curtask+1]-(uchar idata *)svsp-1;

for(i=nxttask+1;i<curtask+1;i++)

{

stk[i]+=temp;

}

}

if(nxttask==curtask)

SP=svsp;

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);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: