51单片机操作系统

上传人:第*** 文档编号:31309660 上传时间:2018-02-06 格式:DOC 页数:10 大小:63KB
返回 下载 相关 举报
51单片机操作系统_第1页
第1页 / 共10页
51单片机操作系统_第2页
第2页 / 共10页
51单片机操作系统_第3页
第3页 / 共10页
51单片机操作系统_第4页
第4页 / 共10页
51单片机操作系统_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《51单片机操作系统》由会员分享,可在线阅读,更多相关《51单片机操作系统(10页珍藏版)》请在金锄头文库上搜索。

1、嵌入式实时操作系统,可以充分的利用单片机的资源,提高 CPU 使用效率。操作系统最主要就是实现任务的调度、管理。同时对于实时操作系统来说响应时间很重要。操作系统编写最主要就是用到了堆栈 SP 于 RET 指令。这两个东西怎么用呢?其实在我们每次调用函数的时候都会自动将函数的断点地址(执行函数调用时的 PC)压入到 SP 中,而从函数中返回时其实是利用 RET 指令将断点弹回到 PC(程序指针)中。所以利用堆栈和 RET 指令就可以实现简单的任务的切换。这么说肯定挺模糊的,接下来一步一步解释。首先,要知道任务是一个死循环。如下面所示,可以看出两个任务都是死循环,按照以往的情况,程序是跳不出来的,

2、只能在 while(1)中无限执行。那怎么才可以实现从 task0 到 task1 的切换呢?其实如果我们能够改变 PC 的值是不是就可以改变程序执行顺序了。任务的调度切换就是利用改变 PC 的值来改变程序执行顺序的。其次,就是要解决如何实现 PC 值的正确变换问题,如何让 PC 指向我们需要执行的地方。这就是通过堆栈来实现的。我们可以为每个任务建立一个堆栈用于保存任务 PC 的值,以及任务寄存器的值。这样每次进行任务切换时只要从相应的堆栈中取出 PC 和寄存器的值就可以实现任务的调度了。在程序中于寄存器相关的程序使用在 C 语言中嵌入汇编来实现的。因为直接使用 C 语言不能直接控制寄存器。在

3、本程序中,入栈和出栈是通过汇编实现的。一个简单的操作系统如下所示,只能实现简单的任务调度,延时。必须注意,空闲任务(Idle)必须建立,否则会出错。#include#define OSEnterCritical() EA=0#define OSExitCritical() EA=1#define EnterInt() EA=0;#define uint unsigned short int#define uchar unsigned char#define MAX_Tasks 3#define False 0#define Ture 1#define MaxPrio 2#define Idle

4、Prio MaxPrio#define OS_Task_Create_Error 1#define OS_Delet_Task_Error 2#define OS_Delet_Task_Not_Exit 3#define OS_Resume_Idle_Error 4#define OS_Resume_Task_Error 5typedef structuchar OSStackTop; /SPuchar OSSuspend;uchar OSTCBDly; /delay timeOSTCB;uchar code OSMapTbl8=0x01,0x02,0x04,0x08,0x10,0x20,0x

5、40,0x80;OSTCB OSTCBTblMAX_Tasks;volatile uchar OSRdyTbl;volatile uchar OSIntNesting; /用于中断锁死volatile uchar OSSchNesting; /任务切换上锁volatile uchar OSRuning=False;volatile uchar OSStartStackMAX_Tasks20;volatile uchar OSPointMAX_Tasks2;volatile uchar OSPrioCur;/volatile uchar OSTaskPend;OSInit()/ uchar i;

6、EA=0;ET0=1;TMOD=0x01;TH0=0xB1;TL0=0xE0;OSRdyTbl=0;OSIntNesting=0;OSSchNesting=0;/PCL,PCH,ACC ,B,DPL,DPH,PSW,R0-R7uchar *OSStackInit(uint task,uchar *ptr,uchar OSPrio)uchar* stk;stk=ptr;OSPointOSPrio0=task;OSPointOSPrio1=task8;*(stk+)= OSPointOSPrio0;*(stk+)= OSPointOSPrio1;*(stk+)= 0x00; /ACC*(stk+)

7、= 0x00;*(stk+)= 0x00;*(stk+)= 0x00;*(stk+)= 0x00;*(stk+)= 0x00;*(stk+)= 0x00;*(stk+)= 0x00;*(stk+)= 0x00;*(stk+)= 0x00;*(stk+)= 0x00;*(stk+)= 0x00; *(stk) = 0x00; return stk;uchar OSTaskCreate(uint task,uchar *ptr,uchar OSPrio)uchar* psp;OSEnterCritical();if(OSPrio=IdlePrio)OSExitCritical();return O

8、S_Delet_Task_Error;if(!(OSRdyTbl & OSMapTblpriority)OSExitCritical();return OS_Delet_Task_Not_Exit;OSRdyTbl OSExitCritical();if(priority=0)OSRdyTbl |= (OSMapTblpriority);else /返回的任务不存在,返回错误标志OSExitCritical();return OS_Resume_Task_Error;OSExitCritical();if(priorityOSPrioCur)OSSchedule();/*=定时器 0 用于产生

9、系统时钟,这里每过 20ms 中断一次。=*/void timer0() interrupt 1uchar i;EA=0;TR0=0;TH0=0xB1;TL0=0xE0;if(OSRuning=Ture) /如果不是第一次调度则保护任务堆栈 ,有部分堆栈进入中断时自动完成 /定时器自动保护的堆栈可通过反汇编查看,以此确定堆栈的安排顺序_asm PUSH 1_asm PUSH 2_asm PUSH 3_asm PUSH 4_asm PUSH 5_asm PUSH 6OSTCBTblOSPrioCur.OSStackTop=SP;else /第一次进入则将 OSRuning 置位OSRuning=

10、Ture;if(OSRuning=Ture)/如在运行,for(i=0;iMAX_Tasks;i+)if(OSRdyTbl & OSMapTbli) & OSTCBTbli.OSTCBDly)/如果任务需要延时,将任务延时参数减一OSTCBTbli.OSTCBDly-;if(OSTCBTbli.OSTCBDly=0)OSTCBTbli.OSSuspend=0;for(i=0;iMAX_Tasks;i+)if(OSRdyTbl & OSMapTbli) & (!OSTCBTbli.OSSuspend)/查找优先级最高的且未挂起的任务OSPrioCur=i;break;SP=OSTCBTblOSP

11、rioCur.OSStackTop;#pragma asmPOP 6;POP 5;POP 4;POP 3;POP 2;POP 1;/* POP 7;POP 0; POP PSW;POP DPH;POP DPL;POP ACC; */#pragma endasmTR0=1;EA=1;void Idle()while(1);void task0()uchar temp=0x01,i;while(1)for(i=0;i8;i+)P1=temp;temp=1;OSDelay(10);temp=0x01;void task1()uchar i=0,j=0;while(1)for(i=0;i16;i+)P3=j;OSDelay(20);j+;j=0;int main()OSInit();OSTaskCreate(OSTaskCreate(OSTaskCreate(OSStart();

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 其它中学文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号