程序中是實現了一字節整數的加減乘除計算,支持連續按鍵的情況,其程序流程圖將要上傳至圖片,希望對愛好者有所幫助也希望能夠得到高手的指點。
本文引用地址:
http://m.cqxgywz.com/article/201611/321253.htmORG 00H
LJMP MAIN
ORG 0BH ;定時器1處理
LJMP PROC_COUNT
Keydata EQU 35H ;0->0 ..9-> , +->10, -->11 , =->14 C->15
flag bit 0
last bit 1
Cup bit 2
tempc bit 3
DisBuffer EQU 50H
STA EQU 49H
OP1 EQU 40H
OP EQU 43H
OP2 EQU 44H
Buff EQU 42H
Resut EQU 41H
MAIN:
CLR flag
CLR last
CLR Cup
CLR tempc
MOV STA,#0
MOV OP1,#0
MOV OP2,#0
MOV OP,#0
MOV Buff,#0
MOV Keydata,#0
MOV SP,#60H
MOV psw ,#0
MOV TMOD,#01H ; clock =12mhz 定時器0的方式1
MOV TH0,#0D8H
MOV TL0,#0F0H ;定時時間為10ms
SETB ET0
SETB EA
SETB TR0
MOV 50H,#3FH ;初始化緩沖區50h-52h
MOV 51H,#3FH
MOV 52H,#3FH
WORK:
CLR C
CALL KeyIN ;調用鍵盤掃描程序有鍵按下時C=1 Keydata返回 0~9 為0~9 "+-*/" 為10、11、12、13 "="為14 C鍵為15
mov tempc,c
anl c,/last
mov Cup,c
mov c,tempc
mov last,c
mov c,Cup
JNC WORK ;進位為0則轉移
;檢測狀態程序段
MOV A,STA ;將狀態值送A
RL A
MOV DPTR,#STTAB ;將分支程序的初值送DPTR
JMP @A+DPTR ;選擇程序分支
STTAB:
AJMP STA0 ;狀態0子程序
AJMP STA1 ;狀態1子程序
AJMP STA2 ;狀態2子程序
AJMP STA3 ;狀態3子程序
AJMP STA4 ;狀態4子程序
AJMP STA5 ;狀態5子程序
STA0:
MOV A,Keydata ;將鍵值送A
CLR C ;清除進位位
SUBB A,#10 ;判斷是否位數字鍵
JNC STA0END ;否時轉移到STA0END
CALL DATA_IN ;調用DATA_IN子程序講數值送入Buff
MOV STA,#1
STA0END:
JMP Display
STA1:
MOV A,Keydata ;將鍵盤所對應的數值送A
CLR C ;清除進位位
SUBB A,#10 ;判斷是否位數字鍵
JNC STA1NEXT ;否時轉移到continue
CALL DATA_IN ;調用DATA_IN子程序講數值送入Buff
JNC STA1END ;無溢出時跳至狀態1結束節點
MOV STA,#5 ;有溢出時將狀態標志置為5
STA1END:
JMP Display
;判斷是否為運算符 是時將Buff中的值送給OP1 將運算符送OP中保存 將狀態置為2態
STA1NEXT:
MOV A,Keydata
CLR C
SUBB A,#14
JNC STA1NEXT1
MOV OP1,Buff
MOV OP,Keydata
MOV STA,#2
JMP STA1END
;判斷是否是=
STA1NEXT1:
MOV A,Keydata
CJNE A,#14,STA1NEXT2 ;是否為等號 不是時轉移
MOV OP1,Buff ;是"="時將Buff中的數值送OP1
MOV Buff,#0 ;將Buff清空將狀態變為4態
MOV STA,#4
JMP STA1END ;跳到STA1END
;不是=時只能為C鍵
STA1NEXT2:
MOV Buff,#0 ;將Buff清空 將狀態置為0態
MOV STA,#0
JMP STA1END ;跳至狀態1結束節點
;STA2處理程序
STA2:
MOV A,Keydata ;將鍵盤所對應的數值送A
CLR C ;清除進位位
SUBB A,#10 ;判斷是否位數字鍵
JNC STA2NEXT ;否時轉移到STA2NEXT
MOV Buff,#0
CALL DATA_IN ;調用DATA_IN子程序講數值送入Buff
MOV STA,#3
STA2END:
JMP Display
;是否為運算符 是時將運算符送OP否時轉移至STA2NEXT1
STA2NEXT:
MOV A,Keydata
CLR C
SUBB A,#14
JNC STA2NEXT1
MOV A,Keydata
MOV OP,A
JMP STA2END
STA2NEXT1:
MOV A,Keydata
CJNE A,#14,STA2NEXT2 ;是否為等號 不是時轉移STA2NEXT2 是"="時 將狀態設為4態
MOV STA,#4
JMP STA2END
STA2NEXT2: ;是C鍵時將Buff清空將狀態變為0態
MOV Buff,#0
MOV STA,#0
JMP STA2END
STA3:
MOV A,Keydata ;將鍵盤所對應的數值送A
CLR C ;清除進位位
SUBB A,#10 ;判斷是否位數字鍵
JNC STA3NEXT ;否時轉移到STA3NEXT
CALL DATA_IN ;調用DATA_IN子程序講數值送入Buff
JNC STA3END ;無溢出時跳至狀態3結束節點
MOV STA,#5 ;有溢出時將狀態標志置為5
STA3END:
JMP Display
;判斷是否為運算符 是運算符時先進行運算 且判斷是否有溢出
STA3NEXT:
MOV A,Keydata
CLR C
SUBB A,#14
JNC STA3NEXT1 ;不是運算符時進行下次判斷是否為=
MOV OP2,Buff ;是運算符時將緩沖區的數值給OP2 再將緩沖區清除
MOV Buff,#0
CALL Comput ;調用Comput 將結果Resut送入OP1
JNC STA3NEXT2 ;計算完成后判斷數值是否有溢出 沒有時跳至STA3NEXT2
MOV STA,#5 ;結果有溢出時進入狀態5
JMP STA3END
STA3NEXT2:
MOV OP1,Resut
MOV OP,Keydata ;連續按運算符的情況
MOV STA,#2
JMP STA3END
;判斷是否為"="的情況
STA3NEXT1:
MOV A,Keydata
CJNE A,#14,STA3NEXT3
MOV OP2,Buff ;是運算符時將緩沖區的數值給OP2 再將緩沖區清除
MOV Buff,#0
CALL Comput
JNC STA3NEXT4 ;計算完成后判斷數值是否有溢出 沒有時跳至STA3NEXT4
MOV STA,#5 ;結果有溢出時進入狀態5
JMP STA3END
STA3NEXT4: ;將結果送入OP1進入狀態4
MOV A,Resut
MOV OP1,A
MOV STA,#4
JMP STA3END
STA3NEXT3: ;按C鍵的情況將緩沖區清除 進入狀態0
MOV Buff,#0
MOV STA,#0
JMP STA3END
STA4:
MOV A,Keydata ;將鍵盤所對應的數值送A
CLR C ;清除進位位
SUBB A,#10 ;判斷是否位數字鍵
JNC STA4NEXT ;不是數字鍵時處理
MOV Buff,#0 ;清除緩沖區
CALL DATA_IN ;調用DATA_IN子程序
MOV STA,#1 ;進入狀態1
STA4END:
JMP Display
;判斷是否為運算符
STA4NEXT:
MOV A,Keydata
CLR C
SUBB A,#14
JNC STA4NEXT1
MOV OP,Keydata ;將鍵盤所對應的數值送OP
MOV STA,#2
JMP STA4END
;為C鍵的處理
STA4NEXT1:
MOV A,Keydata
CJNE A,#15,STA4END
MOV Buff,#0
MOV STA,#0
JMP STA4END
;在狀態5判斷是否為C鍵 若是則清除緩沖區
STA5:
MOV A,Keydata
CJNE A,#15,STA5END
MOV Buff,#0
MOV STA,#0
STA5END:
JMP Display
;Display子程序段 當為狀態0、1、3時轉向Buff_display 當為狀態2、4時轉向OP1_display當為狀態5和其他狀態時轉向E_display
Display:
MOV A,STA
JZ Buff_display
CJNE A,#1,DNEXT
JMP Buff_display
DNEXT:
CJNE A,#2,DNEXT1
JMP OP1_display
DNEXT1:
CJNE A,#3,DNEXT2
JMP Buff_display
DNEXT2:
CJNE A,#4,DEND
JMP OP1_display
DEND:
JMP E_display
;因 OP1_display與 Buff_display 的處理一致所以使用公用的程序段BandOP1dis
Buff_display:
MOV R3,Buff
JMP BandOP1dis
OP1_display:
MOV R3,OP1
JMP BandOP1dis
;檢查是一位數時進入G_display 是兩位數時進入SH_display 三位數時進行 B_display
BandOP1dis:
MOV A,R3
MOV B,#10 ;將R3中的內容除10 若商為0則為一位數
DIV AB
JZ G_display
MOV A,R3 ;將R3中的內容除100 若商為0則為兩位數否則為三位數
MOV B,#100
DIV AB
JZ SH_display
JMP B_display
G_display:
MOV DPTR,#SEG1_TABLE ;B中的數就是個位上的數 將個位數所對應的7段碼送50h 且將51h、52H 存入0FFH將數碼管熄滅
MOV R2,B
MOV A,R2
MOVC A,@A+DPTR
MOV 52H,A
MOV 51H,#0
MOV 50H,#0
JMP BandOend
SH_display: ;將R3中的內容除10 商為十位上的數 余數為個位上的數
MOV DPTR,#SEG1_TABLE
MOV A,R3
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV 51H,A ;將十位上的數所對應的7段碼送51h
MOV R2,B
MOV A,R2
MOV DPTR,#SEG1_TABLE
MOVC A,@A+DPTR
MOV 52H,A ;將個位上的數所對應的7段碼送50h
MOV 50H,#0
JMP BandOend
B_display: ;經過判斷以后 A中的數為百位上的數將所對應的7段碼送52h
MOV DPTR,#SEG1_TABLE
MOVC A,@A+DPTR
MOV 50H,A
MOV R2,B ;B中為后兩位數
MOV A,R2
MOV B,#10
DIV AB ;運算后A中為十位上的數 B中為個位上的數
MOV DPTR,#SEG1_TABLE
MOVC A,@A+DPTR
MOV 51H,A
MOV R2,B
MOV A,R2
MOV DPTR,#SEG1_TABLE
MOVC A,@A+DPTR
MOV 52H,A
BandOend:
JMP DisOver ;跳入顯示結束程序口 DisOver
E_display:
MOV DPTR,#SEG1_TABLE
MOV A,#10
MOVC A,@A+DPTR
MOV 52H,A
MOV 51H,#00H
MOV 50H,#00H
JMP DisOver ;跳入顯示結束程序口 DisOver
DisOver:
JMP WORK
;DATA_IN 子程序段實現 Buff=Buff*10+Keydata并判斷是否有溢出 送C中
DATA_IN :
CLR C
MOV A,Buff
MOV B,#10
MUL AB
MOV C,PSW.2
JNC DATA_IN1
JMP DOVER
DATA_IN1:
ADDC A,Keydata
MOV C,PSW.2
DOVER:
MOV Buff,A
RET
;計算子程序段
Comput:
MOV A,OP ;因運算符的末位數為0、1、2、3
MOV B,#10 ;將OP除以10所得的余數為所對應的末尾數 再將其賦予A進行分支程序選擇
DIV AB
MOV R5,B
MOV A,R5
RL A
MOV DPTR,#ComTAB
JMP @A+DPTR
ComTAB:
AJMP ADDER ;為0時為加法運算
AJMP SUBBER ;為1時為減法運算
AJMP MULER ;為2時為乘法運算
AJMP DIVER ;為3時為除法運算
ADDER: ;加法運算
MOV A,OP1
ADDC A,OP2
JMP ComEND
SUBBER: ;減法運算
MOV A,OP1
SUBB A,OP2
JMP ComEND
MULER: ;乘法運算
MOV A,OP1
MOV B,OP2
MUL AB
JMP ComEND
DIVER: ;除法運算
MOV A,OP1
MOV B,OP2
DIV AB
JMP ComEND
ComEND: ;將結果送Resut
MOV Resut,A
MOV C,PSW.2 ;將溢出標志送C
RET
;中斷程序處理中斷任務
PROC_COUNT: ;將緩沖區的內容送數碼管顯示
PUSH ACC ; r0 顯示位 計數 0~7
PUSH PSW
MOV PSW ,#08H ;select r group 1
CLR TR0
CLR EA
MOV TH0,#0D8H ; 2.1ms
MOV TL0,#0F0H
CLR TF0 ;清除中斷溢出位
MOV A,R0 ;顯示的位數超過4時R0賦值0
SUBB A,#3 ;R0的值與3相減有借位時轉移到pro1
JC pro1
MOV R0,#0
pro1: MOV P2,#0FFH ;先熄滅數碼管以免產生掃尾現象
MOV A,R0
MOV P1,A
MOV A,#DisBuffer
ADD A,R0 ;第R0位對應的緩沖區的地址
MOV R1,A
MOV A,@R1 ;將緩沖區的內容送A
MOV P2,A ;將A中的內容送P2口顯示
INC R0
SETB EA
SETB TR0
POP PSW
POP ACC
RETI
KeyIN:
PUSH PSW
MOV PSW,#10H ;選擇第二組寄存器組
MOV P0,#0FFH
CLR P0.0
MOV A,P0
CJNE A,#0XFE,CHECK ;Scane L1若有鍵按下時調用CHECK子程序
SETB P0.0
CLR P0.1
MOV A,P0
CJNE A,#0XFD,CHECK ;Scane L2 若有鍵按下時調用CHECK子程序
SETB P0.0
SETB P0.1
CLR P0.2
MOV A,P0
CJNE A,#0XFB,CHECK ;Scane L3 若有鍵按下時調用CHECK子程序
SETB P0.0
SETB P0.1
SETB P0.2
CLR P0.3
MOV A,P0
CJNE A,#0XF7,CHECK ;Scane L4 若有鍵按下時調用CHECK子程序
CLR C ;沒有鍵按下清除C
retsub:
MOV flag,c
POP PSW
MOV C,flag
RET
CHECK:
MOV Keydata,A ;將P0口的狀態給Keydata
MOV R2,#16 ;設定查找次數為15次而R2賦16
MOV A,#0
MOV R6,#0 ;初始計數寄存器
MOV DPTR,#key_TABLE ;開始查表鍵
D:
MOV A,R6 ;將寄存器6的值送a
MOVC A,@A+DPTR ;查表將得到是值送a
CJNE A,Keydata,D1 ;將a的值與p0口對比若不相等查詢下一個
JMP OK ;相等調用OK子程序
D1:
INC R6 ;將R6的值加1
DJNZ R2, D ;r2不等于0轉移
CLR C
MOV Keydata,#0FFH ;沒有查到數時將0FF送 Keydata
RET
OK:
SETB C
MOV A,R6 ;查到第R6個數則這個數是R6
MOV Keydata,A ;將數值送Keydata
JMP retsub
SEG1_TABLE:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,79H ;數字的0~9 + - */ 對應 ASCD "E"對應錯誤
key_TABLE:
DB 7EH,7DH,7BH,0BEH,0BDH,0BBH,0DEH,0DDH,0DBH,0EEH,77H,0B7H,0D7H,0E7H,0EBH,0EDH ;鍵盤的16個鍵
評論