松翰单片机之汇编编程

汇编工程排版说明

1、汇编中的宏定义,大写且前缀加MAC,如下:

MAC_XXX_XX     EQU        1

2、定义变量,前缀加VAR;局部变量小写,全局变量首字母大写

VAR_XXX     DS      1

3、定义位变量(可作为标志位)

 workflag            DS          2
 BF_XXX         EQU         (workflag+0).0
 ...
 BF_XXX         EQU         (workflag+0).7
 BF_XXX         EQU         (workflag+1).0

4、定义引脚

PIN_Led_Red          EQU          P0.0 

5、定义跳转位置

                    JMP       JMP_XXX      ;跳转
JMP_XXX:     
                    BTS0      XXX   

6、定义函数

 ;---------------------------------------------------------------------------------------
; 函数功能:
;     XXX
; 入口参数:
;     1. XXX 2.XXX ……
; 出口参数:
;     1. XXX 2.XXX ……
; 占用资源:
;     1. XXX 2.XXX ……
; 堆栈深度:
;     SP_DEPTH = 1
;---------------------------------------------------------------------------------------  
func_XXX:
                   XXX       XXX
                   ……
                   RET

程序状态寄存器 PFLAG 中常用标志 C、DC、Z

  • C:进位标志。
    1 = 加法运算后有进位、减法运算没有借位发生或移位后移出逻辑“1”或比较运算的结果 ≥ 0;
    0 = 加法运算后没有进位、减法运算有借位发生或移位后移出逻辑“0”或比较运算的结果 < 0。
  • DC:辅助进位标志。
    1 = 加法运算时低四位有进位,或减法运算后没有向高四位借位;
    0 = 加法运算时低四位没有进位,或减法运算后有向高四位借位。
  • Z:零标志。
    1 = 算术/逻辑/分支运算的结果为零;
    0 = 算术/逻辑/分支运算的结果非零。

常用的判断指令 BTS0、BTS1

BTS0 M.b如果 M.b = 0,则跳过下一条指令
BTS1 M.b如果 M.b = 1,则跳过下一条指令

用 XOR(异或)判断两变量是否相同

异或运算:相同为0,不同为1;
两变量相同,异或运算为0;两变量不同,异或运算为1;
进行异或运算后(也是逻辑运算),零标志(Z)状态会改变:

  • Z:零标志。
    1 = 逻辑运算的结果为零;
    0 = 逻辑运算的结果非零。
      B0MOV           A,var1
      XOR             A,#AA            ; "#AA"可以是宏定义或变量 (异或:两变量值相同为0(FZ==1),两变量值不同为1(FZ==0))
      B0BTS0          FZ
      JMP             JMP_XXX           
      ...            
;------------------------------------------------------------------------------------------
      B0MOV           A,var2
      XOR             A,#BB        ; 
      B0BTS1          FZ
      JMP             JMP_XXX               
      ...

用SUB(减法)判断两变量大小

SUB A,MA ← A – M,如果产生借位则 C=0,否则 C=1。
SUB M,AM ← A – M,如果产生借位则 C=0,否则 C=1。
;subtract word
SUBW	            MACRO	    m_minuend,m_subtrahend   //m_minuend=m_minuend-m_subtrahend
                    MOV             A,m_minuend
                    SUB             A,m_subtrahend
                    MOV             m_minuend,A             // save low byte
                    MOV             A,m_minuend+1
                    SBC             A,m_subtrahend+1
                    MOV             m_minuend+1,A           // save high byte
	               ENDM
 ;------------------------------------------------------------------------------------------
  AAA                 DS              2                  ; 临时双字节寄存器AAA
  BBB                 DS              2                  ; 临时双字节寄存器BBB
  ;------------------------------------------------------------------------------------------
  ;双字节变量的比较
       B0MOV           A,var1 + 0                ; var1 + 0:表示字节1
       B0MOV           AAA + 0,A
       B0MOV           A,var1 + 1                ; var1 + 1:表示字节2
       B0MOV           AAA + 1,A
       MOV             A,#CON1$L        ; #CON1$L 低字节
       B0MOV           BBB+0,A
       MOV             A,#CON1$M        ; #CON1$M 中字节
       B0MOV           BBB + 1,A
       SUBW            AAA,BBB          ; var1 -CON1(AAA >= BBB,FC为1)
       B0BTS1          FC               ; 也可以用 B0BTS0
       JMP             JMP_XXX          ; var1 < CON1
       ...                              ; var1 > CON1
  ;------------------------------------------------------------------------------------------
  ;单字节变量的比较
       B0MOV           A,var1           ; 
       B0MOV           AAA ,A
       MOV             A,#CON1          ; 
       B0MOV           BBB,A
       SUBW            AAA,BBB          ; var1 -CON1(AAA >= BBB,FC为1)
       B0BTS1          FC               ; 也可以用 B0BTS0
       JMP             JMP_XXX          ; var1 < CON1
       ...                              ; var1 > CON1

用跳转表实现如C语言switch功能

B0MOV  A, BUF0  ; “BUF0”从 04。
@JMP_A  5       ; 列表个数为 5。
JMP  A0POINT    ; ACC = 0,跳至 A0POINT。
JMP  A1POINT    ; ACC = 1,跳至 A1POINT。
JMP  A2POINT    ; ACC = 2,跳至 A2POINT。
JMP  A3POINT    ; ACC = 3,跳至 A3POINT。
JMP  A4POINT    ; ACC = 4,跳至 A4POINT。

扫描按键输入

按键连接同一个端口

key0、key1、key2、key3 分别连接 P1端口的P1.0、P1.1、P1.2、P1.3;

;最后 keycode 返回的是序号,而不是 TBL_KEY 表中的值
KEYIN:
        MOV             A,P1                     ; (有按键按下,相应位为0)
        XOR             A,#0xFF                  ; 此处是为了避免不按键时与结束码相同,键码取反(即有按键按下,相应位为1)(XOR:相同为0,不同为1)
        AND             A,#0x0F                  ; 屏蔽非按键IO口
KEYIN1:
        B0MOV           R1,A                     ; A 保存了按键值,如果只有P1.0按下,则A值为0x01
        MOV             A,#0xFF
        B0MOV           R0,A                     ; R1 为按键状态,R0 为0xFF
KEYIN2:
        B0MOV           Y,#TBL_KEY$M
        B0MOV           Z,#TBL_KEY$L
        INCMS           R0                       ; 第一遍R0 == 0 ;第二遍 R0 == 1...
        NOP
        B0MOV           A,R0                     ; A 即 R0 的值;
        B0ADD           Z,A                      ; 第一遍 Z == #TBL_KEY$L;第二遍 Z 为 #TBL_KEY$L 的下一个地址;...(ADD,如果产生进位则 C = 1,否则 C = 0)
        B0BTS1          FC                       ; 
        JMP             FIND_KEYTBL
        INCMS           Y
        NOP
FIND_KEYTBL:
        MOVC                                      ; 查表(执行完 MOVC 指令后,所查找数据低字节内容被存入 ACC 中,而数据高字节内容被存入 R 寄存器。)
        CMPRS           A,R1                      ; A 存储的是 TBL_KEY 表中的值,R1 即按键状态                       
        JMP             KEYIN3                    ; A != R1 ,
        B0MOV           A,R0                      ; A == R1 , 将 R0 序号(0123...)赋值给keycode,而不是将TBL_KEY 表中的值     
        B0MOV           keycode,A
        RET
KEYIN3:
        CMPRS           A,#0xFF                   ; 比较,如果相等则跳过下一条指令(0xFF是TBL_KEY表中结尾的值,所以前面值都不等,最后一个就一定等)
        JMP             KEYIN2                    ; 没有查完 TBL_KEY 表,循环查找
        B0MOV           keycode,A                 ; 

        RET
       
TBL_KEY:                                           ; 如key0(P1.0)按下,按键值为0x01,
                    DW              0x0000         ; --------------->  无按键按下
                    DW              0x0001         ; --------------->  key0 按下
                    DW              0x0002         ; --------------->  key1 按下
                    DW              0x0004         ; --------------->  key2 按下
                    DW              0x0008         ; --------------->  key3 按下
                    DW              0x00FF         ; --------------->  无定义的按键值

按键连接不同端口

key0、key1、key2、key3 分别连接 P1端口的P5.4、P5.5、P1.2、P1.3;

KEYIN:
        MOV             A,P1
        XOR             A,#0xFF                  ; 此处是为了避免不按键时与结束码相同,键码取反
        AND             A,#(BIT2|BIT3)           ; 屏蔽非按键IO口(读取P1^2,P1^3)
        B0MOV           R1,A

        MOV             A,P5
        XOR             A,#0xFF                  ; 此处是为了避免不按键时与结束码相同,键码取反
        AND             A,#(BIT4|BIT5)           ; 屏蔽非按键IO口(读取P5^4,P5^5)
        OR              R1,A                     ; 综合P1 & P5两个IO口
KEYIN1:
        MOV             A,#0xFF
        B0MOV           R0,A
KEYIN2:
        B0MOV           Y,#TBL_KEY$M
        B0MOV           Z,#TBL_KEY$L
        INCMS           R0
        NOP
        B0MOV           A,R0
        B0ADD           Z,A
        B0BTS1          FC
        JMP             FIND_KEYTBL
        INCMS           Y
        NOP
FIND_KEYTBL:
        MOVC                                      ; 
        CMPRS           A,R1
        JMP             KEYIN3
        B0MOV           A,R0
        B0MOV           keycode,A
        RET
KEYIN3:
        CMPRS           A,#0xFF
        JMP             KEYIN2
        B0MOV           keycode,A                 ; 

        RET
     
TBL_KEY:                                           ; 如key0(P5.4)按下,按键值为0x10,
                    DW              0x0000         ; --------------->  无按键按下
                    DW              0x0010         ; --------------->  key0 按下
                    DW              0x0020         ; --------------->  key1 按下
                    DW              0x0004         ; --------------->  key2 按下
                    DW              0x0008         ; --------------->  key3 按下
                    DW              0x0030         ; --------------->  key0&key1 同时按下
                    DW              0x00FF         ; --------------->  无定义的按键值
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值