3.2 Bare Metal Code
The necessary code and functions to implement the presented example are analyzed in this section. It has five functions: three of them configure the ADCC, FVR and the main oscillator and one discharges the sample capacitor. The last one initiates the conversion on the temperature channel.
The first step will be to configure the microcontroller to disable the Watchdog Timer (WDT) and to enable low-voltage programming.
/*disable Watchdog*/ #pragma config WDTE = OFF /* Low voltage programming enabled, RE3 pin is MCLR */ #pragma config LVP = ON
CLK_Init
function selects HFINTOSC as the main
osciilator and sets the frequency to 1
MHz.static void CLK_Init(void) { /* set HFINTOSC Oscillator */ OSCCON1bits.NOSC = 6; /* set HFFRQ to 1 MHz */ OSCFRQbits.HFFRQ = 0; }
The FVR_Init
function enables the Fixed Voltage Reference
(FVR) and the temperature sensor. The sensor is configured to work on the low range as
the high range requires an operating voltage above 3.6V.
static void FVR_Init(void) { /*Enable temperature sensor*/ FVRCONbits.TSEN = 1; /*Enable FVR*/ FVRCONbits.FVREN = 1; }
ADCC_Init
function configures the peripheral to use its
FRC clock and give the results right
justified.static void ADCC_Init(void) { /* Enable the ADCC module */ ADCON0bits.ADON = 1; /* Select FRC clock */ ADCON0bits.ADCS = 1; /* result right justified */ ADCON0bits.ADFM = 1; }
ADCC_DischargeSampleCap
function connects the ADCC
channel to VSS to discharge the sampling capacitor and provide accurate
results.static void ADCC_DischargeSampleCap(void) { /*channel number that connects to VSS*/ ADPCH = 0x3C; }
ADCC_ReadValue
function initiates the conversion on the
temperature channel, waits for it to end and returns the value. The channel number to
connect to the temperature sensor is
0x3C
.static uint16_t ADCC_ReadValue(uint8_t channel) { ADPCH = channel; /*start conversion*/ ADCON0bits.ADGO = 1; while (ADCON0bits.ADGO) { ; } return ((uint16_t)((ADRESH << 8) + ADRESL)); }
The value from the ADC is then converted to Celsius and Fahrenheit values that give the temperature of the device. The variables can be checked with the debugger.
#define VDD 3.3 #define ADC_TO_CELSIUS(adcVal) (int16_t) \ ((1241.4967 - VDD * (1024 - (adcVal))) / 2.70336) #define ADC_TO_FAHRENHEIT(adcVal) (int16_t) \ ((((1241.4967 - VDD * (1024 - (adcVal))) / 2.70336) * 1.8) + 32)