ercircle 发表于 2025-4-17 18:35:48

第十集

分支程序



汇编冒泡



四位二进制数转ASCII码

ASCII码转四位二进制数









ercircle 发表于 2025-4-17 23:59:26

;*******************程序说明***********************
/*
使用定时器1s切一次P2.0状态
100MS,执行一次C函数,通过直接位寻址间接切一次P2.1状态
500MS,切一次P2高4位状态
*/
;**************************************************

$include (Ai8051U.inc)


;*******************常量定义***********************
    CONSTVALUE1       EQU   1
    CONSTVALUE2       EQU   2
               
;*******************变量定义***********************
;测试定时器,1s切一次状态
LED1 BIT P2.0
;测试外部C函数调用,100MS
LED2 BIT P2.1


;20H~7FH 可位寻址
;测试位寻址
FLAG1 BIT 20H.0
FLAG2 BIT 7FH.0
FLAG3 BIT 7FH.7


;1ms定时中断标识
F1MS BIT 20H.1

MSCOUNT DATA 30H
MS100COUNT DATA 32H
;*******************外部变量及函数声明***********************

;EXTRN   CODE(RL_LAMP_APP);
EXTRN   CODE(DELAY500MS);
EXTRN   CODE(MyBank3Fun);
EXTRN   CODE(MyBank2Fun);
;C函数调用测试       
EXTRN   CODE(toggleBit);

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

?ED?MAIN    SEGMENT EDATA               ;定义数据段
    RSEG    ?ED?MAIN
EDATAVAR1:
    DS      2

       
       
;*******************中断定义***********************

CSEG    AT0000H
LJMP    RESET                     ;复位跳转       
ORG 000BH               
LJMP TIMER0_ISR
ORG 1000H
       
;********************主程序*************************
?PR?MAIN    SEGMENT CODE                ;定义代码段
RSEG    ?PR?MAIN

MAIN:
        NOP
RESET:
    MOV   R0,#7FH
    CLR   A
CLEARRAM:
    MOV   @R0,A
    DJNZ    R0,CLEARRAM

INIT_SP:
        ;MOV SP,#80H
        MOV   DR60,#0100H

INIT_EAXFR:       
        MOV   WTST,#00H
    MOV   CKCON,#00H
    SETB    EAXFR
       
        LCALL         TIMER0_INIT
        CLR                F1MS
        SETB    EA
INIT_APP:       
        MOV P2M0,#00H
        MOV P2M1,#00H
        MOV WR0,#0
       
        MOV EDATAVAR1,WR0 ; 初始化MSCOUNT为0
        MOV MSCOUNT,WR0 ; 初始化MSCOUNT为0
        MOV MS100COUNT,A;
        SETB FLAG1
        SETB FLAG2
        SETB FLAG3
        LCALL MyBank3Fun
        LCALL MyBank2Fun
RUN_APP:       
        LOOP:
                JBC F1MS,LOOP_1MS_EVENT
                LCALL CHECK_LESS_500MS               
                ;LCALL RL_LAMP_APP       
                LJMP LOOP;
                LOOP_1MS_EVENT:
                LCALL FUN_100MS;
                LCALL FUN_1MS;
                LJMP LOOP;


TIMER0_INIT:                                ;1毫秒@40.000MHz
        ORL                AUXR,#80H                ;定时器时钟1T模式
        ANL                TMOD,#0F0H                ;设置定时器模式
        MOV                TL0,#0C0H                ;设置定时初始值
        MOV                TH0,#063H                ;设置定时初始值
        CLR                TF0                                ;清除TF0标志
        SETB        TR0                                ;定时器0开始计时
        SETB        ET0                                ;定时器0中断开
        RET

TIMER0_ISR:
        SETB F1MS
        RETI

FUN_100MS:
    INC MS100COUNT      ; 递增计数器(先低字节)
    MOV A, MS100COUNT
        CJNE A, #100,FUN_100MS_RET
    ;达到100ms
        ;CPL LED2
        LCALL toggleBit
        JC FUN_100MS_C1
        CLRLED2
        SJMP FUN_100MS_CLR
FUN_100MS_C1:
        SETB LED2
        SJMP FUN_100MS_CLR       
FUN_100MS_CLR:       
    CLR A      ; 清零
        MOV MS100COUNT,A
FUN_100MS_RET:
        RET;
       
       
       
               
CHECK_LESS_500MS:
    ; 检查MSCOUNT是否小于500(0x01F4)
    MOV A, MSCOUNT+1 ; 加载高字节
    CJNE A, #01H, CHECK_LESS_500MS_1
CHECK_LESS_500MS_1:
        JC LESS_THAN_500;前数小于后数
        LJMP GREATER_EQUAL_500;前数大于等于后数
       
    MOV A, MSCOUNT   ; 高字节等于0x01,检查低字节
        CJNE A, #0F4H, CHECK_LESS_500MS_2
CHECK_LESS_500MS_2:
        JC LESS_THAN_500;前数小于后数
        LJMP GREATER_EQUAL_500;前数大于等于后数

        LESS_THAN_500:
                ; 设置P2的高四位为0
                ANL P2, #0x0F    ; 将P2的高四位清零,低四位保持不变
                SJMP CHECK_LESS_500MS_END   ; 跳转到更新P2的代码

        GREATER_EQUAL_500:
                ; 设置P2的高四位为1
                ORL P2, #0xF0    ; 将P2的高四位置1,低四位保持不变
        CHECK_LESS_500MS_END:
                RET
       
       
FUN_1MS:
        LCALL FUN_100MS;
       
    INC MSCOUNT      ; 递增计数器(先低字节)
    MOV A, MSCOUNT
        CJNE A, #00H,FUN_1MS_JUGE
    INC MSCOUNT+1    ; 递增高字节
FUN_1MS_JUGE:
    ; 检查是否达到1000(0x03E8)
    MOV A, MSCOUNT+1 ; 加载高字节
    CJNE A, #03H, FUN_1MS_RET ; 比较高字节是否为0x03
    MOV A, MSCOUNT   ; 高字节匹配,检查低字节
    CJNE A, #0E8H, FUN_1MS_RET
       
       ; 触发条件:切换灯状态并清零
        CPL LED1
    CLR A      ; 清零低字节
        MOV MSCOUNT,A
        MOV MSCOUNT+1,A
FUN_1MS_RET:
        RET;
END

ercircle 发表于 2025-4-18 15:42:54

735

ercircle 发表于 2025-4-18 15:44:15

汇编编程中压栈和出栈的作用是什么:







ercircle 发表于 2025-4-18 15:47:20

汇编与C混合编程说明及注意事项:

C51


C251


代码中C51 C251标准切换:

寄存器堆:


注意事项:
汇编函数可能会改变当前所选寄存器组中的所有寄存器内容,以及累加器(ACC)、寄存器 B、数据指针(DPTR)和程序状态字(PSW)寄存器的内容。
当从汇编语言中调用 C 函数时,需假定这些寄存器会被所调用的 C 函数破坏。


ercircle 发表于 2025-4-18 16:26:54

汇编字符串定义



页: 1 [2]
查看完整版本: 陈老师课程学习记录贴