2.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, the main oscillator and the pin, while the fourth one discharges the sample capacitor and the last one initiates the conversion and returns the result.
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
oscillator 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 PORT_Init
function sets the RA0 pin as analog input.
static void PORT_Init(void) { /*set pin RA0 as analog*/ ANSELAbits.ANSELA0 = 1; /*set pin RA0 as input*/ TRISAbits.TRISA0 = 1; }
The ADCC_Init
function enables the ADCC, configures it to
give right-justified results and use its dedicated clock.
static void ADCC_Init(void) { /* Enable the ADCC module */ ADCON0bits.ADON = 1; /* Select FRC clock */ ADCON0bits.ADCS = 1; /* result right justified */ ADCON0bits.ADFM = 1; }
The ADCC_DischargeSampleCap
function connects the ADCC to
VSS and thus discharges the capacitor to provide an accurate reading.
static void ADCC_DischargeSampleCap(void) { /*channel number that connects to VSS*/ ADPCH = 0x3C; }
The ADCC_ReadValue
function selects the channel, starts the
conversion, waits for it to end and then returns the result. This result is saved into a
variable that can be watched with the debugger. The channel that connects to pin RA0 is
0x00
.
static uint16_t ADCC_ReadValue(uint8_t channel) { ADPCH = channel; /*start conversion*/ ADCON0bits.ADGO = 1; while (ADCON0bits.ADGO) { ; } return ((uint16_t)((ADRESH << 8) + ADRESL)); }