PIC16F883實現按鍵行列掃描,準確識別按鍵,數碼管顯示按鍵編號

控制芯片:PIC16F883 oop

引腳圖: code

按鍵鏈接圖: io

 

四位數碼管鏈接:四個共陰極分別鏈接PORTA<3:0>,8段數碼管分別鏈接PORTC<7:0>,PORTB<4,2:0>分別鏈接按鍵的四個I/O引腳。 class

我在PORTC上鍊接了數碼管,按鍵進行編號。按鍵時數碼管會顯示對應的編號。 變量

簡單說明: 原理

我是改變PORTB引腳的設置(TRISB,PORTB),寫了後馬上讀取PORTB引腳的值,檢查鏈接按鍵的引腳——值爲0的引腳有按鍵按下。好比上圖,PORTB<4,2,1,0>引腳全設置爲輸入時,讀取PORTB寄存器的值。若我按下了S7,PORTB4就是0值(同理S8\S9\S10)。咱們微機原理老師強調必定先檢測S7\S8\S9\S10。我沒試過先檢測其餘按鍵的狀況,是按照老師的提示作的。下次更改設置:PORTB4設爲輸出低電位(0),其餘三個引腳都設置爲輸入。讀取PORTB<2,1,0>引腳的值,S5\S1\S2中某一按鍵被按下就能夠在PORTB<2,1,0>對應的引腳檢測到。就這樣掃描全部按鍵,有按鍵按下就會調用按鍵處理程序。 配置

實現代碼以下: 程序

#include<p16f883.inc>

udata_shr

counter res 1 ;延時計數

counter0 res 1 ;延時計數

counter1 res 1 ;掃描按鍵變量

counter2 res 1 ;延時程序微調參數

key_state res 1 ;按鍵狀態

keynum res 1 ;按鍵標號

swap res 1 ;確認按鍵轉換值

keydown res 1

keyup res 1



reset code 0x0000

pagesel start

goto start



;int_vector code 0x0004

code

start

banksel ANSEL ;設置PORTA爲數字模式

clrf ANSEL

banksel ANSELH ;設置PORTB爲數字模式

clrf ANSELH

banksel WPUB ;設置PORTB弱上拉

movlw b'11111111'

movwf WPUB

banksel OPTION_REG

movlw b'01000101' ;TMR0 64分頻

movwf OPTION_REG

banksel TRISA ;設置PORTA<3:0>爲輸出,接數碼管的共陰極

movlw b'11110000'

movwf TRISA

banksel PORTA

clrf PORTA

banksel TRISC

movlw b'00000000' ;設置PORTC爲輸出,接8段數碼管

movwf TRISC



loop

banksel TRISB

movf counter1,0

call Table1

movwf TRISB

banksel PORTB

movwf PORTB

movf PORTB,0

movwf key_state

movlw b'11101000'

iorwf key_state,1

movf counter1,0

call Table1

xorwf key_state,0

movwf swap

comf swap,1

incfsz swap,1

goto case1



incf counter1,1

movf counter1,0

call Table1

banksel TRISB

movwf TRISB

movf counter1,0

call Table1

banksel PORTB

movwf PORTB

movf PORTB,0 ;讀取I/O狀態

movwf key_state

movlw b'11001000'

iorwf key_state,1

movf counter1,0

call Table1

xorwf key_state,0

movwf swap

comf swap,1

incfsz swap,1

goto case2



incf counter1,1

movf counter1,0

call Table1

banksel TRISB

movwf TRISB

movf counter1,0

call Table1

banksel PORTB

movwf PORTB

movf PORTB,0 ;讀取I/O狀態

movwf key_state

movlw b'11001000'

iorwf key_state,1

movf counter1,0

call Table1

xorwf key_state,0

movwf swap

comf swap,1

incfsz swap,1

goto case3



incf counter1,1

movf counter1,0

call Table1

banksel TRISB

movwf TRISB

movf counter1,0

call Table1

banksel PORTB

movwf PORTB

movf PORTB,0 ;讀取I/O狀態

movwf key_state

movlw b'11001000'

iorwf key_state,1

movf counter1,0

call Table1

xorwf key_state,0

movwf swap

comf swap,1

incfsz swap,1

goto case4

goto continue

case1

btfsc key_state,4

goto key2

movlw d'1'

movwf keynum

call DealKeyPress

goto continue

key2

btfsc key_state,2

goto key3

movlw d'2'

movwf keynum

call DealKeyPress

goto continue

key3

btfsc key_state,1

goto key4

movlw d'3'

movwf keynum

call DealKeyPress

goto continue

key4

btfsc key_state,0

goto continue

movlw d'4'

movwf keynum

call DealKeyPress

goto continue









case2

;-------------------------------------------------

;下面代碼實現K10\K8\K5的按鍵處理

btfsc key_state,2

goto key8

movlw d'10'

movwf keynum

call DealKeyPress

goto continue

;------------------------------------

;處理K8

key8

btfsc key_state,1

goto key5

movlw d'8'

movwf keynum

call DealKeyPress

goto continue

;------------------------------------

;處理K5

key5

btfsc key_state,0

goto case3

movlw d'5'

movwf keynum

call DealKeyPress

goto continue



case3

;----------------------------------

;處理K6/K9

btfsc key_state,1

goto key6

movlw d'9'

movwf keynum

call DealKeyPress

goto continue

key6

btfsc key_state,0

goto case4

movlw d'6'

movwf keynum

call DealKeyPress

goto continue

case4

;-----------------------------------------

;處理K7

btfsc key_state,0

goto continue

movlw d'7'

movwf keynum

call DealKeyPress



continue

clrf counter1

goto loop







delay ;按鍵去抖,約8mS

movlw d'4'

movwf counter2

LOOP2

banksel TMR0

clrf TMR0

LOOP1

banksel INTCON

btfss INTCON,T0IF

goto LOOP1

bcf INTCON,T0IF

decfsz counter2,1

goto LOOP2

return



DealKeyPress

call delay

movf counter1,0

call Table1

banksel TRISB

movwf TRISB

banksel PORTB

movwf PORTB

movf PORTB,0 ;讀取I/O狀態

movwf key_state

movlw b'11101000'

iorwf key_state,1

movf counter1,0

call Table1

xorwf key_state,0

movwf swap

comf swap,1

incfsz swap,1

goto continue



movf keynum,0

call Table3

banksel PORTC

movwf PORTC

clrf keynum

return



Table1 ;PORTB、TRISB掃描配置信息

    ADDWF   PCL,f

    RETLW   B'11111111' 

    RETLW   B'11101111'

    RETLW   B'11111011'

    RETLW   B'11111101'

     

Table3 ;PORTC設置,數碼管真值表

    ADDWF   PCL,f

RETLW B'01001001' ;三條橫線

    RETLW   B'10111111' ;0

    RETLW   B'00000110' ;1

    RETLW   B'01011011' ;2

    RETLW   B'01001111' ;3

    RETLW   B'01100110' ;4

    RETLW   B'01101101' ;5

    RETLW   B'01111101' ;6

    RETLW   B'00000111' ;7

    RETLW   B'01111111' ;8

    RETLW   B'01101111' ;9

end

我用邏輯與運算屏蔽掉PORTB<7,6,4>號引腳。僅檢查PORTB<4,2,1,0>引腳。該方法先檢測按鍵七、八、九、10,調整配置後檢測按鍵五、一、2,再調整配置檢測按鍵三、4,最後調整配置檢測按鍵6。 方法

1)PORTB<4,2,1,0>設置爲輸入,而後讀取並檢測這四個角 im

2)PORTB4設置爲輸出低電平0,PORTB<2,1,0>設置爲輸入,而後檢測二、一、0引腳電平(爲0則有按鍵按下)

3)PORTB2設置爲輸出低電平,其餘三個腳設置爲輸入,僅檢測一、0引腳電平

4)PORTB1設置爲輸出低電平,其餘三個角設置爲輸入,僅檢測0引腳電平

因爲個人按鍵編號與上圖鏈接圖不一致,圖中的K七、K八、K九、K10分別對應個人K一、K二、K三、K4(按下數碼管會顯示一、二、三、4),K二、K四、K6分別對應個人K五、K六、K7(按下會顯示五、六、7),K一、K3分別對應個人K八、K9(按下分別顯示八、9),K5對應個人K10(這個因爲數碼管只設置1-9,K10按下會顯示7是吳顯示)。

相關文章
相關標籤/搜索