51系列小型操作系统精髓 简单实现12 C语言版再优化

来源:互联网 发布:907和140数据对比 编辑:程序博客网 时间:2024/05/18 02:44

/*CRTOS 实时可剥夺型内核1.任务不用预加载,不用预定义。任务调用时加载,可删除(退出死循环即可)2.单位轮转查询时间由晶振和定时器初始化决定。在这里为10ms3.定时时间为【 time*单位轮转查询时间 】 ,其中time为 rtos_wait(time)中time.4.可运行多个任务【自定义】5.任务从rtos_wait()处切换,在定时时间到后从定时中断中切换回来,任务执行后,回到中断,再从中断回到主程序。*/#include "STC12C5A.H"#define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T/C  初始10ms#define MAX_TASKS 2 //任务槽最大个数.unsigned char data task_stack[MAX_TASKS][2];//任务堆栈.  PC指针为16位,需2个字节task_stack[][0]L  task_stack[][1]H。unsigned char data task_time[MAX_TASKS];//定时时间unsigned char data task_id=0; //当前活动任务号void Timer0Init()//@18.432MHz{AUXR &= 0x7F;//定时器时钟12T模式TMOD &= 0xF0;//设置定时器模式TMOD |= 0x01;//设置定时器模式TL0 = 0x00;//设置定时初值TH0 =0xC4;//设置定时初值 10msTF0 = 0;//清除TF0标志TR0 = 1;//定时器0开始计时ET0=1;EA=1;}void rtos_wait(unsigned char time){task_time[task_id]=time;   //保存当前任务时间task_stack[task_id][1] =*((unsigned char data* )(SP));  //保存当前断点 并把SP=SP-2,任务切换到下一任务;SP--;task_stack[task_id][0] =*((unsigned char data*)(SP));SP--;for(task_id=0;task_id<MAX_TASKS && task_time[task_id];task_id++){} //任务号设为最大,越过最大则回到0 //根据定时时间判断//if(task_id==MAX_TASKS) //任务满 超出则回到0//task_id=0;}void rwcl() //任务时间是否到,任务时间到 实时切换回{//从把定时时间减1 ,找看哪个任务到,任务时间到 实时切换回unsigned char data i;for(i=0;i<MAX_TASKS && task_time[i];i++){if(--task_time[i]==0)//多个定时时间同时到,任务越靠后,越优先执行。{task_id=i;//当前任务号//保存的PC指针调出来SP++;(*((unsigned char data*)(SP)))=task_stack[i][0];SP++;(*((unsigned char data*)(SP)))=task_stack[i][1] ;}}}void tm0_isr() interrupt 1 //using 1{ TIMER_RELOAD(); //定时时间重载rwcl(); //任务时间是否到,任务时间到 实时切换回}//****************************************************************示例unsigned char a=0;unsigned char bb=0;void task_test(){while(1){  a++;rtos_wait(10); //执行完后,记录下一步地址,返回a++;}}void task_test2(){while(1){bb++;rtos_wait(10);//执行完后,记录下一步地址,返回bb++;}}void main(){Timer0Init();task_test();task_test2();while(1);}


1 0
原创粉丝点击