作为一个简单实用的示例,图1中的电路利用一个8位PIC微控制器控制一个4位LED显示器,显示出按下了哪个按钮。当任意按钮被按下时,比较器中断程序会立即作出响应。该程序会在VREF值之间进行循环,直至比较器输出COUT返回高电平,表明该按钮被按下。完整注释的汇编程序源代码总共不到100字。该代码并未作过度优化,从而可方便理解或易于转化到其他控制器上。

汇编程序源代码:
; 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<3:0>=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<3:0>=cnt3<3:0>
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<3:0>=0001 => ratio = 1/24
BANK0
BCF	PIR1, CMIF	 ; clear comparator interrupt flag
RETFIE
;-----------------------------------------------------------------------------
END