51系列小型操作系统精髓 简单实现5 执行流程

1.      初始化

2.      执行完后,记录下一步地址,返回


3.      接着task_test2()

4.      执行完后,记录下一步地址,返回(与第2步相似)

5.      接着主程序While(1);

6.      定时是10Ms(18.432MHz) .定时时间到就进入定时中断执行

7.      定时中断里,把各定时到减1.  如果为0,就进入该任务处理

 

在这里有两个任务,定时时间是10*10ms和100*10ms

While(1); 执行10ms过后,定时时间是9*10ms和99*10ms,中断返回主程序。

While(1); 执行20ms过后,定时时间是8*10ms和98*10ms,中断返回主程序。

………………

8.      While(1); 执行100ms过后,定时时间是0*10ms和90*10ms, 0*10ms这个任务时间到,进入该任务处理

  

9.      继续该任务处理,执行到rtos_wait后,又返回。此时返回到中断,因为是从中断里进入的。

10.  返回到中断后,程序把中断剩下内容执行完,再回到主程序。又回到wkile(1);  (回到第5步)

 

 

附:测试程序如下

extern void rtos_init(unsigned int i);

extern void rtos_wait(unsigned char c);

#include <reg51.h>

unsigned char a=0;

unsigned char b=0;

void task_test()

{

         while(1)

         {

                   a++;

                   rtos_wait(100);                 //执行完后,记录下一步地址,返回

                   a++;

 

         }

}

void task_test2()

{

         while(1)

         {

                   b++;

                   rtos_wait(10);          //执行完后,记录下一步地址,返回

                   b++;

         }

}

void main()

{

         rtos_init(0xc400);

         task_test();

         task_test2();

         while(1); 

}

 

 

 

 

 

;********************************************

;RTOS                 用定时器0的多任务处理程序

;项目增加方式使用。

;程序不影响其它数据,目前程序的前后段不能进行参数传递 。 最多可以同时运行8个任务,

;执行时使用定时器0,定时时间根据初始化时的参数确定,一般为10mS。

;当指定优先级被占用时自动向高优先级调整,在R7中返回实际优先级,当所有高优先级都被占用时返回 0FFH,任务将被忽略。

;占用24H个内存单元。

;如果程序不可再入,需要设定 RWZT 的标志位。调用前先检查相应位。

;如果定时数设置过大,会引起一直在中断中,不能执行外部程序。如果任务执行时间过长,会引起堆栈溢出。

;18.432MHz,单时钟周期模式。不用任务单取反,输出频率1.3MHz ,指令周期 384 nS 。速度是带系统的 100 倍。

;8个任务,只对管脚取反,T0=FEF0H,输出 2.8K 频率,为最高频率。执行周期不受任务影响。18.432MHz,单时钟周期模式。

;1个任务,只对管脚取反,T0=FFE1H,输出 12K 频率,为最高频率。执行周期受任务影响。每次调度时间为42US。

;*********************************************

;------------------------------------------------------------- 示例程序

 

;***********************************************

         NAME       RTOS_C   ;程序段名

         ?PR?RTOS?RTOS_C                   SEGMENT         CODE   ;代码段 ; 段名 SEGMENT 段类型

         ?DT?RTOS?RTOS_C                   SEGMENT DATA

         ?ID?RTOS?RTOS_C          SEGMENT IDATA

        

         PUBLIC     RTOS

         PUBLIC     _RTOS_WAIT

         PUBLIC     _RTOS_INIT

;---------------------------------------------

;BANBH   EQU 0A3H        ;版本号 101221

;定义数据地址

;----------------------------------------------

RSEG         ?DT?RTOS?RTOS_C

;RWZT               EQU 29H  ;任务状态,0为停止,1为正在执行

TL:    DS1 ;EQU         30H  ;RTOS定时器值,C=FFFFH-ft

TH:   DS1 ;EQU         31H  ;18.432MHz(12周期)=C400H

RWB:        DS1 ;EQU         33H  ;任务表

 

 

RSEG         ?ID?RTOS?RTOS_C

RWDZ:     DS16                ;任务堆栈

;        EQU 80H  ;任务地址

;        EQU 8FH

RWS:         DS8          ;任务数

;        EQU 90H  ;任务定时数

;        EQU 97H

;*********************************************

       CSEG  AT   0BH        ;TO入口

       JMP     RTOS       

;*********************************************

RSEG         ?PR?RTOS?RTOS_C

 

_RTOS_INIT:                       ;任务初始化

;--------------------------------------------在 R6 R7 中,设置定时值

;RTOS定时器值,C=FFFFH-ft,18.432MHz(12周期)=C400H,40MHz(12周期)=7DC9H

;定时器0定时程序,18.432MHz,10MS,方式1

           ORL   TMOD,#01H   ;定时10MS  ;定时器0初始化,设置TMOD          MOV   TL0,R7

         MOV    TL,R7          ;设置TL

         MOV    TH0,R6

         MOV    TH,R6       ;设置TH

         MOV    RWB,#0      ;任务表清0

         SETB   TR0          ;启动定时器

         SETB   ET0              ;打开中断

         SETB   EA       ;打开总中断

         RET                ;等待中断

;**********************************************等待函数,优先级为最低 0 级,等待时间放入 R7 中

;        目前函数不能传递参数

_RTOS_WAIT:  MOV         A,R7        ;接收参数

         MOV         R5,A                   ;接收的数存在R5

         MOV         R7,#0                 ;R7清零

         CALL         YXJSZ                 ;优先级设置

         CJNE         R7,#8,RWSZ     ;R7如果不等于8,则任务设置

         MOV         R7,#0FFH ;返回值0xff  当指定优先级被占用时自动向高优先级调整,在R7中返回实际优先级,当所有高优先级都被占用时返回 0FFH,任务将被忽略。

         RET                     ;返回

;---------------------------------------------   

RWSZ:      MOV         A,R7                   ;送任务数

         ADD A,#RWS             ;

         MOV         R0,A                   ;任务数保存到R0

         MOV         A,R5                   ;R5上是 定时时间

         MOV         @R0,A          ;保存定时时间数到【R7+RWS】位置

        

         MOV         A,R7                   ;送任务数  把当前任务函数地址放入RWDZ中

         RL     A                ;

         ADD A,#RWDZ

         MOV         R0,A

         POP  ACC           ;跳转地址,在堆栈中

         POP  B

         MOV         @R0,B               ;低地址在低字节

         INC  R0

         MOV         @R0,A

        

         MOV         B,R7                   ;设置任务列表

         CLR  A                ;当前正在执行的程序如果被中断,并且中断中使用了此任务位,则此次任务将会丢失。

         INC  B                ;可以关中断来解决此问题。

         SETB         C

RWSZ2:    RLC  A

         DJNZ         B,RWSZ2

         ORL  RWB,A

         RET

;--------------------------

YXJSZ:       MOV         B,R7          ;0      ;优先级设置

         INC  B       ;B++1

         MOV         A,RWB     ;0

         CLR  C       ;0

YXJ2:         RRC A       ;RRC是带进位的循环右移指令

         DJNZ         B,YXJ2     ;如果B不等于0,  b=0

YXJ4:         JNC  YXJ3 ;C=0,则

         RRC A       ;

         INC  R7    ;

         JMP YXJ4    ;

YXJ3:         RET                  ;返回

 

;------------------------------- 中断程序   把所有相关寄存器内容压入堆栈  任务调度完后 再弹出来

RTOS:       MOV    TH0,TH              ;重载定时数

         MOV    TL0,TL                ;

         JB     PSW.3,RTOS1   ;RS0==1用于选择当前工作寄存器区。8051有8个8位寄存器R0~R7

         JB     PSW.4,RTOS2   ;RS1==1

         PUSH        0                ;RS0=0,RS1=0;  第一组寄存器区

         PUSH        1

         PUSH        2

         PUSH        3

         PUSH        4

         PUSH        5

         PUSH        6

         PUSH        7                ;存入椎栈第一组寄存器上的内容

         JMP RTOS0                ;都跳到RTOS0

RTOS1:     JB     PSW.4,RTOS3   ;

         PUSH        8                ;RS0=1,RS1=0;  第三组寄存器区

         PUSH        9

         PUSH        10

         PUSH        11

         PUSH        12

         PUSH        13

         PUSH        14

         PUSH        15

         JMP RTOS0                ;

RTOS2:    

         PUSH        10H           ;RS0=0,RS1=1;       第二组寄存器区

         PUSH        11H

         PUSH        12H

         PUSH        13H

         PUSH        14H

         PUSH        15H

         PUSH        16H

         PUSH        17H

         JMP RTOS0

RTOS3:     PUSH        18H           ;RS0=1,RS1=1; 第四组寄存器区

         PUSH        19H

         PUSH        1AH

         PUSH        1BH

         PUSH        1CH

         PUSH        1DH

         PUSH        1EH

         PUSH        1FH

 

RTOS0:     PUSH        PSW                  ;入栈

         PUSH        ACC           ;

         PUSH        B

         PUSH        DPL

         PUSH        DPH

         CALL         RWDD0             ;任务调度

         POP  DPH          ;出栈

         POP  DPL

         POP  B               

         POP  ACC

         POP  PSW

         JB     PSW.3,RTOS01

         JB     PSW.4,RTOS02

         POP  7

         POP  6

         POP  5

         POP  4

         POP  3

         POP  2

         POP  1

         POP  0                ;弹出第一组寄存器区上的变量

         RETI                   ;中断返回

RTOS01:   JB     PSW.4,RTOS3

         POP  15

         POP  14

         POP  13

         POP  12

         POP  11

         POP  10

         POP  9

         POP  8

         RETI

RTOS02:  

         POP  17H

         POP  16H

         POP  15H

         POP  14H

         POP  13H

         POP  12H

         POP  11H

         POP  10H

         RETI

RTOS03:   POP  1FH

         POP  1EH

         POP  1DH

         POP  1CH

         POP  1BH

         POP  1AH

         POP  19H

         POP  18H

         RETI

;-----------------------------       中断任务调度

RWDD0:  MOV         B,#7          ;任务号

         MOV         R0,#RWS+7      ;

         MOV         R1,#0FFH ;执行任务号

         MOV         A,RWB

         JNZ  RWDD3

         RET

RWDD3:  CLR  C

         RLC  A

         JNC  RWDD6

         CJNE         @R0,#0,RWDD2

RWDD4:  CJNE         R1,#0FFH,RWDD6

         MOV         R1,B

RWDD6:  DEC R0

         DEC B

         JNZ  RWDD3

         CJNE         R1,#0FFH,RWCL

         RET

RWDD2:  DEC @R0

         CJNE         @R0,#0,RWDD6

         JMP RWDD4

;---------------------------------

RWDD:     MOV         R1,#7

         MOV         R0,#RWS+7

         MOV         A,RWB

         JNZ  RWDD03

         RET

RWDD03:         CLR  C

         RLC  A

         JNC  RWDD06

         CJNE         @R0,#0,RWDD06

         JMP RWCL

RWDD06:         DEC R0

         DEC R1

         JNZ  RWDD03

         RET

;--------------------------------------

RWCL:      MOV         DPTR,#RWDD   ;任务处理?

         PUSH        DPL          

         PUSH        DPH

         MOV         A,R1

         RL     A

         ADD A,#RWDZ

         MOV         R0,A

         MOV         A,@R0

         PUSH        ACC           ;低地址在低字节

         INC  R0

         MOV         ACC,@R0

         PUSH        ACC

 

         MOV         A,#0FFH            ;清除任务列表  当前正在执行的程序如果在下一个中断到来时还未执行完, 它的优先级将变为最低优先级,

         INC  R1              ;可以加入一个执行标志RWZT 来解决此问题。

         CLR  C

RWCL22: RLC  A

         DJNZ         R1,RWCL22

         ANL  RWB,A

         RETI

;***********************************

         END

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黄人软件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值