松翰单片机之汇编编程

tech2022-12-06  93

汇编工程排版说明

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 ; ---------------> 无定义的按键值
最新回复(0)