📄 计算器ok.asm
字号:
ORG 00H
SJMP START
ORG 30H
;用78H、79H、7AH三个单元作为数据缓存区,最多显示三位数据
START:MOV 78H,#0 ;初始化:78H放0的段码,其中0表示TAB表偏移量
MOV 79H,#10 ;放熄灭码,存在TAB表偏移量10处
MOV 7AH,#10
MOV R5, #0 ;R5是按键次数,初始置0
MOV 30H,#0 ;30H是功能键存放单元,置为0
MOV 40H,#0 ;40H单元初始置为0
MOV 41H,#0 ;41H单元初始置为0
LOOP:LCALL DIR ;在数码管显示78H,79H,7AH对应的内容(动态显示)
LCALL KEY ;给出按下的键的位置
INC R5 ;KEY返回表示有键按下,R5自加1
;判断按下的是哪个键
S1:CJNE A,#10,S2 ;不是"+"键,跳到S2
LJMP FUN ;是"+"键,跳到FUN
S2:CJNE A,#11,S3 ;不是"-"键,跳到S3
LJMP FUN ;是"-"键,跳到FUN
S3:CJNE A,#12,S4 ; 不是" "键,跳到S4
LJMP START ; 是" "键,跳到FUN
S4:CJNE A,#13,S5 ; 不是" "键,跳到S5
LJMP START ; 是" "键,跳到FUN
S5:CJNE A,#14,S6 ; 不是"="键,跳到S6
LJMP FUN ;是"="键,跳到FUN
S6:CJNE A,#15,N1 ; 不是"CL"键,跳到N1
LJMP START ; 是"CL"键,跳到START
;判断第几次按键(R5值为按键次数)
N1:CJNE R5,#1,N2
MOV R4,A
MOV 78H,A ;输入值送显示个位缓存
MOV 79H,#10
MOV 7AH,#10
LJMP LOOP
N2:CJNE R5,#2,N3
MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7AH,#10
MOV 79H, 78H ;个位到十位
MOV 78H,R7 ;新数为个位
LJMP LOOP
N3:CJNE R5,#3,START
MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7AH,79H ;十位到百位
MOV 79H,78H ;个位到十位
MOV 78H,R7 ; 新数为个位
LJMP LOOP
FUN:MOV 78H,#10
MOV 79H,#10
MOV 7AH,#10
MOV R0,30H ;与上次功能键交换
MOV 30H,A
MOV A,R0
CJNE A,#10,FUN1 ;判断功能键
LJMP ADDY ;"+"
FUN1:CJNE A,#11,FUN2
LJMP SUBT ;"-"
FUN2:CJNE A,#14,FUN3 ;首次按功能键,即A=#0
LJMP EQUA ;"="
FUN3:MOV 40H,R4 ;保存第一个数
MOV R5,#0 ;按键次数清零
LJMP BCD ;将R4内容转换为BCD码,并存入78H、79H、7AH单元
OF:LJMP START ;溢出处理
ADDY:MOV A,40H ;第一个数送累加器
ADD A,R4 ;第一个数加第二个数
JC OF ;溢出
MOV 40H,A ;存本次结果
MOV R5,#0 ;按键次数清零
LJMP BCD ;转换为数值并显示
SUBT:MOV A,40H
CLR C
SUBB A,R4
JC OF
MOV 40H,A
EQUA:MOV R5,#0
BCD:MOV B,#10
MOV A,40H ;结果送累加器
DIV AB ;结果除10
MOV 41H,A ;暂存"商"
MOV A,B ;取个位数
MOV 78H,A ;个位数送显示缓存
MOV A,41H
JZ RETURN ;结果是一位数,返回LOOP
MOV B,#10
MOV A,41H
DIV AB
MOV 41H,A
MOV A,B
MOV 79H,A ;十位送显示缓存
MOV A,41H
JZ RETURN ;结果是二位数,返回LOOP
MOV 7AH,A ;百位数送显示缓存
RETURN: LJMP LOOP
;动态显示子程序
DIR:MOV DPTR,#TAB ; 数码管译码表首址
MOV R0,#78H ;待显缓冲区个位地址
MOV R2,#3 ;3位显示
MOV R1,#0FFH ; 个位位选信号
LD1:MOV A,@R0
MOVC A,@A+DPTR ;查表
MOV P2,R1 ;共阴极管字位选择送到P2口
MOV P0,A ;字段码送P0口
LCALL DELAY1ms ;调延时1ms 子程序
INC R0 ;R0指向下一模块
DEC R1 ;指向下一数码管
DJNZ R2,GO ;判断是否发完3个数
SJMP LD2
GO: SJMP LD1 ;跳去再显示下一个数
LD2:RET ;发完3个数就返回
;检测一次按键的TAB表偏移量
KEY:LCALL KS ;调用检测按键子程序
JNZ K1 ;有键按下继续
LCALL DELAY12ms ;无键按调用延时去抖
ACALL DIR ;调用动态显示
AJMP KEY ;返回继续检测按键
K1: LCALL DELAY12ms ;有键按下延时去抖动
LCALL KS ;再调用检测按腱子程序
JNZ K2 ;确认有按键进行下一步
ACALL DIR ;调用动态显示
AJMP KEY ;无键按下返回继续检测
K2: MOV P3,#0FEH ;判断第一行是否有键按下
MOV A,#0
K3: JNB P3.7 , L1
INC A
JNB P3.6, L1
INC A
JNB P3.5, L1
INC A
JNB P3.4, L1
L3: INC A ;判断下一行是否有键按下
MOV R7,A
MOV A,P3
RL A
MOV P3,A
MOV A,R7
LJMP K3
L1: PUSH ACC ;将A中的值送入堆栈暂存
K4:LCALL DELAY12ms ;调用延时去抖程序
LCALL KS ;调用按键检测程序
JNZ K4 ;按键没有松开继续返回检测
POP ACC ;将堆栈值送入ACC
MOV DPTR,#KEYTAB ;使按键与TAB表共阴极数码管码值对应
MOVC A,@A+DPTR
RET
;判断有无键按下
KS:MOV P3,#0F0H ;所有行选通,给0
MOV A,P3 ;读P3口
XRL A,#0F0H ;判断高4位是否有键按下
RET
DELAY1ms:MOV R6,#2
LOOP1:MOV R7,#0FFH
DJNZ R7,$
DJNZ R6,LOOP1
RET
DELAY12ms:MOV R7,#24 ;延时去抖动子程序
LOOP2 :MOV R6,#0FFH
DJNZ R6,$
DJNZ R7,LOOP2
RET
TAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,00H ;共阴极译码表
KEYTAB:DB 1,2,3,4,5,6,7,8,9,0,10,11,12,13,15,14;键值表
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -