簡易四則運算計算器(C51微控制器實現)
阿新 • • 發佈:2019-02-03
【說明】
這是嵌入式課程的一個小作業,用C51微控制器,實現了0-255內的簡易四則運算,暫不支援負數、溢位等特殊情況的處理。
【關鍵點】
1、計算器用R5、R6、R7三位顯示,段碼為0,全暗,段碼為0xff,全亮。
2、R3用於儲存運算子
3、兩數都用B壓入棧中,最後取結果時可以分別彈出,並根據操作符計算。
4、程式在兩數的第一位預設都輸入數字,其他位置皆可復位。
5、一次計算完成後、按任意鍵復位。
【鍵盤位置】
程式碼:
;3位0-255計算器,支援四則運算 ;按鍵有0-9、+、-、*、/、復位、= ;R5,R6,R7分別用於顯示三位 ;暫不支援負數、溢位處理 ORG 0000H LJMP START WC EQU P0 ;數碼管位控 DC EQU P1 ;數碼管段控 KC EQU P2 ;鍵盤檢測 ORG 0030H START: MOV R5, #0 MOV R6, #0 MOV R7, #0 N1_B1: ACALL KEYDOWN CJNE R4, #0x10, PRO1 ;檢測到按鍵做相應處理 ACALL DISPLAY JMP N1_B1 ;否則繼續檢測 PRO1: MOV A, R4 MOV R0, A MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R5, A N1_B2: ACALL DISPLAY ACALL KEYDOWN CJNE R4, #0x10, PRO2 ;檢測按鍵,有鍵按下做相應處理 JMP N1_B2 PRO2: MOV A, R4 ACALL JUDGE_OPER ;檢查是否為操作符 CJNE R3, #0x04, CON1 ;是清除鍵,直接復位 JMP START CON1: CJNE R3, #0x06, PRO3 ;是操作符,跳轉到PRO3 MOV A, R4 ;是數字 MOV R1, A MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R6, A MOV R4, #0x10 JMP N1_B3 PRO3: MOV B, R0 ;將num1的結果儲存在B中 PUSH B JMP N2_B1 ;轉去判斷第2個數的第1位 N1_B3: ACALL DISPLAY ;第1個數字第3位 ACALL KEYDOWN CJNE R4, #0x10, PRO4 ;檢測按鍵,有鍵按下做相應處理 JMP N1_B3 PRO4: MOV A, R4 ACALL JUDGE_OPER ;檢查是否為操作符 MOV A, R3 CJNE A, #0x04, CON2 ;是清除鍵,直接復位 JMP START CON2: CJNE A, #0x06, PRO5 ;等於則是數字,不等於則是操作符 MOV A, R4 ;是數字 MOV R2, A MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R7, A MOV A, R0 ;保留第1位數 MOV B, #100D MUL AB MOV R0, A ;將百位保留在R0 MOV A, R1 ;保留第2位數 MOV B, #10D MUL AB MOV R1, A ;將十位保留在R1 MOV A, R2 ;相加 ADD A, R1 ADD A, R0 MOV B, A ;將第1位數先存在B中 PUSH B JMP OPER PRO5: MOV A, R0 MOV B, #10D MUL AB MOV R0, A MOV A, R1 ADD A, R0 MOV B, A PUSH B JMP N2_B1 OPER: ACALL DISPLAY ACALL KEYDOWN MOV A, R4 CJNE A, #0x10, PRO6 ;有鍵按下 JMP OPER PRO6: MOV A, R4 ACALL JUDGE_OPER MOV A, R3 CJNE A, #0x04, N2_B1 ;不等於是操作符,等於是復位鍵 JMP START N2_B1: ACALL DISPLAY ;第2個數第1位 ACALL KEYDOWN MOV A, R4 CJNE A, #0x10, PRO7 ;有鍵按下 JMP N2_B1 PRO7: MOV A, R4 ;保留原有操作符 PUSH 0x03 ;儲存R3中的操作符標記 ACALL JUDGE_OPER MOV A, R3 POP 0x03 CJNE A, #0x04, CON3 ;判斷是否是復位鍵 JMP START CON3: MOV A, R4 MOV R0, A MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R5, A MOV R6, #0x00 ;清除後兩位顯示 MOV R7, #0X00 N2_B2: ACALL DISPLAY ACALL KEYDOWN MOV A, R4 CJNE A, #0x10, PRO8 ;有鍵按下 JMP N2_B2 PRO8: MOV A, R4 ;保留原有操作符 PUSH 0x03 ;儲存R3中的操作符標記 ACALL JUDGE_OPER MOV A, R3 POP 0x03 CJNE A, #0x04, CON4 ;不是清除鍵繼續判斷 JMP START CON4: CJNE A, #0x06, PRO9 ;不相等說明是操作符,相等說明是數字 MOV A, R4 MOV R1, A MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R6, A JMP N2_B3 PRO9: CJNE A, #0x05, MIDNODE ;不是等於號,出錯返回 MOV A, R0 MOV B, A PUSH B JMP EDIS N2_B3: ACALL DISPLAY ACALL KEYDOWN MOV A, R4 CJNE A, #0x10, PRO10 JMP N2_B3 PRO10: MOV A, R4 ;保留原有操作符 PUSH 0x03 ;儲存R3中的操作符標記 ACALL JUDGE_OPER MOV A, R3 POP 0x03 CJNE A, #0x04, CON5 ;不是清除鍵繼續判斷 JMP START CON5: CJNE A, #0x06, PRO11 ;不相等說明是操作符 MOV A, R4 MOV R2, A MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R7, A MOV A, R0 MOV B, #100D MUL AB MOV R0, A MOV A, R1 MOV B, #10D MUL AB MOV R1, A MOV A, R2 ADD A, R1 ADD A, R0 MOV B, A PUSH B JMP AK MIDNODE: JMP START PRO11: CJNE A, #0x05, MIDNODE ;通過中繼節點返回 MOV B, #10D MOV A, R0 MUL AB ADD A, R1 MOV B, A PUSH B JMP EDIS AK: ACALL DISPLAY ACALL KEYDOWN MOV A, R4 CJNE A, #0x10, EDIS JMP AK EDIS: POP B MOV A, B POP B MOV R0, A ;交換AB MOV A, B MOV B, R0 MOV R1, A MOV A, R3 CJNE A, #0x00, NXT1 ;通過R3的值,判斷運算子 MOV A, R1 ;並進行相應運算 ADD A, B JMP TS NXT1: CJNE A, #0x01, NXT2 MOV A, R1 SUBB A, B JMP TS NXT2: CJNE A, #0x02, NXT3 MOV A, R1 MUL AB JMP TS NXT3: CJNE A, #0x03, MIDNODE MOV A, R1 DIV AB TS: ;轉換顯示 MOV R0, A MOV B, #100D DIV AB MOV R1, A MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R5, A MOV A, B MOV B, #10D DIV AB MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R6, A MOV A, B MOV DPTR, #DCODE MOVC A, @A+DPTR MOV R7, A RESTART: ACALL DISPLAY ACALL KEYDOWN MOV A, R4 CJNE A, #0x10, MIDNODE JMP RESTART ;按鍵檢測程式,若有鍵按下,返回0-15,無鍵按下返回16 KEYDOWN: MOV R4, #0x10 MOV KC, #0x0F MOV A, KC CJNE A, #0X0F, PRO ;檢測列 RET PRO: ACALL DELAY ;延時消抖 MOV A, KC CJNE A, #0X0F, COL ;確認有鍵按下 RET COL: COL1: MOV A, KC CJNE A, #0X07, COL2 ;判斷哪一列 MOV R4, #0H JMP ROW COL2: CJNE A, #0X0B, COL3 MOV R4, #4H JMP ROW COL3: CJNE A, #0X0D, COL4 MOV R4, #8H JMP ROW COL4: CJNE A, #0X0E, BACK ;沒有列被按下,直接返回 MOV R4, #0CH ROW: MOV KC, #0XF0 ;行檢測 MOV A, KC ROW1: CJNE A, #0X70, ROW2 MOV A, R4 ADD A, #3H MOV R4, A JMP BACK ROW2: CJNE A, #0XB0, ROW3 MOV A, R4 ADD A, #2H MOV R4, A JMP BACK ROW3: CJNE A, #0XD0, ROW4 MOV A, R4 ADD A, #1H MOV R4, A JMP BACK ROW4: BACK: MOV A, R4 CJNE A, #0x10, DY RET DY: ACALL DELAY ACALL DELAY ACALL DELAY ACALL DELAY RET ;數碼管顯示3位數字,分別存在R5,R6,R7 DISPLAY: PUSH 0x00 PUSH 0x01 MOV R0, #0 ;輸出位碼 MOV DPTR, #WCODE MOV A, R0 MOVC A, @A+DPTR MOV WC, A ;輸出段碼 MOV A, R5 MOV DC, A MOV R1, #0x0f LP1: ;延長單位顯示時間 DJNZ R1, LP1 MOV DC, #0 INC R0 ;輸出位碼 MOV DPTR, #WCODE MOV A, R0 MOVC A, @A+DPTR MOV WC, A ;輸出段碼 MOV A, R6 MOV DC, A MOV R1, #0x0f LP2: ;延長單位顯示時間 DJNZ R1, LP2 MOV DC, #0 INC R0 ;輸出位碼 MOV DPTR, #WCODE MOV A, R0 MOVC A, @A+DPTR MOV WC, A ;輸出段碼 MOV A, R7 MOV DC, A MOV R1, #0x0f LP3: ;延長單位顯示時間 DJNZ R1, LP3 MOV DC, #0 POP 0x01 POP 0x00 RET ;判斷A中是什麼操作符,+ — * / reset =分別對應R3中的值為0-5, ;若不是操作符,則R3中的值被設定為6 JUDGE_OPER: MOV R3, #6 AD: CJNE A, #0x0a, SB ;不是加號,跳到減號 MOV R3, #0 ;0代表加法 RET SB: CJNE A, #0x0b, ML ;不是減號,跳到乘號 MOV R3, #1 ;1代表減法 RET ML: CJNE A, #0x0c, DV ;不是乘號,跳到除號 MOV R3, #2 ;2代表乘法 RET DV: CJNE A, #0x0d, CL ;不是除號,跳到清除鍵 MOV R3, #3 ;3代表除法 RET CL: CJNE A, #0x0e, EU ;不是清除鍵,跳到等號 MOV R3, #4 ;4代表清除鍵 RET EU: CJNE A, #0x0f, FN ;不是等號,返回 MOV R3, #5 ;5代表等號 FN: RET ;延時程式 DELAY: PUSH 0x00 ;保護現場,R0,R1 PUSH 0x01 MOV R0, #96H LP4: MOV R1, #82H LP5: DJNZ R1, LP5 DJNZ R0, LP4 POP 0x01 ;還原現場 POP 0x00 RET WCODE: DB 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f ;位碼 DCODE: DB 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f ;段碼 NUM1: DB 0xff,0xff,0xff ;運算元1 NUM2: DB 0xff,0xff,0xff ;運算元2 END