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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 8374|回復(fù): 4
收起左側(cè)

有沒有人用匯編的線反轉(zhuǎn)法編寫調(diào)試完成4*4矩陣鍵盤的掃描顯示呢?

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

使用道具 舉報(bào)

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

沒人幫忙解決嘛,自己想辦法解決了一些問(wèn)題,不會(huì)顯示亂碼了,也去掉了用二極管顯示行列狀態(tài)的部分,不過(guò)又遇到了新的問(wèn)題,就是硬件仿真執(zhí)行程序的時(shí)候只能連續(xù)按下4到5個(gè)鍵并正常顯示,之后再按其他鍵就沒反應(yīng)了,好像死了似的,想不通,現(xiàn)將程序貼出來(lái),希望有人幫忙分析,謝謝!

;*****************************************************
;矩陣鍵盤的識(shí)別,檢測(cè)是否有按鍵按下,并將其
;鍵號(hào)通過(guò)LED數(shù)碼管顯示出來(lái)
;*****************************************************
            ORG 0000H
            AJMP MAIN
            ORG 0100H
    MAIN :  MOV 31H,#00H
            MOV 30H,#00H
            ACALL KEY  ;調(diào)用鍵盤掃描子程序
    
            ACALL SHOW0;調(diào)用判斷按鍵鍵號(hào)即數(shù)碼管顯示子程序
            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;      判斷是否有按鍵按下,有,轉(zhuǎn)到按鍵去抖子程序
         AJMP KEY ;     沒有,返回繼續(xù)掃描
 HKEY :  LCALL DELAY10ms;調(diào)用延時(shí)10ms子程序
         MOV A,P1   ;    再讀P1口
         ANL A,#0FH ;    屏蔽高四位
         MOV 30H,A  ;    將行線狀態(tài)放30H單元低四位寄存
         XRL A,#0FH ;    (A)與0FH相異或
         JNZ WKEY   ;    判斷是否真的有鍵按下,若是,轉(zhuǎn)到判斷哪個(gè)按鍵按下子程序
         AJMP KEY   ;    若不是,則返回繼續(xù)掃描
       
 WKEY :               ;   判斷列線狀態(tài)
         MOV P1,#0F0H ;   P1口高四位作輸入端,置1,低四位清0
         MOV A,P1     ;   讀P1口到累加器A
         ANL A,#0F0H  ;   屏蔽低四位
         MOV 31H,A    ;   將列線狀態(tài)放入31H暫存
         XRL A,#0F0H  ;   
         JZ KEY       ;   再次判斷按鍵狀態(tài),增強(qiáng)識(shí)別的可*性
         MOV A,31H    ;   將列線狀態(tài)送回A
         ORL A,30H    ;   將行列狀態(tài)合并
         MOV 30H,A    ;   放入30H
         ACALL DELAY10ms; 調(diào)用延時(shí)10ms子程序
   RE:   MOV A,P1     ;   再讀入P1口狀態(tài)
         CJNE A,#0F0H,RE; 判斷按鍵是否釋放了,沒有,則等待釋放
         RET            ; 若釋放了,則返回

;到這邊為止經(jīng)過(guò)測(cè)試是沒有問(wèn)題的,讀出的行列狀態(tài)即30H中的內(nèi)容是正確的,就是執(zhí)行后面的程序不知道為什么會(huì)出問(wèn)題!!!!!
;***************************************************************
;判斷按鍵的鍵號(hào)及數(shù)碼管顯示子程序SHOW0
;**************************************************************
   SHOW0: 
    
      L1:   MOV A,30H    ;將檢測(cè)到得按鍵行列狀態(tài)送到A
            XRL A,#77H   ;(A)與77H(01110111)相異或
            JNZ L2       ;判斷是否是第16個(gè)鍵按下,若不是,轉(zhuǎn)到L2判斷是否是第15個(gè)鍵按下
            MOV A,#0FH   ;若是,則將鍵號(hào)送入A
            ACALL SHOW0_1;調(diào)用數(shù)碼管顯示子程序
      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            ;若檢測(cè)到均不是以上鍵號(hào)對(duì)應(yīng)的按鍵按下,則轉(zhuǎn)到L17返回主程序重新檢測(cè)
            MOV A,#00H
            ACALL SHOW0_1      ;.....................
      L17: 
            AJMP MAIN
;********************************************************************************
;鍵號(hào)送數(shù)碼管顯示
;********************************************************************************          
SHOW0_1:   CLR P2.0
            MOV DPTR,#TAB
            MOVC A,@A+DPTR
            MOV P0,A
    
            RET
DELAY10ms:  MOV R6,#20 ;延時(shí)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

回復(fù)

使用道具 舉報(bào)

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

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

  1、沒有關(guān)閉ADC、DAC時(shí)鐘通道數(shù)據(jù)寄存器。這是因?yàn)閷?duì)自己實(shí)驗(yàn)板還沒有完全學(xué)習(xí)掌握完,所以這是賣家?guī)椭鉀Q的,很欽佩賣家的服務(wù)態(tài)度!解決方法就是將其關(guān)閉唄:

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

           ……………

但僅僅這樣問(wèn)題依然存在,下一個(gè)問(wèn)題是什么呢?

  2、子程序設(shè)計(jì)與堆棧技術(shù):在調(diào)用子程序的時(shí)候我沒有按照子程序的原則,最后一定以返回指令RET結(jié)束,而是用的AJMP指令,一種解決方法就是如賣家的建議,按子程序設(shè)計(jì)的原則來(lái),以RET 結(jié)束,鍵盤掃描子程序無(wú)需修改,修改如下;

          ………………  …………

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

;判斷按鍵的鍵號(hào)及數(shù)碼管顯示子程序SHOW0

;**************************************************************
   SHOW0: 
      L1:   MOV A,30H    ;將檢測(cè)到得按鍵行列狀態(tài)送到A
            XRL A,#77H   ;(A)與77H(01110111)相異或
            JNZ L2       ;判斷是否是第16個(gè)鍵按下,若不是,轉(zhuǎn)到L2判斷是否是第15個(gè)鍵按下
            MOV A,#0FH   ;若是,則將鍵號(hào)送入A
            ACALL SHOW0_1;調(diào)用數(shù)碼管顯示子程序
     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            ;若檢測(cè)到均不是以上鍵號(hào)對(duì)應(yīng)的按鍵按下,則轉(zhuǎn)到L17返回主程序重新檢測(cè)
            MOV A,#00H
            ACALL SHOW0_1;.....................
      L17:  RET


;********************************************************************************
;鍵號(hào)送數(shù)碼管顯示
;********************************************************************************          
SHOW0_1:    CLR P2.0
            MOV DPTR,#TAB
            MOVC A,@A+DPTR
            MOV P0,A
     RET

DELAY10ms:  MOV R6,#20 ;延時(shí)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結(jié)束呢?總得有原因的吧,通過(guò)看書,思考,我認(rèn)為這應(yīng)該是堆棧的問(wèn)題,因?yàn)樵趫?zhí)行調(diào)用子程序的指令時(shí),也執(zhí)行了PUSH(壓入堆棧)指令,將數(shù)據(jù)壓入堆棧,而在子程序執(zhí)行完后,我用的AJMP指令,程序就直接跳到AJMP指定的地址去了,而壓入堆棧的數(shù)據(jù)還在堆棧中,與使用RET指令相比,少了一個(gè)POP(出棧)過(guò)程,所以每執(zhí)行一次調(diào)用子程序指令,就會(huì)往堆棧中壓入數(shù)據(jù),而堆棧SP是一個(gè)8為寄存器,在反復(fù)執(zhí)行幾次調(diào)用指令后,SP指針就到棧頂了,相當(dāng)于堆棧已壓經(jīng)滿了數(shù)據(jù),后面再執(zhí)行調(diào)用指令時(shí),數(shù)據(jù)無(wú)法壓入堆棧,也就導(dǎo)致程序無(wú)法繼續(xù)執(zhí)行了,這就是為什么之后無(wú)論怎么按鍵都沒反應(yīng)的原因了,到這里,我想何不“將錯(cuò)就錯(cuò)”,直接在主程序中加一條設(shè)置堆棧的指令,當(dāng)然最好在每個(gè)子程序執(zhí)行完后設(shè)置一下堆棧,于是做出如下修改(紅色和綠色為修改的部分):

;*****************************************************
;矩陣鍵盤的識(shí)別,檢測(cè)是否有按鍵按下,并將其
;鍵號(hào)通過(guò)LED數(shù)碼管顯示出來(lái)
;*****************************************************
            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  ;調(diào)用鍵盤掃描子程序
    
            LCALL SHOW0;調(diào)用判斷按鍵鍵號(hào)即數(shù)碼管顯示子程序
         AJMP MAIN1
    上述兩種修改方法均經(jīng)過(guò)實(shí)驗(yàn)板調(diào)試,可以正常運(yùn)行!但不知道我的解釋有沒有問(wèn)題,還是希望有高人指點(diǎn),謝謝! 

回復(fù)

使用道具 舉報(bào)

ID:9596 發(fā)表于 2009-5-29 00:06 | 顯示全部樓層
不過(guò)建議還是按照子程序設(shè)計(jì)的規(guī)則來(lái)寫程序,不然可能會(huì)出現(xiàn)很多意想不到的情況的!
回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产激情在线播放 | 日韩免费网站 | 国产色网| 精品国产欧美一区二区 | 久久免费电影 | 一区二区在线 | 欧美九九 | 91高清免费观看 | 国产精品成人一区二区三区 | 综合欧美亚洲 | 国产精品色 | 国产精品久久久久久久久久久久久 | 午夜合集| 免费激情 | 在线视频中文字幕 | 国产精品99久久久精品免费观看 | 久久久精品视 | 成人午夜网站 | 国产区在线视频 | 亚洲成人精选 | 久久精品一区二区 | 91精品国产乱码久久久久久久 | 五月天婷婷久久 | 日韩在线电影 | 欧美精品在线看 | 欧美一区二区视频 | 成人综合久久 | 欧美激情欧美激情在线五月 | 五月天婷婷激情 | 老司机67194精品线观看 | 国产高清精品一区二区三区 | 美日韩一区二区 | 男人的天堂久久 | 久久一区二 | 国产精品免费在线 | 日韩欧美专区 | 日韩欧美网 | www日日日 | 精品一二三区 | 国产精品成人一区二区三区 | 日韩一区二区三区视频在线播放 |