;
; be80be's example ADC program for 16F684
;
;
list p=16f684 ; list directive to define processor
#include <P16F684.inc>
errorlevel -302 ; Turn off banking message
radix dec
__CONFIG _BOD_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF
CBLOCK 0x020
shadow
newadc
oldadc
endc
v5.0 equ 50000/196 ; adc value for 5.0v
v4.0 equ 40000/196 ; adc value for 4.0v
v3.0 equ 30000/196 ; adc value for 3.0v
v2.5 equ 25000/196 ; adc value for 2.5v
v2.0 equ 20000/196 ; adc value for 2.0v
v1.0 equ 10000/196 ; adc value for 1.0v
org 0x000 ; reset vector
init
bsf STATUS,RP0 ; select Register Page 1
movlw 0xFF ;
movwf TRISA ; Make PortA all input
clrf TRISC ; Make PortC all output
movlw 0x10 ; A2D Clock Fosc/8
movwf ADCON1 ;
bcf STATUS,RP0 ; back to Register Page 0
bsf STATUS,RP1 ; select Register Page 2
movlw 0xFF ; we want all Port A pins Analog
movwf ANSEL ;
bcf STATUS,RP1 ; back to Register Page 0
clrf ADCON0 ;
movlw 0x01 ;
movwf ADCON0 ; configure A2D for Channel 0
loop
call adcdelay ; delay to charge cap
bsf ADCON0,GO ; start adc conversion
btfss ADCON0,GO ; complete? yes, skip, else
goto $-1 ; branch (wait for complete)
movf ADRESH,W ; new adc reading, 0..255
;
; get absolute "delta" between 'new' and 'old' ADC readings
;
movwf newadc ; W = new reading, 0..255
subwf oldadc,W ; subtract from 'oldadc'
skpc ; borrow? no, skip, else
sublw 0 ; twos complement WREG
;
; use 'newadc' if ∆ adc >= 2 points, else use 'oldadc'
;
sublw 2 ; C=0 if ∆ adc >= 2 points
movf oldadc,W ; use 'oldadc' if C=1
skpc ; C=1? yes, skip, else
movf newadc,W ; use 'newadc' if C=0
movwf oldadc ; update 'oldadc' var
;
; adc 'window' compare code
;
clrf shadow ; clear LED shadow reg'
addlw -v5.0 ; C = adcval >= 255 (5.0v)
rlf shadow,F ; move C into 'shadow'
btfss shadow,0 ; borrow? no, skip, else
addlw v5.0 ; undo the subtract
addlw -v4.0 ; C = adcval >= 204 (4.0v)
rlf shadow,F ; move C into 'shadow'
btfss shadow,0 ; borrow? no, skip, else
addlw v4.0 ; undo the subtract
addlw -v3.0 ; C = adcval >= 153 (3.0v)
rlf shadow,F ; move C into 'shadow'
btfss shadow,0 ; borrow? no, skip, else
addlw v3.0 ; undo the subtract
addlw -v2.5 ; C = adcval >= 127 (2.5v)
rlf shadow,F ; move C into 'shadow'
btfss shadow,0 ; borrow? no, skip, else
addlw v2.5 ; undo the subtract
addlw -v2.0 ; C = adcval >= 102 (2.0v)
rlf shadow,F ; move C into 'shadow'
btfss shadow,0 ; borrow? no, skip, else
addlw v2.0 ; undo the subtract
addlw -v1.0 ; C = adcval >= 51 (1.0v)
rlf shadow,W ;
movwf PORTC ; update LED display
goto loop ; loop
adcdelay
nop ; 1 cycle
return ; 5 cycles (including call)
end