15.5.3 Windowed Multiple Conversions

In Windowed Conversions Example, the conversion results are accumulated until the RA4 pin is at the high level. The conversions are triggered from 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()
{
    // RA4/RP5 pin is a trigger input.
    // Switch to a digital input.
    ANSELAbits.ANSELA4 = 0;
    // Make an input. 
    TRISAbits.TRISA4 = 1;
    // Map external pin trigger to RP5/RA4.
    _ADTRIG31R = 5; 
    // In this example channel 3 will be used.
    // Set limit for the accumulated samples number.
    AD1CH3CNTbits.CNT = 0xffff; 
    // Window conversion mode.
    AD1CH3CONbits.MODE = 1;
    // Accumulation will be started/stopped from an external pin.
    AD1CH3CONbits.TRG1SRC = 31; 
    // Trigger all conversions from the ADC repeat timer.
    AD1CH3CONbits.TRG2SRC = 3; 
    // Select the AN5 analog positive input/pin.
    AD1CH3CONbits.PINSEL = 5;
    // Select signal sampling time (6.5 TADs = 81nS).
    AD1CH3CONbits.SAMC = 3;
    // Set period of the triggers timer (63 is maximum).
    AD1CONbits.RPTCNT = 60;
    // Set ADC to RUN mode.
    AD1CONbits.MODE = 2;
    // Enable ADC.
    AD1CONbits.ON = 1;
    // Wait when ADC will be ready/calibrated.
    while(AD1CONbits.ADRDY == 0);
    // Enable interrupt;
    _AD1CH3IE = 1;
    
    // Channel 3 is converted and results are accumulated until the RA4 pin is high.
    // On transition from high to low an interrupt is generated.
    while(1);
    
    return 1;
}

void __attribute__((interrupt)) _AD1CH3Interrupt() {
    // Read result in accumulator and clear CH3RDY flag.
    result = AD1CH3DATA;
    number_of_accumulated_samples = AD1CH3CNTbits.CNTSTAT;
    result /= number_of_accumulated_samples;
    // Clear interrupt flag.
    _AD1CH3IF = 0;
}