📄 ucos51移植心得.htm
字号:
MOV DPH,R0<BR>
MOV DPL,R1<BR>
<BR> ;*UserStkPtr
===> R5 用户堆栈起始地址内容(即用户堆栈长度放在此处) 详见文档说明
指针用法详见C51.PDF第169页
<BR> MOVX
A,@DPTR ;用户堆栈中是unsigned
char类型数据<BR>
MOV R5,A
;R5=用户堆栈长度<BR>
<BR>
;恢复现场堆栈内容<BR>
MOV
R0,#OSStkStart<BR>
<BR>restore_stack:<BR>
<BR> INC
DPTR<BR> INC
R0<BR> MOVX
A,@DPTR<BR>
MOV @R0,A<BR>
DJNZ R5,restore_stack<BR>
<BR>
;恢复堆栈指针SP<BR>
MOV SP,R0<BR>
<BR>
;OSRunning=TRUE<BR>
MOV R0,#LOW
(OSRunning)<BR>
MOV @R0,#01<BR>
<BR>
POPALL<BR> SETB
EA
;开中断<BR>
RETI<BR>;-------------------------------------------------------------------------<BR>
RSEG ?PR?OSCtxSw?OS_CPU_A<BR>OSCtxSw:
<BR>
PUSHALL<BR>
<BR>OSIntCtxSw_in:<BR>
<BR>
;获得堆栈长度和起址<BR>
MOV A,SP<BR>
CLR C<BR> SUBB
A,#OSStkStart<BR>
MOV R5,A
;获得堆栈长度
<BR>
<BR> ;OSTCBCur
===> DPTR
获得当前TCB指针,详见C51.PDF第178页<BR>
MOV R0,#LOW (OSTCBCur)
;获得OSTCBCur指针低地址,指针占3字节。+0类型+1高8位数据+2低8位数据<BR>
INC R0<BR>
MOV DPH,@R0
;全局变量OSTCBCur在IDATA中<BR>
INC R0<BR>
MOV DPL,@R0<BR>
<BR>
;OSTCBCur->OSTCBStkPtr ===> DPTR
获得用户堆栈指针<BR>
INC DPTR
;指针占3字节。+0类型+1高8位数据+2低8位数据<BR>
MOVX A,@DPTR
;.OSTCBStkPtr是void指针<BR>
MOV R0,A<BR>
INC DPTR<BR>
MOVX A,@DPTR<BR>
MOV R1,A<BR>
MOV DPH,R0<BR>
MOV DPL,R1<BR>
<BR>
;保存堆栈长度<BR>
MOV A,R5<BR>
MOVX @DPTR,A<BR>
<BR> MOV
R0,#OSStkStart
;获得堆栈起址<BR>save_stack:<BR>
<BR> INC
DPTR<BR> INC
R0<BR> MOV
A,@R0<BR> MOVX
@DPTR,A<BR> DJNZ
R5,save_stack<BR>
<BR>
;调用用户程序<BR> LCALL
_?OSTaskSwHook<BR>
<BR> ;OSTCBCur =
OSTCBHighRdy<BR>
MOV R0,#OSTCBCur<BR> MOV
R1,#OSTCBHighRdy<BR> MOV
A,@R1<BR> MOV
@R0,A<BR> INC
R0<BR> INC R1<BR>
MOV A,@R1<BR>
MOV @R0,A<BR>
INC R0<BR> INC
R1<BR> MOV
A,@R1<BR> MOV
@R0,A<BR>
<BR> ;OSPrioCur =
OSPrioHighRdy
使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。<BR>
MOV R0,#OSPrioCur<BR> MOV
R1,#OSPrioHighRdy<BR> MOV
A,@R1<BR> MOV
@R0,A<BR>
<BR> LJMP
OSCtxSw_in<BR>;-------------------------------------------------------------------------<BR>
RSEG
?PR?OSIntCtxSw?OS_CPU_A<BR>
<BR>OSIntCtxSw:</P>
<P>
;调整SP指针去掉在调用OSIntExit(),OSIntCtxSw()过程中压入堆栈的多余内容<BR>
;SP=SP-4</P>
<P> MOV
A,SP<BR> CLR
C<BR> SUBB
A,#4<BR> MOV
SP,A<BR>
<BR> LJMP
OSIntCtxSw_in<BR>;-------------------------------------------------------------------------<BR>
CSEG AT 000BH
;OSTickISR<BR> LJMP
OSTickISR
;使用定时器0<BR> RSEG
?PR?OSTickISR?OS_CPU_A</P>
<P>OSTickISR:
<BR>
<BR> USING
0
<BR>
PUSHALL<BR>
<BR> CLR
TR0<BR> MOV
TH0,#70H
;定义Tick=50次/秒(即0.02秒/次)<BR>
MOV TL0,#00H ;OS_CPU_C.C 和
OS_TICKS_PER_SEC<BR>
SETB TR0<BR>
<BR> LCALL
_?OSIntEnter<BR>
LCALL
_?OSTimeTick<BR>
LCALL
_?OSIntExit<BR>
POPALL
<BR>
RETI<BR>;-------------------------------------------------------------------------<BR>
CSEG AT 0023H
;串口中断<BR> LJMP
SerialISR
;工作于系统态,无任务切换。<BR>
RSEG
?PR?_?serial?OS_CPU_A<BR>
<BR>SerialISR:<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -