This is part of my Garage Door Opener programme using a 16F88.
I expect the 16F871 is similar. I hope it helps you.
This is the initialise sub routine.
Initialise
BANKSEL CMCON ;selects BANK 1
movlw 0x07 ;see spec of the 16F88 p.121
movwf CMCON ;turn comparators off
movlw 0x03 ;see spec p.113
movwf ANSEL ;set AN0:1 as analogue inputs
bsf OSCCON,6 ;
bsf OSCCON,5 ;
bcf OSCCON,4 ;OSCCON <6:4> = 110 => 4 MHz
movlw b'11111111' ;AN1:0 Pot1, Pot2, RA3:2 up, down
movwf TRISA ;RA7:4 DL, UL, stp, opto
movlw b'00000000' ;RB7:4 Ux, Dx, led_5, enUD
movwf TRISB ;RB3:0 light, pwr, led_1, laser
movlw 0xA8 ;external TMR0, 1:1 (bit 0 = prescale WDT)
movwf OPTION_REG ;bit 7 = 1 disables PORTB pullup resistors
movlw 0x00 ;ADCON1 - bank 1: set RIGHT justification,
movwf ADCON1 ; -ref = 0V & +ref = 5V. see 16f88 spec p. 115
BANKSEL portb ;selects BANK 0
clrf portb
movlw 0x20 ;see spec page 72
movwf T1CON ;TMR1 - 1:4 prescale, internal clock
movlw 0x7E ;see spec page 80
movwf T2CON ;TMR2 on, set for 1:16 prescale & postscale
movlw 0x41 ;Fosc/8 & A/D on
movwf ADCON0 ;see spec page 114
clrf INTCON ;no interrupts
return
This is the sub routine that reads the AN inputs.
meas_pots
bcf tmr1_on ;stop TMR1
btfsc Ux ;is the door going up?
bsf ADCON0, 3 ;Yes, select AN1
btfsc Dx ;is the door going down?
bcf ADCON0, 3 ;Yes, select AN0
call delay_30u ;30 us delay
bsf ADCON0,2 ;start the A/D conversion
btfsc ADCON0,2
goto $-1 ;wait until finished
movfw ADRESH ;high byte of force Pot voltage
movwf force_H ;store high byte of force Pot voltage
BANKSEL ADRESL ;select bank 1
movfw ADRESL ;low byte of force Pot voltage
BANKSEL force_L ;select bank 0
movwf force_L ;store low byte of force Pot voltage
bcf c_bit
rrf force_H ;divide pot value by 8
rrf force_L ;the LSB bits of force_L are 0
rrf force_H
rrf force_L
rrf force_H
rrf force_L
movlw 0x63 ;0x630 = 1584 = minimum "pot value"
addwf force_H ; 101 ms pot at min, 134 ms pot at max
return