各任务间的堆栈空间变换

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值