4.2 Bare Metal Code

The necessary code and functions to implement the presented example are analyzed in this section.

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
The CLK_Init function selects HFINTOSC as the main oscillator and sets its 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 configures the mode and time constant in ADCON2 and the number of repetitions in ADRPT as well as selecting the FRC dedicated clock and setting 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;  
     /* Low pass filter mode */
    ADCON2bits.ADMD = 4;  
    /* lpf time constant = 16 */
    ADCON2bits.ADCRS = 4; 

    ADRPT = 100;
}
The ADCC_DischargeSampleCap function connects the ADCC channel to VSS in order to discharge the sampling capacitor.
static void ADCC_DischargeSampleCap(void)
{
    /*channel number that connects to VSS*/
    ADPCH = 0x3C;
}
The ADCC_ReadValue function initiates a conversion on the analog channel and returns the result. The channel number that connects to pin RA0 is 0x00. The variable can then be checked with the debugger.
static uint16_t ADCC_ReadValue(uint8_t channel)
{   
    ADPCH = channel;
    /*start conversion*/
    ADCON0bits.ADGO = 1;
    while (ADCON0bits.ADGO)
    {
        ;
    }
        
    return ((uint16_t)((ADRESH << 8) + ADRESL));
}