久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8397|回復: 4
收起左側

有沒有人用匯編的線反轉法編寫調試完成4*4矩陣鍵盤的掃描顯示呢?

[復制鏈接]
ID:9596 發表于 2009-5-21 21:49 | 顯示全部樓層 |閱讀模式
最近在用匯編編寫矩陣鍵盤的掃描(P1.0~P1.3為行線,P1.4~P1.7為列線),采用的是線反轉法,預想編程的效果是 按下一個鍵時,先是用P0口控制的八只發光二極管(共陽接法)的發光情況來表示所按鍵在的行和列,比如按下0號鍵(第0行和第0列),則P0口的狀態為11101110,即第1只和第5只二極管點亮,保持一段時間后,再通過數碼管顯示出所按鍵的鍵號,第一步通過二極管顯示可以正常完成,但數碼管顯示就一直不對,很亂,只有最后一列的按鍵有時按下會顯示出正確的鍵號,其他的都不知道顯示的什么,找了好幾本書,上面講的思想都一樣,我也是那樣編的,但就是有問題,不知道有沒有哪位有同樣想法編寫過這樣的程序,或是哪位感興趣的編編看,交流交流啊!
回復

使用道具 舉報

ID:9596 發表于 2009-5-25 12:21 | 顯示全部樓層

沒人幫忙解決嘛,自己想辦法解決了一些問題,不會顯示亂碼了,也去掉了用二極管顯示行列狀態的部分,不過又遇到了新的問題,就是硬件仿真執行程序的時候只能連續按下4到5個鍵并正常顯示,之后再按其他鍵就沒反應了,好像死了似的,想不通,現將程序貼出來,希望有人幫忙分析,謝謝!

;*****************************************************
;矩陣鍵盤的識別,檢測是否有按鍵按下,并將其
;鍵號通過LED數碼管顯示出來
;*****************************************************
            ORG 0000H
            AJMP MAIN
            ORG 0100H
    MAIN :  MOV 31H,#00H
            MOV 30H,#00H
            ACALL KEY  ;調用鍵盤掃描子程序
    
            ACALL SHOW0;調用判斷按鍵鍵號即數碼管顯示子程序
            AJMP MAIN
;************************************************************
;按鍵掃描子程序KEY
;************************************************************

   KEY:  MOV P1,#0FH;   P1口低四位作輸入端,置1,高四位清0
         MOV A,P1   ;   讀P1口到累加器A
         ANL A,#0FH ;   屏蔽高四位
         XRL A,#0FH ;   (A)與0FH相異或
         JNZ HKEY;      判斷是否有按鍵按下,有,轉到按鍵去抖子程序
         AJMP KEY ;     沒有,返回繼續掃描
 HKEY :  LCALL DELAY10ms;調用延時10ms子程序
         MOV A,P1   ;    再讀P1口
         ANL A,#0FH ;    屏蔽高四位
         MOV 30H,A  ;    將行線狀態放30H單元低四位寄存
         XRL A,#0FH ;    (A)與0FH相異或
         JNZ WKEY   ;    判斷是否真的有鍵按下,若是,轉到判斷哪個按鍵按下子程序
         AJMP KEY   ;    若不是,則返回繼續掃描
       
 WKEY :               ;   判斷列線狀態
         MOV P1,#0F0H ;   P1口高四位作輸入端,置1,低四位清0
         MOV A,P1     ;   讀P1口到累加器A
         ANL A,#0F0H  ;   屏蔽低四位
         MOV 31H,A    ;   將列線狀態放入31H暫存
         XRL A,#0F0H  ;   
         JZ KEY       ;   再次判斷按鍵狀態,增強識別的可*性
         MOV A,31H    ;   將列線狀態送回A
         ORL A,30H    ;   將行列狀態合并
         MOV 30H,A    ;   放入30H
         ACALL DELAY10ms; 調用延時10ms子程序
   RE:   MOV A,P1     ;   再讀入P1口狀態
         CJNE A,#0F0H,RE; 判斷按鍵是否釋放了,沒有,則等待釋放
         RET            ; 若釋放了,則返回

;到這邊為止經過測試是沒有問題的,讀出的行列狀態即30H中的內容是正確的,就是執行后面的程序不知道為什么會出問題!!!!!
;***************************************************************
;判斷按鍵的鍵號及數碼管顯示子程序SHOW0
;**************************************************************
   SHOW0: 
    
      L1:   MOV A,30H    ;將檢測到得按鍵行列狀態送到A
            XRL A,#77H   ;(A)與77H(01110111)相異或
            JNZ L2       ;判斷是否是第16個鍵按下,若不是,轉到L2判斷是否是第15個鍵按下
            MOV A,#0FH   ;若是,則將鍵號送入A
            ACALL SHOW0_1;調用數碼管顯示子程序
      L2:   MOV A,30H    ;...............................
            XRL A,#0B7H  ;..............................
            JNZ L3      
            MOV A,#0EH
            ACALL SHOW0_1
      L3:   MOV A,30H
            XRL A,#0D7H
            JNZ L4
            MOV A,#0DH
            ACALL SHOW0_1
      L4:   MOV A,30H
            XRL A,#0E7H
            JNZ L5
            MOV A,#0CH
            ACALL SHOW0_1
      L5:   MOV A,30H
            XRL A,#7BH
            JNZ L6
            MOV A,#0BH
            ACALL SHOW0_1
      L6:   MOV A,30H
            XRL A,#0BBH
            JNZ L7
            MOV A,#0AH
            ACALL SHOW0_1
      L7:   MOV A,30H
            XRL A,#0DBH
            JNZ L8
            MOV A,#09H
            ACALL SHOW0_1
      L8:   MOV A,30H
            XRL A,#0EBH
            JNZ L9
            MOV A,#08H
            ACALL SHOW0_1
    
      L9:   MOV A,30H
            XRL A,#7DH
            JNZ L10
            MOV A,#07H
            ACALL SHOW0_1
      L10:  MOV A,30H
            XRL A,#0BDH
            JNZ L11
            MOV A,#06H
            ACALL SHOW0_1
      L11:  MOV A,30H
            XRL A,#0DDH
            JNZ L12
            MOV A,#05H
            ACALL SHOW0_1
      L12:  MOV A,30H
            XRL A,#0EDH
            JNZ L13
            MOV A,#04H
            ACALL SHOW0_1
      L13: 
            MOV A,30H
            XRL A,#7EH
            JNZ L14
            MOV A,#03H
            ACALL SHOW0_1
      L14:  MOV A,30H
            XRL A,#0BEH
            JNZ L15
            MOV A,#02H
            ACALL SHOW0_1
      L15:  MOV A,30H
            XRL A,#0DEH
            JNZ L16
            MOV A,#01H
            ACALL SHOW0_1
      L16:  MOV A,30H
            XRL A,#0EEH
            JNZ L17            ;若檢測到均不是以上鍵號對應的按鍵按下,則轉到L17返回主程序重新檢測
            MOV A,#00H
            ACALL SHOW0_1      ;.....................
      L17: 
            AJMP MAIN
;********************************************************************************
;鍵號送數碼管顯示
;********************************************************************************          
SHOW0_1:   CLR P2.0
            MOV DPTR,#TAB
            MOVC A,@A+DPTR
            MOV P0,A
    
            RET
DELAY10ms:  MOV R6,#20 ;延時10ms子程序
      LX0:  MOV R7,#248h
            DJNZ R7,$
            DJNZ R6,LX0
            RET
   TAB:  DB 0C0H,0F9H,0A4H,0B0H
         DB 99H,92H,82H,0F8H
         DB 80H,90H,88H,83H
         DB 0C6H,0A1H,86H,8EH
    
         END

回復

使用道具 舉報

ID:9596 發表于 2009-5-29 00:04 | 顯示全部樓層

哈哈,真慘,自己的問題還是要自己回答啊,問題已解決了,主要有兩個問題:

  1、沒有關閉ADC、DAC時鐘通道數據寄存器。這是因為對自己實驗板還沒有完全學習掌握完,所以這是賣家幫助解決的,很欽佩賣家的服務態度!解決方法就是將其關閉唄:

            ORG 0000H
            AJMP MAIN1
            ORG 0100H
    MAIN1:  CLR P2.2 ;關閉時鐘芯片
            CLR P3.7;關閉數碼管以外的其他通道
            SETB P2.2
    MAIN :  MOV 31H,#00H
            MOV 30H,#00H
            LCALL KEY  ;調用鍵盤掃描子程序
            LCALL SHOW0;調用判斷按鍵鍵號即數碼管顯示子程序
            AJMP MAIN

           ……………

但僅僅這樣問題依然存在,下一個問題是什么呢?

  2、子程序設計與堆棧技術:在調用子程序的時候我沒有按照子程序的原則,最后一定以返回指令RET結束,而是用的AJMP指令,一種解決方法就是如賣家的建議,按子程序設計的原則來,以RET 結束,鍵盤掃描子程序無需修改,修改如下;

          ………………  …………

;****************************************************************

;判斷按鍵的鍵號及數碼管顯示子程序SHOW0

;**************************************************************
   SHOW0: 
      L1:   MOV A,30H    ;將檢測到得按鍵行列狀態送到A
            XRL A,#77H   ;(A)與77H(01110111)相異或
            JNZ L2       ;判斷是否是第16個鍵按下,若不是,轉到L2判斷是否是第15個鍵按下
            MOV A,#0FH   ;若是,則將鍵號送入A
            ACALL SHOW0_1;調用數碼管顯示子程序
     RET
      L2:   MOV A,30H    ;...............................
            XRL A,#0B7H  ;..............................
            JNZ L3      
            MOV A,#0EH
            ACALL SHOW0_1
     RET
      L3:   MOV A,30H
            XRL A,#0D7H
            JNZ L4
            MOV A,#0DH
            ACALL SHOW0_1
     RET
      L4:   MOV A,30H
            XRL A,#0E7H
            JNZ L5
            MOV A,#0CH
            ACALL SHOW0_1
     RET
      L5:   MOV A,30H
            XRL A,#7BH
            JNZ L6
            MOV A,#0BH
            ACALL SHOW0_1
     RET
      L6:   MOV A,30H
            XRL A,#0BBH
            JNZ L7
            MOV A,#0AH
            ACALL SHOW0_1
     RET
      L7:   MOV A,30H
            XRL A,#0DBH
            JNZ L8
            MOV A,#09H
            ACALL SHOW0_1
     RET
      L8:   MOV A,30H
            XRL A,#0EBH
            JNZ L9
            MOV A,#08H
            ACALL SHOW0_1
     RET
      L9:   MOV A,30H
            XRL A,#7DH
            JNZ L10
            MOV A,#07H
            ACALL SHOW0_1
     RET
      L10:  MOV A,30H
            XRL A,#0BDH
            JNZ L11
            MOV A,#06H
            ACALL SHOW0_1
     RET
      L11:  MOV A,30H
            XRL A,#0DDH
            JNZ L12
            MOV A,#05H
            ACALL SHOW0_1
     RET
      L12:  MOV A,30H
            XRL A,#0EDH
            JNZ L13
            MOV A,#04H
            ACALL SHOW0_1
     RET
      L13:  MOV A,30H
            XRL A,#7EH
            JNZ L14
            MOV A,#03H
            ACALL SHOW0_1
     RET
      L14:  MOV A,30H
            XRL A,#0BEH
            JNZ L15
            MOV A,#02H
            ACALL SHOW0_1
     RET
      L15:  MOV A,30H
            XRL A,#0DEH
            JNZ L16
            MOV A,#01H
            ACALL SHOW0_1
     RET
      L16:  MOV A,30H
            XRL A,#0EEH
            JNZ L17            ;若檢測到均不是以上鍵號對應的按鍵按下,則轉到L17返回主程序重新檢測
            MOV A,#00H
            ACALL SHOW0_1;.....................
      L17:  RET


;********************************************************************************
;鍵號送數碼管顯示
;********************************************************************************          
SHOW0_1:    CLR P2.0
            MOV DPTR,#TAB
            MOVC A,@A+DPTR
            MOV P0,A
     RET

DELAY10ms:  MOV R6,#20 ;延時10ms子程序
      LX0:  MOV R7,#248
            DJNZ R7,$
            DJNZ R6,LX0
     RET
   TAB:  DB 0C0H,0F9H,0A4H,0B0H
         DB 99H,92H,82H,0F8H
         DB 80H,90H,88H,83H
         DB 0C6H,0A1H,86H,8EH
    
         END

但究其原因,我為什么要用RET結束呢?總得有原因的吧,通過看書,思考,我認為這應該是堆棧的問題,因為在執行調用子程序的指令時,也執行了PUSH(壓入堆棧)指令,將數據壓入堆棧,而在子程序執行完后,我用的AJMP指令,程序就直接跳到AJMP指定的地址去了,而壓入堆棧的數據還在堆棧中,與使用RET指令相比,少了一個POP(出棧)過程,所以每執行一次調用子程序指令,就會往堆棧中壓入數據,而堆棧SP是一個8為寄存器,在反復執行幾次調用指令后,SP指針就到棧頂了,相當于堆棧已壓經滿了數據,后面再執行調用指令時,數據無法壓入堆棧,也就導致程序無法繼續執行了,這就是為什么之后無論怎么按鍵都沒反應的原因了,到這里,我想何不“將錯就錯”,直接在主程序中加一條設置堆棧的指令,當然最好在每個子程序執行完后設置一下堆棧,于是做出如下修改(紅色和綠色為修改的部分):

;*****************************************************
;矩陣鍵盤的識別,檢測是否有按鍵按下,并將其
;鍵號通過LED數碼管顯示出來
;*****************************************************
            ORG 0000H
            AJMP MAIN
            ORG 0100H
    MAIN :  CLR P2.2;
            clr p3.7;
     SETB P2.2
    MAIN1:  mov sp,#07h
            MOV 31H,#00H
            MOV 30H,#00H

            LCALL KEY  ;調用鍵盤掃描子程序
    
            LCALL SHOW0;調用判斷按鍵鍵號即數碼管顯示子程序
         AJMP MAIN1
    上述兩種修改方法均經過實驗板調試,可以正常運行!但不知道我的解釋有沒有問題,還是希望有高人指點,謝謝! 

回復

使用道具 舉報

ID:9596 發表于 2009-5-29 00:06 | 顯示全部樓層
不過建議還是按照子程序設計的規則來寫程序,不然可能會出現很多意想不到的情況的!
回復

使用道具 舉報

ID:71905 發表于 2015-1-9 13:07 | 顯示全部樓層
求問樓主拿鍵盤掃描子程序
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成年人在线视频 | 国产精品中文字幕一区二区三区 | 男女羞羞视频免费看 | 超碰成人在线观看 | 亚洲成人一区 | 日韩成人国产 | 国产三级精品三级在线观看四季网 | 欧美一区二区三区视频在线观看 | 中文字幕一区二区三区精彩视频 | 精品一区国产 | 伊人久久在线观看 | 国产精品日日摸夜夜添夜夜av | 黄色毛片免费 | 欧美一级网站 | 天堂资源最新在线 | 在线一区二区三区 | 天天射影院 | 成人在线欧美 | 日韩高清一区 | 日批免费看 | 蜜桃在线一区二区三区 | 亚洲激情av | 盗摄精品av一区二区三区 | 欧美久久一区二区 | 色一级片| 国产一区二区影院 | 亚洲国产精品一区二区三区 | 1204国产成人精品视频 | 日本久久网 | 999国产精品视频 | 国产精品区二区三区日本 | 久久伊人在 | 国产在线播 | av黄色在线观看 | www国产成人 | 在线观看国产视频 | 国产日韩欧美在线 | 国产欧美精品一区二区色综合朱莉 | 国产免费av在线 | 国产99小视频 | 伊人影院99 |