16.6.3 Windowed Multiple Conversions

In Windowed Conversions Example, the conversion results are accumulated until the RD6 pin is at a high level. The conversions are triggered by the internal ADC timer.

Windowed Conversions Example

#include <xc.h>

// The channel output from primary accumulator.
volatile long result = 0; 
// The number of accumulated samples.
volatile long number_of_accumulated_samples;


int main() {
    _TRISC8 = 0;

    //Set up clock for 40Msps operation
    clock_ADC_for_40Msps_from_PLL2();
    // RD6/RP55 pin is a trigger input.
    // Make it a digital input
    _ANSELD6 = 0;
    _TRISD6 = 1;
        // Map external pin trigger to RD6/RP55
    _ADTRG31R = 55;
    // In this example channel 0 will be used.
    // Set limit for the accumulated samples number.
    AD3CH0CNTbits.CNT = 0xffff;
    // Window conversion mode.
    AD3CH0CON1bits.MODE = 1;
    // Accumulation will be started/stopped from an external pin.
    AD3CH0CON1bits.TRG1SRC = 31;
    // Logic LOW on RD6/RP55 will trigger conversion
    AD3CH0CON1bits.TRG1POL = 1;
    // Trigger all conversions from the ADC repeat timer.
    AD3CH0CON1bits.TRG2SRC = 3;
    // Select the AN0 analog positive input/pin.
    AD3CH0CON1bits.PINSEL = 0;
    // Select signal sampling time (6.5 TADs = 81nS).
    AD3CH0CON1bits.SAMC = 3;
    // Set period of the triggers timer (63 is maximum).
    AD3CONbits.RPTCNT = 60;
    // Interrupt when AD3CH0DATA is updated
    AD3CH0CON1bits.IRQSEL = 1;
    // Enable ADC.
    AD3CONbits.ON = 1;
    // Wait when ADC will be ready/calibrated.
    while (AD3CONbits.ADRDY == 0);
    // Enable interrupt;
    _AD3CH0IF = 0;
    _AD3CH0IE = 1;
    // Channel 0 is converted and results are accumulated until the RD6 pin is high.
    // On transition from high to low an interrupt is generated.
    while (1);
    return 1;
}

void __attribute__((interrupt)) _AD3CH0Interrupt(){
    _LATC8 ^= 1;
    
    // Read result in accumulator and clear CH3RDY flag.
    result = AD3CH0DATA;
    number_of_accumulated_samples = AD3CH0CNTbits.CNTSTAT;
    result /= number_of_accumulated_samples;
    
    // Clear interrupt flag.
    _AD3CH0IF = 0;
}