在51单片机中,不能直接修改PC,但有一种方法是可以改变PC的。函数调用里会把PC值压入堆栈中,调用结束后,会把PC值弹出到PC中。
能改变PC就可以控制程序流程。
1.在任务中切换出去
#define MAX_TASKS 8 //任务槽最大个数.
unsigned char idata task_stack[MAX_TASKS][2];//任务堆栈.
//保存当前断点 并把SP=SP-2;
task_stack[task_id][0] =*(SP--);
task_stack[task_id][1] =*(SP--);
2.在定时器中,定时时间到就切换回来。
// 实时切换回
SP=task_stack[task_id]+1;
3.还需要存储定时时间
unsigned char idata task_time[MAX_TASKS]; //一个任务一个定时时间
比如定时器定时时间是10ms ,每10ms查询一次各个实时任务时间是否到。到了就切换对应的任务执行。否则各任务定时时间减10ms
#define TIMER_RELOAD() {TL0=0x00;TH0=0xC4;}//使能T/C<span style="white-space:pre"> </span> 初始10ms
void Timer0Init() //@18.432MHz { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x00; //设置定时初值 TH0 =0xC4; //设置定时初值 10ms TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1; EA=1; }
void tm0_isr() interrupt 1 using 1 { <span style="white-space: pre;"> </span>//任务时间是否到,任务时间到 实时切换回 <span style="white-space: pre;"> </span>//定时时间重载 <span style="white-space: pre;"> </span>TIMER_RELOAD(); }
4.还需要什么呢?
51系列小型操作系统精髓 简单实现2,布布扣,bubuko.com
原文:http://blog.csdn.net/chenhao0568/article/details/25950771