作為一個(gè)簡(jiǎn)單實(shí)用的示例,圖1中的電路利用一個(gè)8位PIC微控制器控制一個(gè)4位LED顯示器,顯示出按下了哪個(gè)按鈕。當(dāng)任意按鈕被按下時(shí),比較器中斷程序會(huì)立即作出響應(yīng)。該程序會(huì)在VREF值之間進(jìn)行循環(huán),直至比較器輸出COUT返回高電平,表明該按鈕被按下。完整注釋的匯編程序源代碼總共不到100字。該代碼并未作過(guò)度優(yōu)化,從而可方便理解或易于轉(zhuǎn)化到其他控制器上。 匯編程序源代碼: ; MULTIBTN.ASM: sensing upto 15 pushbuttons with one I/O (pin6: GP1/CIN-) ; BENABADJI Noureddine - ORAN - Dec. 11...14th, 2013 ; Errorlevel -302 ; avoid warning #302: Register in operand not in bank0. ; Ensure that bank bits are correct. List P = 12F683 #include "p12f683.inc" __CONFIG _INTOSCIO&_MCLRE_OFF&_PWRTE_ON&_WDT_OFF&_FCMEN_OFF&_IESO_OFF&_BOD_ON&_CPD_OFF&_CP_OFF #define LED1 GPIO, 0 ; output bit0 of the 4-bit binary LED display #define LED2 GPIO, 2 ; output bit1 of the 4-bit binary LED display #define LED3 GPIO, 4 ; output bit2 of the 4-bit binary LED display #define LED4 GPIO, 5 ; output bit3 of the 4-bit binary LED display ;----------------------------- define variables ------------------------------ CBLOCK 0x20 ; bank0 = [0x20...0x7F] = 94 bytes ;delay cnt1, cnt2, cnt3 ; counters ENDC ;------------------------------------------------------------------------------ BANK0 macro BCF STATUS, RP0 ; bank0 endm ;------------------------------------------------------------------------------ BANK1 macro BSF STATUS, RP0 ; bank1 endm ;------------------------------------------------------------------------------ SIregGEval8b macro file, val, jmpOk ; if (file >= val) goto jmpOk ; MOVLW val SUBWF file, w ; w = file - val BTFSC STATUS, C GOTO jmpOk ; yes endm ;///////////////////////////////////////////////////////////////////////////// ; MAIN PROGRAM ;///////////////////////////////////////////////////////////////////////////// ORG 0x00 ; reset vector GOTO Setup ORG 0X04 ; interrupt vector GOTO IntCmp ;///////////////////////////////////////////////////////////////////////////// ;----------------------------------------------------------------------------- LEDsOFF CALL Delay256ms CLRF GPIO ; all LEDs off RETLW 0 ;----------------------------------------------------------------------------- Delay256ms CLRF cnt2 CLRF cnt1 NOP ; 1us DECFSZ cnt1, f ; 1us GOTO $-2 ; 2us => 4*256 = 1024 us, approx. 1 ms internal delay loop DECFSZ cnt2, f ; approx. 256 ms external delay loop GOTO $-4 RETLW 0 ;///////////////////////////////////////////////////////////////////////////// Setup BANK1 CLRF TRISIO ; config. all I/O as outputs BCF OPTION_REG, T0CS ; use pin5 as GP2, not TOCKI CLRF ANSEL ; use all AN as digital I/O BANK0 CLRF GPIO ; all LEDs off MOVLW b'00000111' MOVWF CMCON0 ;comparator off splash ; (initial test for LEDs) BSF LED1 CALL LEDsOFF BSF LED2 CALL LEDsOFF BSF LED3 CALL LEDsOFF BSF LED4 CALL LEDsOFF ;;;;;;;;;; initializeComparator BANK1 MOVLW b'00001010' ;config. GP1 as input (will be CIN-) MOVWF TRISIO ;BANK0 MOVLW b'10100001' ;BANK1 MOVWF VRCON ;Vref on, low range, VR=0001 => ratio = 1/24 BANK0 MOVLW b'00000100' MOVWF CMCON0 ;comparator on: CIN- = GP1; CIN+ = Vref; Cout internal ;;;;;;;;; ;enable interrupt BANK1 BSF INTCON, PEIE ; enable interrupt on Comparator trip BSF PIE1, CMIE ; enable interrupt on Comparator trip BANK0 BSF INTCON, GIE ; set general interrupt enable goto $ ; infinite loop (waiting for an interrupt) ;----------------------------------------------------------------------------- ; Comparator trip interrupt routine ;----------------------------------------------------------------------------- IntCmp ;don't need to save any context, only interrupting a goto $ BANK0 MOVLW .1 MOVWF cnt3 nextBtn INCF cnt3, F SIregGEval8b cnt3, .16, whichBtn ; if (cnt3 >= 16) goto whichBtn ; MOVLW b'10100000' ADDWF cnt3, W BANK1 MOVWF VRCON ;Vref on, low range, VR=cnt3 BANK0 BTFSS CMCON0, COUT ; Cout == 1 ? GOTO nextBtn whichBtn DECF cnt3, F BTFSC cnt3, 0 BSF LED1 BTFSC cnt3, 1 BSF LED2 BTFSC cnt3, 2 BSF LED3 BTFSC cnt3, 3 BSF LED4 CALL LEDsOFF endIntCmp MOVLW b'10100001' BANK1 MOVWF VRCON ;Vref on, low range, VR=0001 => ratio = 1/24 BANK0 BCF PIR1, CMIF ; clear comparator interrupt flag RETFIE ;----------------------------------------------------------------------------- END |
你這樣的等比例電阻分壓,多個(gè)按鈕同時(shí)按下時(shí),會(huì)錯(cuò)誤的認(rèn)為是氣體按鈕按下的,沒(méi)啥意義。 電阻分組必須按1:2:4:8:16:32:64:128:256:1024:2048......這樣的2的N次方來(lái)分配才能確定是哪幾個(gè)按鍵按下了。 |