⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_a.a51

📁 实现ucos任务调度时保存LCD上的显示信息
💻 A51
字号:
;/*
;*********************************************************************************************************
;*                                               uC/OS-II
;*                                               实时内核
;*
;*                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
;*                                               版权所有
;*
;*                                            MCU-51 专用代码
;*                                           KEIL C51小模式编译
;*
;* 文件名 : OS_CPU_A.ASM
;* 作者   : Jean J. Labrosse
;* 改编   : 杨屹 gdtyy@ri.gdt.com.cn 巨龙公司系统集成开发部 2002.09.27
;*********************************************************************************************************
;*/
$NOMOD51

EA	BIT	    0A8H.7
SP	DATA	081H
B	DATA	0F0H
ACC	DATA	0E0H
DPH	DATA	083H
DPL	DATA	082H
PSW	DATA	0D0H
TR0	BIT	    088H.4
TF0 BIT     088H.5
TH0	DATA	08CH
TL0	DATA	08AH

        NAME OS_CPU_A    ;模块名
        
;定义重定位段
?PR?OSStartHighRdy?OS_CPU_A    SEGMENT CODE
?PR?OSCtxSw?OS_CPU_A           SEGMENT CODE
?PR?OSIntCtxSw?OS_CPU_A        SEGMENT CODE
?PR?OSTickISR?OS_CPU_A         SEGMENT CODE
        
;声明引用全局变量和外部子程序
        EXTRN DATA  (?C_XBP)     ;仿真堆栈指针用于重入局部变量保存
        EXTRN IDATA (STACK)

        EXTRN DATA (OSTCBCur)
        EXTRN DATA (OSTCBHighRdy)
        EXTRN DATA (OSRunning)
        EXTRN DATA (OSPrioCur)
        EXTRN DATA (OSPrioHighRdy)
    
        EXTRN CODE  (_?OSTaskSwHook)
        EXTRN CODE  (_?OSIntEnter)
        EXTRN CODE  (_?OSIntExit)
        EXTRN CODE  (_?OSTimeTick)
            
;对外声明4个不可重入函数
        PUBLIC OSStartHighRdy
        PUBLIC OSCtxSw
        PUBLIC OSIntCtxSw
        PUBLIC OSTickISR
        
        ;PUBLIC SerialISR        

;定义压栈出栈宏
;-------------------------------------------------------------------------
PUSHALL	MACRO
		IRP	REG,	<PSW, ACC, B, DPL, DPH, 0, 1, 2, 3, 4, 5, 6, 7>
		PUSH	REG
		ENDM
	ENDM

POPALL	MACRO
		IRP	REG,	<7, 6, 5, 4, 3, 2, 1, 0, DPH, DPL, B, ACC, PSW>
		POP	REG
		ENDM
	ENDM  

;子程序
;-------------------------------------------------------------------------
        RSEG ?PR?OSStartHighRdy?OS_CPU_A
OSStartHighRdy:
;上电后51自动关中断,此处不必用CLR EA指令,因为到此处还未开中断,本程序退出后,开中断。
        LCALL _?OSTaskSwHook
OSCtxSw_in:
        ;OSTCBCur ===> DPTR  获得当前TCB指针,详见C51.PDF第178页
        MOV  DPH,(OSTCBCur+1)
        MOV  DPL,(OSTCBCur+2)

        MOVX A,@DPTR     ;.OSTCBStkPtr是xadta指针
        MOV  B,A
        INC  DPTR
        MOVX A,@DPTR
        MOV  DPL,A
        MOV  DPH,B       ;此时PDTR指向用户堆栈

        ;*UserStkPtr ===> R5  用户堆栈起始地址内容(即用户堆栈长度放在此处)  详见文档说明  指针用法详见C51.PDF第178页    

        MOVX A,@DPTR     ;用户堆栈中是unsigned char类型数据
        MOV  R5,A        ;R5=用户堆栈长度
    
        ;恢复现场堆栈内容
        MOV  R0,#STACK-1

L00:    INC  DPTR
        INC  R0
        MOVX A,@DPTR
        MOV  @R0,A
        DJNZ R5,L00
    
        ;恢复堆栈指针SP
        MOV  SP,R0
        ;恢复仿真堆栈指针?C_XBP   	
		INC  DPTR
		MOVX A,@DPTR
		MOV  ?C_XBP,A
		INC  DPTR
		MOVX A,@DPTR
		MOV  ?C_XBP+1,A

        ;OSRunning=TRUE
		MOV  A,#1
		MOV  OSRunning,A
	

        POPALL
        SETB EA    ;开中断
        RETI
;-------------------------------------------------------------------------
        RSEG ?PR?OSCtxSw?OS_CPU_A
OSCtxSw:    
        PUSHALL
    
OSIntCtxSw_in:
        ;OSTCBCur ===> DPTR  获得当前TCB指针,详见C51.PDF第178页
        MOV  DPH,OSTCBCur+1
        MOV  DPL,(OSTCBCur+2)
;OSTCBCur->OSTCBStkPtr ===> DPTR  获得用户堆栈指针
        MOVX A,@DPTR     ;.OSTCBStkPtr是void指针
        MOV  B,A
        INC  DPTR
        MOVX A,@DPTR
        MOV  DPL,A
        MOV  DPH,B
;获得堆栈长
		MOV  A,SP
        CLR  C
        SUBB A,#STACK-1
        MOV  R5,A     
;保存堆栈长度
        MOVX @DPTR,A
;获得堆栈起址    
        MOV  R0,#STACK-1  
L12:
        INC  DPTR
        INC  R0
        MOV  A,@R0
        MOVX @DPTR,A
        DJNZ R5,L12

;保存C_XBP 到堆栈中
        INC  DPTR
        MOV  A,?C_XBP
        MOVX @DPTR,A
        MOV  A,?C_XBP+1
		INC  DPTR
        MOVX @DPTR,A

        ;调用用户程序
        LCALL _?OSTaskSwHook
        
        ;OSTCBCur = OSTCBHighRdy
        MOV   A,OSTCBHighRdy
		MOV   OSTCBCur,A
        MOV   A,OSTCBHighRdy+1
		MOV   OSTCBCur+1,A
        MOV   A,OSTCBHighRdy+2
		MOV   OSTCBCur+2,A

        ;OSPrioCur = OSPrioHighRdy  使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。
        MOV   A,OSPrioHighRdy
	MOV   OSPrioCur,A
        
        LJMP OSCtxSw_in
;-------------------------------------------------------------------------
        RSEG ?PR?OSIntCtxSw?OS_CPU_A
        
OSIntCtxSw:

        ;调整SP指针去掉在调用OSIntExit(),OSIntCtxSw()过程中压入堆栈的多余内容
        ;SP=SP-4

        MOV  A,SP
        CLR  C
        SUBB A,#4
        MOV  SP,A
        
        LJMP OSIntCtxSw_in
;-------------------------------------------------------------------------
        CSEG AT 000BH    ;OSTickISR
        LJMP OSTickISR   ;使用定时器0
        RSEG ?PR?OSTickISR?OS_CPU_A

OSTickISR:
        
        USING 0
        PUSHALL
        
        MOV  A,#063H
        MOV  TH0,A
        MOV  A,#0C0H
        MOV  TL0,A
	    CLR  TF0
        LCALL _?OSIntEnter
        LCALL _?OSTimeTick

 		LCALL _?OSIntExit
        POPALL
        RETI
;-------------------------------------------------------------------------
	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -