16.6.7 Multiple Channels Scan

In Multiple Channels Scan Example, three channels are scanned. To scan these channels, they are triggered by the same trigger source.

Multiple Channels Scan Example

#include <xc.h>
volatile long channel_2_an1;
volatile long channel_4_an2;
volatile long channel_6_an3;

// Define peripheral clock frequency.
#define FCY (4000000UL)             // 4MHz
// Define the CCP1 timer frequency.
#define TIMER_FREQUENCY (100UL)       // 1kHz

int main(){

   //Set up clock for 40Msps operation
   clock_ADC_for_40Msps_from_PLL2();
   _TRISC8 = 0;

   // In this example channels ## 2, 4 and 6 will be scanned.
   // To scan channels they must be triggered from one source.
   // The channel with lowest number (#2) will be converted first.
   // The channel with highest number (#6) will be converted last.
   // CHANNEL 2
   // Single conversion mode.
   // CCP1 Timer starts conversion (same for all scanned channels).
   AD1CH2CON1bits.TRG1SRC = 0b010011;
   // Select the AN1 analog input/pin for the channel #2.
   AD1CH2CON1bits.PINSEL = 1;
   // Select signal sampling time (6.5 TADs = 81nS).
   AD1CH2CON1bits.SAMC = 3;

   // CHANNEL 4
   // Single conversion mode.
   // CCP1 Timer starts conversion (same for all scanned channels).
   AD1CH4CON1bits.TRG1SRC = 0b010011;
   // Select the AN2 analog input/pin for the channel #4.
   AD1CH4CON1bits.PINSEL = 2;
   // Select signal sampling time (8.5 TADs = 106nS).
   AD1CH4CON1bits.SAMC = 4;

   // CHANNEL 6
   // Single conversion mode.
   // CCP1 Timer starts conversion (same for all scanned channels).
   AD1CH6CON1bits.TRG1SRC = 0b010011;
   // Select the AN3 analog input/pin for the channel #6.
   AD1CH6CON1bits.PINSEL = 3;
   // Select signal sampling time (10.5 TADs = 131nS).
   AD1CH6CON1bits.SAMC = 5;

   // Set ADC to RUN mode.
   // Enable ADC.
   AD1CONbits.ON = 1;
   // Wait when ADC will be ready/calibrated.
   while(AD1CONbits.ADRDY == 0);

   // Configure CCP1 Timer to trigger all channels (to scan).
   CCP1CON1bits.MOD = 0;
   // Set 32-bit timer.
   CCP1CON1bits.T32 = 1;
   // Set period.
   CCP1PR = FCY/TIMER_FREQUENCY;
   // Run timer.
   CCP1CON1bits.ON = 1;

   // Enable channel # 6 interrupt.
   // This channel is processed last and all other channels results
   // will be ready in the channel #6 ISR.
   _AD1CH6IE = 1;

   while(1);

   return 1;
}
// Channel # 6 interrupt (processed last). All channels
// results in the scan are available here.
void __attribute__((interrupt)) _AD1CH6Interrupt(){
_LATC8 ^= 1;
channel_2_an1 = AD1CH2DATA;
channel_4_an2 = AD1CH4DATA;
channel_6_an3 = AD1CH6DATA;
_AD1CH6IF = 0;
}