控制芯片: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是吳顯示)。