• # ADC with “built-in” Scaling on PIC with FVR

To increase resolution and have a “beefier” ADC result, it is common to scale the input to an ADC with external
components, dividers, amplifiers, etc.

On some of the new PICs (I tried it with 18F1XK22 and 16F1823) you can scale the ADC without any external components
by changing the internal fixed voltage reference.
These new devices have fixed voltage reference (FVR) with a “multiplier” that can set FVR to X1 = 1.024V, X2 = 2.048V
or X3 = 4.096V.
The fixed reference for the ADC is controlled from the 2 LSB of the FVRCON (on 18F1XK22 called FVR1S and on 16F1823

Here is an example:
ADC has to be configured to use FVR as reference.
FVR has to be enabled.
To use the entire FVR range 1.024 – 4.096V the supply voltage needs to be above 4.1V
Because FVR value changes in multiplier of 2, using three FVR values has “effectively” the same affect as adding two
bits to the ADC. We add a bit to the ADC result for each increase in the FVR value. The nice thing is with a 10bit
ADC we will have a resolution of 1mV (0.001V) from 0V to 4.096V. This also means that the decimal value of the ADC
result will be in mV so a lot could be done without ever using Float variables. Code example:
Code:
```ADC_BEEFUP:
ADFVR = FVRCON & 3             ' Get the curret ADFVR value from FVRCON
i = ADFVR - 1                  ' shifting factor
GoSub FLOATVOLT                ' Optional - get the voltage in a float variable
GoSub STRVOLT                  ' Optional Print the voltage without using a float
If ADRESULT < 1020 Then        ' threshold must be less then 10bit full scale
ElseIf ADRESULT > 2040 Then    ' threshold must be less then 11bit full scale
Else
EndIf
While FVRRDY = 0 : Wend        ' wait for FVR stable
Return

FLOATVOLT:
VOLT = ADRESULT * 0.001        ' VOLT is a Float
'Print or do something with this value
Return

STRVOLT:
Str VOLTSTR = Str\$(Dec4 AVGRESULT) ' VOLTSTR is a byte array
j = 4
Repeat                             ' move one byte to the right
VOLTSTR[j] = VOLTSTR[j - 1]
Dec j
Until j = 1
j = 0
VOLTSTR[1] = "."                  ' insert a decimal point
'Print
Return```
• ### Recent Activity

#### Driving SK9822 or APA102 RGB LED's

I've been trying to figure out how to drive SK9822 or APA102 RGB LED's using the MSSP module in a PIC16F1503 but I'm getting nowhere. Part of the...

rcurl Yesterday, 20:02

#### Has anyone code to set up a firewing board 18f... to talk via the USART/USB?

Hi As per title I have a firewing board 18F and want make it talk via the built in USART/USB device to a terminal. I can program its via a Pickit2...

Tim Today, 07:43