【說明】
? ? 這是嵌入式課程的一個小作業(yè),用C51單片機,實現(xiàn)了0-255內(nèi)的簡易四則運算,暫不支持負數(shù)、溢出等特殊情況的處理。
【關(guān)鍵點】
? ? 1、計算器用R5、R6、R7三位顯示,段碼為0,全暗,段碼為0xff,全亮。
? ? 2、R3用于保存運算符
? ? 3、兩數(shù)都用B壓入棧中,最后取結(jié)果時可以分別彈出,并根據(jù)操作符計算。
? ? 4、程序在兩數(shù)的第一位默認(rèn)都輸入數(shù)字,其他位置皆可復(fù)位。
? ? 5、一次計算完成后、按任意鍵復(fù)位。
【鍵盤位置】
代碼:
;3位0-255計算器,支持四則運算 ;按鍵有0-9、+、-、*、/、復(fù)位、= ;R5,R6,R7分別用于顯示三位 ;暫不支持負數(shù)、溢出處理 ORG 0000H LJMP START WC EQU ?P0 ?;數(shù)碼管位控 DC EQU ?P1??;數(shù)碼管段控 KC EQU ?P2??;鍵盤檢測 ORG 0030H START: ?????MOV? R5, #0 ?MOV? R6, #0 ?MOV? R7, #0 N1_B1: ?ACALL KEYDOWN ?CJNE R4, #0x10, PRO1 ;檢測到按鍵做相應(yīng)處理 ? ?ACALL DISPLAY ?JMP N1_B1 ;否則繼續(xù)檢測 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 ?;檢測按鍵,有鍵按下做相應(yīng)處理 ?JMP N1_B2 PRO2: ?MOV A, R4 ?ACALL JUDGE_OPER ?;檢查是否為操作符 ?CJNE R3, #0x04, CON1 ?;是清除鍵,直接復(fù)位 ?JMP START CON1: ?CJNE R3, #0x06, PRO3 ?;是操作符,跳轉(zhuǎn)到PRO3 ??? ? ? ?????MOV A, R4 ?;是數(shù)字 ?MOV R1, A ?MOV DPTR, #DCODE ?MOVC? A, @A+DPTR ?MOV R6, A ?MOV R4, #0x10 ?JMP N1_B3 PRO3: ?????MOV B, R0 ?;將num1的結(jié)果保存在B中 ?PUSH B ?JMP N2_B1 ?;轉(zhuǎn)去判斷第2個數(shù)的第1位 N1_B3: ?ACALL DISPLAY ?;第1個數(shù)字第3位 ?ACALL KEYDOWN ?CJNE ??? R4, #0x10, PRO4 ?;檢測按鍵,有鍵按下做相應(yīng)處理 ?JMP N1_B3 PRO4: ?????MOV A, R4 ?ACALL JUDGE_OPER ?;檢查是否為操作符 ?MOV A, R3 ?CJNE A, #0x04, CON2 ?;是清除鍵,直接復(fù)位 ?JMP START CON2: ? ?CJNE A, #0x06, PRO5 ?;等于則是數(shù)字,不等于則是操作符 ?MOV A, R4 ?;是數(shù)字 ?MOV R2, A ?MOV DPTR, #DCODE ?MOVC? A, @A+DPTR ?MOV R7, A ?MOV A, R0 ?;保留第1位數(shù) ?MOV B, #100D ?MUL AB ?MOV R0, A ?;將百位保留在R0 ?MOV A, R1 ?;保留第2位數(shù) ?MOV B, #10D ?MUL AB ?MOV R1, A ?;將十位保留在R1 ?MOV A, R2 ?;相加 ?ADD A, R1 ?ADD A, R0 ?MOV B, A ?;將第1位數(shù)先存在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 ?;不等于是操作符,等于是復(fù)位鍵 ?JMP START N2_B1: ?ACALL DISPLAY ?;第2個數(shù)第1位 ?ACALL KEYDOWN ?MOV A, R4 ?CJNE A, #0x10, PRO7 ?;有鍵按下 ?JMP N2_B1 PRO7: ?MOV A, R4 ?;保留原有操作符 ?PUSH 0x03 ?;保存R3中的操作符標(biāo)記 ?ACALL JUDGE_OPER ?MOV A, R3 ?POP 0x03 ?CJNE A, #0x04, CON3 ?;判斷是否是復(fù)位鍵 ?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中的操作符標(biāo)記 ?ACALL JUDGE_OPER ?MOV A, R3 ?POP 0x03 ?CJNE A, #0x04, CON4 ?;不是清除鍵繼續(xù)判斷 ?JMP START CON4: ?CJNE A, #0x06, PRO9 ?;不相等說明是操作符,相等說明是數(shù)字 ?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中的操作符標(biāo)記 ?ACALL JUDGE_OPER ?MOV A, R3 ?POP 0x03 ?CJNE A, #0x04, CON5 ?;不是清除鍵繼續(xù)判斷 ?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 ???;通過中繼節(jié)點返回 ?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 ;并進行相應(yīng)運算 ?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: ???;轉(zhuǎn)換顯示 ?????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 ;確認(rèn)有鍵按下 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 ;數(shù)碼管顯示3位數(shù)字,分別存在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?=分別對應(yīng)R3中的值為0-5, ;若不是操作符,則R3中的值被設(shè)置為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 ;保護現(xiàn)場,R0,R1 PUSH? 0x01 MOV? R0, #96H ??LP4: MOV? R1, #82H ??LP5: DJNZ? R1, LP5 DJNZ? R0, LP4 POP? 0x01 ;還原現(xiàn)場 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 ;操作數(shù)1 ?NUM2:??DB??0xff,0xff,0xff ;操作數(shù)2 END