15.5.7 Multiple Channels Scan
In Multiple Channels Scan Example, three channels are scanned. To scan these channels, they are triggered from 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 (150000000UL) // 150MHz
// Define the CCP1 timer frequency.
#define TIMER_FREQUENCY (100UL) // 1kHz
int main() {
// 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.
AD1CH2CONbits.MODE = 0;
// CCP1 Timer starts conversion (same for all scanned channels).
AD1CH2CONbits.TRG1SRC = 12;
// Select the AN1 analog input/pin for the channel #2.
AD1CH2CONbits.PINSEL = 1;
// Select signal sampling time (6.5 TADs = 81nS).
AD1CH2CONbits.SAMC = 3;
// CHANNEL 4
// Single conversion mode.
AD1CH4CONbits.MODE = 0;
// CCP1 Timer starts conversion (same for all scanned channels).
AD1CH4CONbits.TRG1SRC = 12;
// Select the AN2 analog input/pin for the channel #4.
AD1CH4CONbits.PINSEL = 2;
// Select signal sampling time (8.5 TADs = 106nS).
AD1CH4CONbits.SAMC = 4;
// CHANNEL 6
// Single conversion mode.
AD1CH6CONbits.MODE = 0;
// CCP1 Timer starts conversion (same for all scanned channels).
AD1CH6CONbits.TRG1SRC = 12;
// Select the AN3 analog input/pin for the channel #6.
AD1CH6CONbits.PINSEL = 3;
// Select signal sampling time (10.5 TADs = 131nS).
AD1CH6CONbits.SAMC = 5;
// Set ADC to RUN mode.
AD1CONbits.MODE = 2;
// 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(){
channel_2_an1 = AD1CH2DATA;
channel_4_an2 = AD1CH4DATA;
channel_6_an3 = AD1CH6DATA;
_AD1CH6IF = 0;
}