新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機鍵盤掃描程序(匯編)

        單片機鍵盤掃描程序(匯編)

        作者: 時間:2016-11-18 來源:網絡 收藏
        ;這個相對起來比較難,如果理解不了的話,可以(返回日志目錄,或者是本日志的右上角,你也可以看到)看上篇(課程設計:矩陣鍵盤,相對來說,非常簡單了)

        ;鍵盤掃描程序;此程序比較復雜,不過如果你堅持的理解下去的話,還是能夠理解的,比較經典
        ;最終是按鍵的值輸出到數碼管中(接在P2口)
        ORG0000H
        START:MOVR0,#00H;初始化程序,開始的延時是為了使硬件能夠準備好
        DJNZR0,$
        LOOP: MOVSP,#60H
        CALLKEY
        DISPLAY:
        MOV A,R4
        MOV DPTR,#TABLE ;定義字形表的起始地址
        MOVC A,@A+DPTR ;TABLE為表的起始地址
        MOV P2,A
        SJMPLOOP

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


        ;子程序內容,P1口的第四位為行線,高四位為列線
        KEY: PUSHPSW
        PUSHACC
        MOVP1,#0F0H ;令所有的行為低電平,全掃描字-P1.0-P1.3,列為輸入方式
        ;這一段只是驗證有鍵按下,并不能判斷是哪一行
        MOVR7,#0FFH;設置計數常數,作為延時

        KEY1:DJNZR7,KEY1

        MOVA,P1;讀取P1口的列值
        ANLA,#0F0H;判別有鍵值按下嗎(當有鍵按下時,P1口的高四位就不全為1了,底四位還是都為0的)
        ;這個地方進行相或的原因,是因為要把底四位的0000變成1111,以便下一步進行求反
        ORLA,#0FH //這個地方原版上沒有,這是又加了,如果不加的的話,是不對的********

        CPLA;求反后,有高電平就有鍵按下
        JZEKEY;累加器為0則轉移(意為求反后本來全為0的,如果有鍵按下時,求反后高四位就有1了),退出
        LCALLDEL20ms ;有鍵按下,進行處理

        ;下面進行行行掃描,1行1行掃
        SKEY:MOVA,#00H
        MOVR0,A ;R0作為行計數器,開始初值為0
        MOVR1,A ;R1作為列計數器,開始初值為0
        MOVR2,#0FEH ;R2作為掃描暫存字,開始初值為1111 1110,(第四位作為行掃描字)

        SKEY2:MOVA,R2
        MOVP1,A ;輸出行掃描字,1111 1110
        NOP

        NOP
        NOP ;3個NOP操作使P1口輸出穩定
        MOVA,P1 ;讀列值(和開始一樣)
        MOVR1,A ;暫存列值(第一次為**** 1110,既高四位有一位"可能"會為0)
        ANLA,#0F0H ;取高四位,
        ORLA,#0FH ;使第四位全部置1
        CPLA
        BIAOZHI:JNZSKEY3;累加器為非0則轉移指令(意思是判斷到按鍵在這一行),轉去處理

        INCR0;如果按鍵沒在這一行,行計數器加1
        SETBC;進位標志位加1,為了在左移的時候開始的低位0不在出現在低(循環一圈后)
        MOVA,R2
        RLCA;帶進位左移1位(形成下一行掃描字,再次掃描)
        MOVR2,A
        MOVA,R0
        ;把加1后的行計數器R0和總共掃描次數(4次比較)
        CJNEA,#04H,SKEY2 ;(掃描完了么)書本上這個地方也有錯誤,書本上寫的是:SKEY1
        AJMPEKEY ;如果沒有的話,退出

        ;有鍵按下后行掃描過后,此為確列行
        SKEY3:MOVA,R1 ;
        JNBACC.4,SKEY5 ;直接尋址位為0咋轉移指令
        JNBACC.5,SKEY6
        JNBACC.6,SKEY7
        JNBACC.7,SKEY8
        AJMPEKEY //我自己感覺到這命令沒有用處

        SKEY5:MOVA,#00H ;存0列號
        MOVR3,A
        AJMPDKEY

        SKEY6:MOVA,#01H ;存1列號
        MOVR3,A
        AJMPDKEY

        SKEY7:MOVA,#02H ;存2列號
        MOVR3,A
        AJMPDKEY

        SKEY8:MOVA,#03H ;存3列號
        MOVR3,A
        AJMPDKEY

        ;取出具體的行號,再加上列號,最終確認按鍵的號碼
        DKEY://MOVR4,#00H
        MOVA,R0
        MOVB,#04H
        MULAB;讓行號*4,第四位放在A中(總共就4行,相乘后一定<16,也就是只有第四位有值)
        ADDA,R3;讓行號和列號相加,最終確認任按鍵的具體號
        MOVR4,A

        EKEY:POPACC
        POPPSW

        RET ;按鍵掃描處理函數

        DEL20ms:
        MOVR7,#2
        DL2: MOVR6,#18
        DL1: MOVR5,#255
        DJNZR5,$
        DJNZR6,DL1
        DJNZR7,DL2

        RET
        ;此為共陰極數碼管的數字表
        TABLE: DB 3FH ;0
        DB 06H ;1
        DB 5BH ;2
        DB 4FH ;3
        DB 66H ;4
        DB 6DH ;5
        DB 7DH ;6
        DB 27H ;7
        DB 7FH ;8
        DB 6FH ;9
        DB77H
        DB7CH
        DB39H
        DB5EH
        DB79H
        DB71H

        END



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 嵊泗县| 社旗县| 绿春县| 万源市| 镇赉县| 察隅县| 金湖县| 延津县| 札达县| 景宁| 沙河市| 永春县| 青阳县| 孝昌县| 江安县| 上杭县| 绥滨县| 湘西| 抚宁县| 剑阁县| 林州市| 原阳县| 兴和县| 邻水| 涞水县| 长岭县| 囊谦县| 新郑市| 前郭尔| 罗田县| 刚察县| 涿鹿县| 夹江县| 两当县| 陵水| 吐鲁番市| 闵行区| 桦甸市| 杭锦旗| 宣武区| 蒲城县|