38.3.6 Selecting the Scanned Inputs

All available analog inputs can be configured for scanning. Class 2 and Class 3 inputs are sampled using the shared ADC module. A single conversion trigger source is selected for all of the inputs selected for scanning using the STRGSRC[4:0] bits (ADCCON1[20:16]). On each conversion trigger, the ADC module starts converting (in the natural priority) all inputs specified in the user-specified scan list (ADCCSS1 or ADCCSS2). For Class 2 and Class 3 inputs, the trigger initiates a sequential sample/conversion process in the natural priority order.

An analog input belongs to the scan if it is:
  • A Class 3 input. For Class 3 inputs, scan is the only mechanism for conversion.
  • A Class 2 input that has the scan trigger selected as the trigger source by selecting the STRIG option in the TRGSRCx[4:0] bits located in the ADCTRG1 through ADCTRG8 registers.

The trigger options available for scan are identical to those available for independent triggering of Class 2 inputs. Any Class 2 inputs that are part of the scan must have the STRIG option selected as their trigger source in the TRGSRCx[4:0] bits.

Note: The end-of-scan (EOS) is generated only if the last shared input conversion has completed. Until this condition is met, the scan sequence is still in effect. Therefore, the EOS Interrupt can be used for any scan sequence with any combination of input types.

The following code is an example for ADC scanning multiple inputs.

int main(int argc, char** argv) {
int result[3];

/* Configure ADCCON1 */
ADCCON1 = 0;              // No ADCCON1 features are enabled including: Stop-in-Idle, turbo,
// CVD mode, Fractional mode and scan trigger source. ADCCON1bits.SELRES = 3;   // ADC7 resolution is 12 bits
ADCCON1bits.STRGSRC = 1;  // Select scan trigger.

/* Configure ADCCON2 */
ADCCON2bits.SAMC = 5;     // ADC7 sampling time = 5 * TAD7
ADCCON2bits.ADCDIV = 1;   // ADC7 clock freq is half of control clock = TAD7

/* Initialize warm up time register */ ADCANCON = 0;
ADCANCONbits.WKUPCLKCNT = 5; // Wakeup exponent = 32 * TADx

/* Clock setting */
ADCCON3bits.ADCSEL = 0;       // Select input clock source
ADCCON3bits.CONCLKDIV = 1;    // Control clock frequency is half of input clock
ADCCON3bits.VREFSEL = 0;      // Select AVDD and AVSS as reference source

ADC0TIMEbits.ADCDIV = 1;      // ADC0 clock frequency is half of control clock = TAD0
ADC0TIMEbits.SAMC = 5;        // ADC0 sampling time = 5 * TAD0
ADC0TIMEbits.SELRES = 3;      // ADC0 resolution is 12 bits

/* Select analog input for ADC modules, no presync trigger, not sync sampling */ ADCTRGMODEbits.SH0ALT = 0;    // ADC0 = AN0

/* Select ADC input mode */
ADCIMCON1bits.SIGN0 = 0;      // unsigned data format ADCIMCON1bits.DIFF0 = 0;      // Single ended mode ADCIMCON1bits.SIGN8 = 0;      // unsigned data format ADCIMCON1bits.DIFF8 = 0;      // Single ended mode ADCIMCON1bits.SIGN40 = 0;     // unsigned data format ADCIMCON1bits.DIFF40 = 0;     // Single ended mode

/* Configure ADCGIRQENx */
ADCGIRQEN1 = 0;               // No interrupts are used. ADCGIRQEN2 = 0;

/* Configure ADCCSSx */
ADCCSS1 = 0;                 // Clear all bits
ADCCSS2 = 0;
ADCCSS1bits.CSS0 = 1;         // AN0 (Class 1) set for scan ADCCSS1bits.CSS8 = 1;         // AN8 (Class 2) set for scan ADCCSS2bits.CSS40 = 1;        // AN40 (Class 3) set for scan

/* Configure ADCCMPCONx */
ADCCMPCON1 = 0;               // No digital comparators are used. Setting the ADCCMPCONx ADCCMPCON2 = 0;               // register to '0' ensures that the comparator is disabled. ADCCMPCON3 = 0;               // Other registers are ‘don't care’.
ADCCMPCON4 = 0;
ADCCMPCON5 = 0; ADCCMPCON6 = 0;

/* Configure ADCFLTRx */
ADCFLTR1 = 0;                // No oversampling filters are used. ADCFLTR2 = 0;
ADCFLTR3 = 0; ADCFLTR4 = 0; ADCFLTR5 = 0; ADCFLTR6 = 0; 
/* Set up the trigger sources */
ADCTRG1bits.TRGSRC0 = 3;      // Set AN0 (Class 1) to trigger from scan source
ADCTRG3bits.TRGSRC8 = 3;      // Set AN8 (Class 2) to trigger from scan source
// AN40 (Class 3) always uses scan trigger source

/* Early interrupt */
ADCEIEN1 = 0;                // No early interrupt
ADCEIEN2 = 0;

/* Turn the ADC on */ ADCCON1bits.ON = 1;

/* Wait for voltage reference to be stable */
while(!ADCCON2bits.BGVRRDY); // Wait until the reference voltage is ready while(ADCCON2bits.REFFLT);   // Wait if there is a fault with the reference voltage

/* Enable clock to analog circuit */
ADCANCONbits.ANEN0 = 1;       // Enable the clock to analog bias ADC0
ADCANCONbits.ANEN7 = 1;       // Enable, ADC7

/* Wait for ADC to be ready */
while(!ADCANCONbits.WKRDY0);     // Wait until ADC0 is ready while(!ADCANCONbits.WKRDY7);     // Wait until ADC7 is ready

/* Enable the ADC module */
ADCCON3bits.DIGEN0 = 1;          // Enable ADC0
ADCCON3bits.DIGEN7 = 1;          // Enable ADC7

while (1) {
/* Trigger a conversion */ ADCCON3bits.GSWTRG = 1;

/* Wait the conversions to complete */
while (ADCDSTAT1bits.ARDY0 == 0);
/* fetch the result */
result[0] = ADCDATA0;

while (ADCDSTAT1bits.ARDY8 == 0);
/* fetch the result */
result[1] = ADCDATA8;

while (ADCDSTAT2bits.ARDY40 == 0);
/* fetch the result */
result[2] = ADCDATA40;

/*
* Process results here
*
*
*/
}
return (1);
}