📄 key.asm
字号:
$MOD52 ; This includes 8052 definitions for the metalink assembler
;
; Variables
;
NUM1L DATA 020H ; low byte of first operand
NUM1H DATA 021H ; high byte of first operand
OPERATOR DATA 022H ; operator
NUM2L DATA 023H ; low byte of second operand
NUM2H DATA 024H ; high byte of second operand
EWB DATA 0F8H ;EWB TRACE SFR
; Program Start
reset:
; move stack pointer past register banks and variables
MOV SP, #28H
MOV P0, #00H
MOV P2, #00H
JMP getnum1
; Initialize values in memory
initVar:
MOV NUM1L, #00H
MOV NUM1H, #00H
MOV OPERATOR, #0FH
MOV NUM2L, #00H
MOV NUM2H, #00H
MOV R5, #00H
MOV R6, #00H
RET
; Getting first operand
getnum1:
MOV A, R1
MOV A, R5
MOV NUM1L, A
MOV A, R6
MOV NUM1H, A
CALL keyscan
call displaynum
JMP getnum1 ; continue getting first num
; Returns key pressed in (row,col) format in R7
; For example: R7 = #028H if 1 was pressed on the keypad
; Keypad
; Row # -----------------
; 8 | 7 8 9 + |
; 4 | 4 5 6 - |
; 2 | 1 2 3 * |
; 1 | C 0 = / |
; -----------------
; Col # 8 4 2 1
keyscan:
PUSH ACC
MOV A, R0
PUSH ACC
MOV A, R1
PUSH ACC
MOV A, R3
PUSH ACC
MOV P1, #00FH
waitkeyuploop:
MOV A, P1
ANL A, #00FH
XRL A, #00FH
JNZ waitkeyuploop
MOV P1, #00FH
anykeyloop:
MOV A, P1
ANL A, #00FH
XRL A, #00FH
JZ anykeyloop
MOV R0, A
XRL A, #00FH
MOV R3, A
call lineclear
MOV P1, #0EFH
MOV R1, #010H
NOP
MOV A, P1
ANL A, #00FH
XRL A, R3
MOV R2,#000H
JZ scanmatch
call lineclear
MOV P1, #0DFH
MOV R1, #020H
NOP
MOV A, P1
ANL A, #00FH
XRL A, R3
MOV R2, #001H
JZ scanmatch
call lineclear
MOV P1, #0BFH
MOV R1, #040H
NOP
MOV A, P1
ANL A, #00FH
XRL A, R3
MOV R2, #002H
JZ scanmatch
call lineclear
MOV P1, #07FH
MOV R1, #080H
NOP
MOV A, P1
ANL A, #00FH
XRL A, R3
MOV R2, #003H
JZ scanmatch
MOV P1, #00FH
JMP keyscan
scanmatch:
MOV A, R1
ORL A, R0 ; combine into scancode
MOV R7, A ; R7 contains value in (row,col) format
keyscanend:
POP ACC
MOV R3, A
POP ACC
MOV R1, A
POP ACC
MOV R0, A
POP ACC
RET
; Input:
; R7 contains last key pressed
; R2 contains last key pressed in converted number
; R5 and R6 contains current number in hex
; Output:
; R5 and R6 contains new number in hex
displaynum:
MOV A, R7
MOV R4, A
MOV A, R2
MOV B, #04H
MUL AB
MOV R2, A
MOV A, R4
ANL A, #00FH
MOV R4, #000H
getnumloop:
INC R4
RR A
ANL A, #00FH
JNZ getnumloop
DEC R4
MOV A, R2
ADD A, R4
MOV R1, A
checknum2:
CJNE A, #02H,checknum5
MOV A, #00H
JMP numfound
checknum5:
CJNE A, #05H,checknum6
MOV A, #03H
JMP numfound
checknum6:
CJNE A, #06H,checknum7
MOV A, #02H
JMP numfound
checknum7:
CJNE A, #07H,checknum9
MOV A, #01H
JMP numfound
checknum9:
CJNE A, #09H,checknum10
MOV A, #06H
JMP numfound
checknum10:
CJNE A, #0AH,checknum11
MOV A, #05H
JMP numfound
checknum11:
CJNE A, #0BH,checknum13
MOV A, #04H
JMP numfound
checknum13:
CJNE A, #0DH,checknum14
MOV A, #09H
JMP numfound
checknum14:
CJNE A, #0EH,checknum15
MOV A, #08H
JMP numfound
checknum15:
CJNE A, #0FH, checkclear
MOV A, #07H
JMP numfound
checkclear:
CJNE A, #03H, checkplus
JMP cleardisplay
checkplus:
CJNE A, #0CH, checkminus
JMP operatorfound
checkminus:
CJNE A, #08H, checkmultiply
JMP operatorfound
checkmultiply:
CJNE A, #04H, checkdivide
JMP operatorfound
checkdivide:
CJNE A, #00H, checkequalop
JMP operatorfound
checkequalop:
CJNE A, #01H, numnotfound
JMP equalfound
equalfound:
MOV R1, #02H
MOV R7, A
JMP displaynumend
operatorfound:
MOV R1, #00H
MOV R7, A
JMP displaynumend
numnotfound:
MOV R7, #0FFH
JMP displaynumend
numfound:
MOV R1, #01H
MOV R7, A
; Shift number to the left before displaying
call shiftnumleft
; display decimal numbers
MOV A, R5
MOV P2, A
MOV A, R6
MOV P0, A
call delay
displaynumend:
RET
; R7 contains the new value
; R5 and R6 contains low and high byte of number to be shifted
shiftnumleft:
PUSH ACC
shiftnumleftstart:
MOV A, R7
PUSH ACC
MOV A, R6
MOV R7, #004H
checkhighnumloop:
RLC A
JC noshift
DJNZ R7, checkhighnumloop
JMP doshift
noshift:
POP ACC
MOV R7, A
JMP shiftnumleftend
doshift:
POP ACC
SWAP A
MOV R7, #004H
shiftbitleft:
RLC A
PUSH ACC
; Take carry bit and rotate it into R5
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
POP ACC
DJNZ R7, shiftbitleft
shiftnumleftend:
POP ACC
RET
cleardisplay:
MOV R5, #00H
MOV A, R5
MOV P2, A
MOV R6, #00H
MOV A, R6
MOV P0, A
CALL delay
MOV R1, #03H
JMP displaynumend
; Wait for no key press
lineclear:
MOV P1, #0FFH
lineclearloop:
MOV A, P1
XRL A, #0FFH
JNZ lineclearloop
RET
delay:
JB EWB.0,delayend ; Jump if using EWB Trace Mode
PUSH ACC
MOV A, R5
PUSH ACC
MOV A, R6
PUSH ACC
MOV R5, #50 ; number of innerdelay's to call
CLR A
outerdelay:
MOV R6, A
CALL innerdelay
DJNZ R5, outerdelay
POP ACC
MOV R6, A
POP ACC
MOV R5, A
POP ACC
delayend:
RET
innerdelay:
NOP
NOP
NOP
NOP
NOP
DJNZ R6, innerdelay
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -