16F18855 with 5K pot
So I have 2 rotary pots that refuse to go down to ADC=0. So I thought it was a perfect occasion to practice using Vref-.
I've gutted my code so there's only 1 pot being scanned:
Code:
#CONFIG
__config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_ON
__config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
__config _CONFIG3, _WDTCPS_WDTCPS_11 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_OFF
__config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG
DEFINE OSC 32
DEFINE ADC_BITS 10 ' 10-bit Analog to digital
DEFINE ADC_SAMPLEUS 5 ' Set sampling time in uS
DEFINE HSER_RXREG PORTC
DEFINE HSER_RXBIT 7
DEFINE HSER_TXREG PORTC
DEFINE HSER_TXBIT 6
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
Define HSER_BAUD 115200
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRGH 0
DEFINE HSER_SPBRG 68
;--- Setup registers -----------------------------------------------------------
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
FVRCON = %0000000 ' FIXED VOLTAGE REFERENCE CONTROL REGISTER
ADCON0 = %10000100 ' ADC CONTROL REGISTER 0
' bit 7 ADON: ADC Enable bit
' 1 = ADC is enabled
' bit 2 ADFRM0: ADC results Format/alignment Selection
' 1 = ADRES and ADPREV data are right-justified
ADCON2 = %00000000 ' ADC CONTROL REGISTER 2
' bit 2-0 ADMD<2:0>: ADC Operating Mode Selection bits(1)
' 000 = Basic (Legacy) mode
ADCLK = %00001111 ' ADC CLOCK SELECTION REGISTER
' bit 5-0 ADCCS<5:0>: ADC Conversion Clock Select bits
' 1111 = FOSC/32
ADREF = %00010000 ' ADC REFERENCE SELECTION REGISTER
' bit 4 ADNREF: ADC Negative Voltage Reference Selection bit
' 1 = VREF- is connected to VREF- pin
' 0 = VREF- is connected to AVSS
' bit 1-0 ADPREF: ADC Positive Voltage Reference Selection bits
' 11 = VREF+ is connected to FVR_buffer 1
' 10 = VREF+ is connected to VREF+ pin
' 00 = VREF+ is connected to VDD
WPUA = %11110011
WPUB = %11111111
WPUC = %00111111
ANSELA = %00010111 ' Pin A4 = ADC (B10K) ... not implemented
' Pin A3 = SW input 3
' Pin A2 = Vref-
' Pin A1 = ADC (B5K w/SW)
' Pin A0 = ADC (B5K)
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00011111 ' Pin A4 = ... not implemented
' Pin A3 = ... not implemented
' Pin A2 = Vref-
' Pin A0 = ADC input 0
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
TRISC = %11000000 ' Pin C7 = RX *** Datasheet requirement, INPUT ***
' Pin C6 = TX *** Datasheet requirement, INPUT ***
SW var PORTA.3 ' ... not implemented
MsgData var byte[3]
MsgCode VAR BYTE
ADCinput var WORD
ADCcalc var WORD
ADCdiff var WORD
OldADC var WORD
OldADC0 var WORD
OldADC1 var WORD
Pause 1500 ' Let PIC and LCD stabilize
OldADC0 = 9999
goto Mainloop
;--- Subroutines ---------------------------------------------------------------
SendData:
MsgData[0] = MsgCode : MsgData[1] = ADCcalc.byte1 : MsgData[2] = ADCcalc.byte0
hserout [ MsgData[0], MsgData[1], MsgData[2] ]
while TX1STA.1 = 0 ' Check TRMT bit
wend
oldADC0 = ADCcalc
RETURN
Mainloop:
rem ADC A0 test
MsgCode = 0 ' Record type
adcin 0, ADCinput
ADCcalc = ADCinput >> 2
if ADCcalc < oldADC0 then
ADCdiff = oldADC0 - ADCcalc
else
ADCdiff = ADCcalc - oldADC0
endif
IF ADCdiff > 2 then ' Check for Diff over 2
if ADCcalc <> oldADC0 then ' ADC value changed
GOSUB SendData
endif
ELSE
IF ADCdiff > 0 then ' Check for Diff over 0
if ADCcalc = 0 then ' Reached end of rotation
GOSUB SendData
ELSE
if ADCcalc = 255 then ' Reached end of rotation
GOSUB SendData
endif
endif
endif
endif
GOTO Mainloop
end
I've added banks of caps on the wiper-to-VSS, as well as just before the VDD pin to the pot (0.1uF, 0.01uF and 0.001uF).
I shift right only 2 digits and that seems to have stabilized things quite a lot; no noticeable jitter so far tonight. 256 seems like a workable range for me so far.
The pot has a reading of 2.0mV when full right:

The Vref- pin reads at 15.7mV (used voltage divider 1K (0.985R really) / 3R:

Pot 0 does not go below ADC=12,and is transmitted on the Saleae probe:

And shows up nicely on LCD on 2nd PIC:

I don't get it. I thought setting Vref- at 15.7mV meant that anything reading below that would read as 0...? I thought I was essentially raising the VSS lower range for ADC.
Code:
ADREF = %00010000 ' ADC REFERENCE SELECTION REGISTER
' bit 4 ADNREF: ADC Negative Voltage Reference Selection bit
' 1 = VREF- is connected to VREF- pin
' 0 = VREF- is connected to AVSS
I'm obviously missing something stupid again, but I don't see what. Or I totally misunderstood what Vref- does in life.
Bookmarks