新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于單片機(jī)計(jì)算器的匯編程序

        基于單片機(jī)計(jì)算器的匯編程序

        作者: 時(shí)間:2016-11-25 來源:網(wǎng)絡(luò) 收藏

        程序中是實(shí)現(xiàn)了一字節(jié)整數(shù)的加減乘除計(jì)算,支持連續(xù)按鍵的情況,其程序流程圖將要上傳至圖片,希望對(duì)愛好者有所幫助也希望能夠得到高手的指點(diǎn)。

        本文引用地址:http://www.104case.com/article/201611/321253.htm

        ORG 00H
        LJMP MAIN
        ORG 0BH ;定時(shí)器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 定時(shí)器0的方式1
        MOV TH0,#0D8H
        MOV TL0,#0F0H ;定時(shí)時(shí)間為10ms
        SETB ET0
        SETB EA
        SETB TR0

        MOV 50H,#3FH ;初始化緩沖區(qū)50h-52h
        MOV 51H,#3FH
        MOV 52H,#3FH

        WORK:
        CLR C
        CALL KeyIN ;調(diào)用鍵盤掃描程序有鍵按下時(shí)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 ;進(jìn)位為0則轉(zhuǎn)移

        ;檢測(cè)狀態(tài)程序段
        MOV A,STA ;將狀態(tài)值送A
        RL A
        MOV DPTR,#STTAB ;將分支程序的初值送DPTR
        JMP @A+DPTR ;選擇程序分支
        STTAB:
        AJMP STA0 ;狀態(tài)0子程序
        AJMP STA1 ;狀態(tài)1子程序
        AJMP STA2 ;狀態(tài)2子程序
        AJMP STA3 ;狀態(tài)3子程序
        AJMP STA4 ;狀態(tài)4子程序
        AJMP STA5 ;狀態(tài)5子程序
        STA0:
        MOV A,Keydata ;將鍵值送A
        CLR C ;清除進(jìn)位位
        SUBB A,#10 ;判斷是否位數(shù)字鍵
        JNC STA0END ;否時(shí)轉(zhuǎn)移到STA0END
        CALL DATA_IN ;調(diào)用DATA_IN子程序講數(shù)值送入Buff
        MOV STA,#1
        STA0END:
        JMP Display
        STA1:
        MOV A,Keydata ;將鍵盤所對(duì)應(yīng)的數(shù)值送A
        CLR C ;清除進(jìn)位位
        SUBB A,#10 ;判斷是否位數(shù)字鍵
        JNC STA1NEXT ;否時(shí)轉(zhuǎn)移到continue
        CALL DATA_IN ;調(diào)用DATA_IN子程序講數(shù)值送入Buff
        JNC STA1END ;無(wú)溢出時(shí)跳至狀態(tài)1結(jié)束節(jié)點(diǎn)
        MOV STA,#5 ;有溢出時(shí)將狀態(tài)標(biāo)志置為5
        STA1END:
        JMP Display
        ;判斷是否為運(yùn)算符 是時(shí)將Buff中的值送給OP1 將運(yùn)算符送OP中保存 將狀態(tài)置為2態(tài)
        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 ;是否為等號(hào) 不是時(shí)轉(zhuǎn)移
        MOV OP1,Buff ;是"="時(shí)將Buff中的數(shù)值送OP1
        MOV Buff,#0 ;將Buff清空將狀態(tài)變?yōu)?態(tài)
        MOV STA,#4
        JMP STA1END ;跳到STA1END
        ;不是=時(shí)只能為C鍵
        STA1NEXT2:
        MOV Buff,#0 ;將Buff清空 將狀態(tài)置為0態(tài)
        MOV STA,#0
        JMP STA1END ;跳至狀態(tài)1結(jié)束節(jié)點(diǎn)
        ;STA2處理程序
        STA2:
        MOV A,Keydata ;將鍵盤所對(duì)應(yīng)的數(shù)值送A
        CLR C ;清除進(jìn)位位
        SUBB A,#10 ;判斷是否位數(shù)字鍵
        JNC STA2NEXT ;否時(shí)轉(zhuǎn)移到STA2NEXT
        MOV Buff,#0
        CALL DATA_IN ;調(diào)用DATA_IN子程序講數(shù)值送入Buff
        MOV STA,#3
        STA2END:
        JMP Display
        ;是否為運(yùn)算符 是時(shí)將運(yùn)算符送OP否時(shí)轉(zhuǎn)移至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 ;是否為等號(hào) 不是時(shí)轉(zhuǎn)移STA2NEXT2 是"="時(shí) 將狀態(tài)設(shè)為4態(tài)
        MOV STA,#4
        JMP STA2END
        STA2NEXT2: ;是C鍵時(shí)將Buff清空將狀態(tài)變?yōu)?態(tài)
        MOV Buff,#0
        MOV STA,#0
        JMP STA2END
        STA3:
        MOV A,Keydata ;將鍵盤所對(duì)應(yīng)的數(shù)值送A
        CLR C ;清除進(jìn)位位
        SUBB A,#10 ;判斷是否位數(shù)字鍵
        JNC STA3NEXT ;否時(shí)轉(zhuǎn)移到STA3NEXT
        CALL DATA_IN ;調(diào)用DATA_IN子程序講數(shù)值送入Buff
        JNC STA3END ;無(wú)溢出時(shí)跳至狀態(tài)3結(jié)束節(jié)點(diǎn)
        MOV STA,#5 ;有溢出時(shí)將狀態(tài)標(biāo)志置為5
        STA3END:
        JMP Display
        ;判斷是否為運(yùn)算符 是運(yùn)算符時(shí)先進(jìn)行運(yùn)算 且判斷是否有溢出
        STA3NEXT:
        MOV A,Keydata
        CLR C
        SUBB A,#14
        JNC STA3NEXT1 ;不是運(yùn)算符時(shí)進(jìn)行下次判斷是否為=
        MOV OP2,Buff ;是運(yùn)算符時(shí)將緩沖區(qū)的數(shù)值給OP2 再將緩沖區(qū)清除
        MOV Buff,#0
        CALL Comput ;調(diào)用Comput 將結(jié)果Resut送入OP1

        JNC STA3NEXT2 ;計(jì)算完成后判斷數(shù)值是否有溢出 沒有時(shí)跳至STA3NEXT2

        MOV STA,#5 ;結(jié)果有溢出時(shí)進(jìn)入狀態(tài)5
        JMP STA3END
        STA3NEXT2:
        MOV OP1,Resut
        MOV OP,Keydata ;連續(xù)按運(yùn)算符的情況
        MOV STA,#2
        JMP STA3END
        ;判斷是否為"="的情況
        STA3NEXT1:
        MOV A,Keydata
        CJNE A,#14,STA3NEXT3
        MOV OP2,Buff ;是運(yùn)算符時(shí)將緩沖區(qū)的數(shù)值給OP2 再將緩沖區(qū)清除
        MOV Buff,#0
        CALL Comput
        JNC STA3NEXT4 ;計(jì)算完成后判斷數(shù)值是否有溢出 沒有時(shí)跳至STA3NEXT4
        MOV STA,#5 ;結(jié)果有溢出時(shí)進(jìn)入狀態(tài)5
        JMP STA3END
        STA3NEXT4: ;將結(jié)果送入OP1進(jìn)入狀態(tài)4
        MOV A,Resut
        MOV OP1,A
        MOV STA,#4
        JMP STA3END
        STA3NEXT3: ;按C鍵的情況將緩沖區(qū)清除 進(jìn)入狀態(tài)0
        MOV Buff,#0
        MOV STA,#0
        JMP STA3END
        STA4:
        MOV A,Keydata ;將鍵盤所對(duì)應(yīng)的數(shù)值送A
        CLR C ;清除進(jìn)位位
        SUBB A,#10 ;判斷是否位數(shù)字鍵
        JNC STA4NEXT ;不是數(shù)字鍵時(shí)處理
        MOV Buff,#0 ;清除緩沖區(qū)

        CALL DATA_IN ;調(diào)用DATA_IN子程序
        MOV STA,#1 ;進(jìn)入狀態(tài)1
        STA4END:
        JMP Display
        ;判斷是否為運(yùn)算符
        STA4NEXT:
        MOV A,Keydata
        CLR C
        SUBB A,#14
        JNC STA4NEXT1
        MOV OP,Keydata ;將鍵盤所對(duì)應(yīng)的數(shù)值送OP
        MOV STA,#2
        JMP STA4END
        ;為C鍵的處理
        STA4NEXT1:
        MOV A,Keydata
        CJNE A,#15,STA4END
        MOV Buff,#0
        MOV STA,#0
        JMP STA4END
        ;在狀態(tài)5判斷是否為C鍵 若是則清除緩沖區(qū)
        STA5:
        MOV A,Keydata
        CJNE A,#15,STA5END
        MOV Buff,#0
        MOV STA,#0
        STA5END:
        JMP Display
        ;Display子程序段 當(dāng)為狀態(tài)0、1、3時(shí)轉(zhuǎn)向Buff_display 當(dāng)為狀態(tài)2、4時(shí)轉(zhuǎn)向OP1_display當(dāng)為狀態(tài)5和其他狀態(tài)時(shí)轉(zhuǎn)向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
        ;檢查是一位數(shù)時(shí)進(jìn)入G_display 是兩位數(shù)時(shí)進(jìn)入SH_display 三位數(shù)時(shí)進(jìn)行 B_display
        BandOP1dis:
        MOV A,R3
        MOV B,#10 ;將R3中的內(nèi)容除10 若商為0則為一位數(shù)
        DIV AB
        JZ G_display
        MOV A,R3 ;將R3中的內(nèi)容除100 若商為0則為兩位數(shù)否則為三位數(shù)
        MOV B,#100
        DIV AB
        JZ SH_display
        JMP B_display
        G_display:
        MOV DPTR,#SEG1_TABLE ;B中的數(shù)就是個(gè)位上的數(shù) 將個(gè)位數(shù)所對(duì)應(yīng)的7段碼送50h 且將51h、52H 存入0FFH將數(shù)碼管熄滅
        MOV R2,B
        MOV A,R2
        MOVC A,@A+DPTR
        MOV 52H,A
        MOV 51H,#0
        MOV 50H,#0
        JMP BandOend
        SH_display: ;將R3中的內(nèi)容除10 商為十位上的數(shù) 余數(shù)為個(gè)位上的數(shù)
        MOV DPTR,#SEG1_TABLE
        MOV A,R3
        MOV B,#10
        DIV AB
        MOVC A,@A+DPTR
        MOV 51H,A ;將十位上的數(shù)所對(duì)應(yīng)的7段碼送51h
        MOV R2,B
        MOV A,R2
        MOV DPTR,#SEG1_TABLE
        MOVC A,@A+DPTR
        MOV 52H,A ;將個(gè)位上的數(shù)所對(duì)應(yīng)的7段碼送50h
        MOV 50H,#0
        JMP BandOend
        B_display: ;經(jīng)過判斷以后 A中的數(shù)為百位上的數(shù)將所對(duì)應(yīng)的7段碼送52h
        MOV DPTR,#SEG1_TABLE
        MOVC A,@A+DPTR
        MOV 50H,A
        MOV R2,B ;B中為后兩位數(shù)
        MOV A,R2
        MOV B,#10
        DIV AB ;運(yùn)算后A中為十位上的數(shù) B中為個(gè)位上的數(shù)
        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 ;跳入顯示結(jié)束程序口 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 ;跳入顯示結(jié)束程序口 DisOver

        DisOver:
        JMP WORK

        ;DATA_IN 子程序段實(shí)現(xiàn) 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
        ;計(jì)算子程序段
        Comput:
        MOV A,OP ;因運(yùn)算符的末位數(shù)為0、1、2、3
        MOV B,#10 ;將OP除以10所得的余數(shù)為所對(duì)應(yīng)的末尾數(shù) 再將其賦予A進(jìn)行分支程序選擇
        DIV AB
        MOV R5,B
        MOV A,R5
        RL A
        MOV DPTR,#ComTAB
        JMP @A+DPTR
        ComTAB:
        AJMP ADDER ;為0時(shí)為加法運(yùn)算
        AJMP SUBBER ;為1時(shí)為減法運(yùn)算
        AJMP MULER ;為2時(shí)為乘法運(yùn)算
        AJMP DIVER ;為3時(shí)為除法運(yùn)算
        ADDER: ;加法運(yùn)算
        MOV A,OP1
        ADDC A,OP2
        JMP ComEND
        SUBBER: ;減法運(yùn)算
        MOV A,OP1
        SUBB A,OP2
        JMP ComEND
        MULER: ;乘法運(yùn)算
        MOV A,OP1
        MOV B,OP2
        MUL AB
        JMP ComEND
        DIVER: ;除法運(yùn)算
        MOV A,OP1
        MOV B,OP2
        DIV AB
        JMP ComEND
        ComEND: ;將結(jié)果送Resut
        MOV Resut,A
        MOV C,PSW.2 ;將溢出標(biāo)志送C
        RET

        ;中斷程序處理中斷任務(wù)

        PROC_COUNT: ;將緩沖區(qū)的內(nèi)容送數(shù)碼管顯示
        PUSH ACC ; r0 顯示位 計(jì)數(shù) 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 ;顯示的位數(shù)超過4時(shí)R0賦值0
        SUBB A,#3 ;R0的值與3相減有借位時(shí)轉(zhuǎn)移到pro1
        JC pro1
        MOV R0,#0
        pro1: MOV P2,#0FFH ;先熄滅數(shù)碼管以免產(chǎn)生掃尾現(xiàn)象
        MOV A,R0
        MOV P1,A
        MOV A,#DisBuffer
        ADD A,R0 ;第R0位對(duì)應(yīng)的緩沖區(qū)的地址
        MOV R1,A
        MOV A,@R1 ;將緩沖區(qū)的內(nèi)容送A
        MOV P2,A ;將A中的內(nèi)容送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若有鍵按下時(shí)調(diào)用CHECK子程序

        SETB P0.0
        CLR P0.1
        MOV A,P0
        CJNE A,#0XFD,CHECK ;Scane L2 若有鍵按下時(shí)調(diào)用CHECK子程序

        SETB P0.0
        SETB P0.1
        CLR P0.2
        MOV A,P0
        CJNE A,#0XFB,CHECK ;Scane L3 若有鍵按下時(shí)調(diào)用CHECK子程序

        SETB P0.0
        SETB P0.1
        SETB P0.2
        CLR P0.3
        MOV A,P0
        CJNE A,#0XF7,CHECK ;Scane L4 若有鍵按下時(shí)調(diào)用CHECK子程序
        CLR C ;沒有鍵按下清除C

        retsub:
        MOV flag,c
        POP PSW
        MOV C,flag
        RET

        CHECK:

        MOV Keydata,A ;將P0口的狀態(tài)給Keydata
        MOV R2,#16 ;設(shè)定查找次數(shù)為15次而R2賦16
        MOV A,#0
        MOV R6,#0 ;初始計(jì)數(shù)寄存器
        MOV DPTR,#key_TABLE ;開始查表鍵
        D:
        MOV A,R6 ;將寄存器6的值送a
        MOVC A,@A+DPTR ;查表將得到是值送a
        CJNE A,Keydata,D1 ;將a的值與p0口對(duì)比若不相等查詢下一個(gè)
        JMP OK ;相等調(diào)用OK子程序
        D1:
        INC R6 ;將R6的值加1
        DJNZ R2, D ;r2不等于0轉(zhuǎn)移
        CLR C
        MOV Keydata,#0FFH ;沒有查到數(shù)時(shí)將0FF送 Keydata
        RET

        OK:
        SETB C
        MOV A,R6 ;查到第R6個(gè)數(shù)則這個(gè)數(shù)是R6
        MOV Keydata,A ;將數(shù)值送Keydata
        JMP retsub


        SEG1_TABLE:
        DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,79H ;數(shù)字的0~9 + - */ 對(duì)應(yīng) ASCD "E"對(duì)應(yīng)錯(cuò)誤
        key_TABLE:
        DB 7EH,7DH,7BH,0BEH,0BDH,0BBH,0DEH,0DDH,0DBH,0EEH,77H,0B7H,0D7H,0E7H,0EBH,0EDH ;鍵盤的16個(gè)鍵




        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 昭苏县| 馆陶县| 随州市| 嘉峪关市| 嵩明县| 化德县| 阳信县| 通许县| 喜德县| 白城市| 沛县| 清丰县| 富源县| 乐东| 寿阳县| 平江县| 洛宁县| 夹江县| 南部县| 陆河县| 青州市| 新巴尔虎右旗| 芜湖市| 岳普湖县| 唐海县| 高陵县| 绥宁县| 大城县| 林周县| 丽水市| 唐海县| 博兴县| 类乌齐县| 桐柏县| 榆林市| 虹口区| 湖南省| 蓝田县| 区。| 日喀则市| 武强县|