adc7scan1.c - Samples 7 channels sequentially with automatic channel scanning (only for PIC24 CPUs without DMA)¶
Performs a basic config of the ADC and samples seven channels sequentially with automatic channel scanning. ADC values are 12-bit results. Samples are obtained continuously. Uses ADC completion interrupts to get values from ADCxBUFn registers. Main routine fetches the “latest” values from memory.
Conversion results are printed to screen to match adc2pots1.c project (HEX values and voltages are printed.) This is only for PIC24 CPUs without DMA.
#include "pic24_all.h"
#include "stdio.h"
#ifdef _DMA0IF
# warning "This processor selection has the DMA module; this code example is incompatible with a PIC24 CPU that has DMA."
int main(void) {
return 0;
}
#else
#define CONFIG_LED2() CONFIG_RB0_AS_DIG_OUTPUT()
#define LED2 _LATB0
uncomment the next line to setup this project for a 12-bit ADC
#define USE_12BIT_ADC
#ifdef USE_12BIT_ADC
#define ADC_LEN 12
#define ADC_NSTEPS 4096
#define ADC_12BIT_FLAG 1
#else
#define ADC_LEN 10
#define ADC_NSTEPS 1024
#define ADC_12BIT_FLAG 0
#endif
volatile uint16_t au16_buffer[16];
volatile uint8_t u8_waiting;
/***
*** HERE IS THE CODE!
***
***/
void _ISR _ADC1Interrupt (void) {
uint8_t u8_i;
uint16_t* au16_adcHWBuff = (uint16_t*) &ADC1BUF0;
for ( u8_i=0; u8_i<16; u8_i++) {
au16_buffer[u8_i] = au16_adcHWBuff[u8_i];
} //end for()
u8_waiting = 0; // signal main() that data is ready
_AD1IF = 0; //clear the interrupt flag
toggle an LED so we can measure how often ADC IRQs are coming in
LED2 = !LED2;
}
int main (void) {
uint8_t u8_i;
uint16_t u16_pot;
float f_pot;
configBasic(HELLO_MSG);
make RA0/AN0/VREF+ a digital input to kill the pullup and set the TRISA bit, then make it ANALOG so the ADC will work
CONFIG_RA0_AS_ANALOG();
CONFIG_RA1_AS_ANALOG();
CONFIG_RB2_AS_ANALOG();
CONFIG_RB3_AS_ANALOG();
CONFIG_RB14_AS_ANALOG();
CONFIG_RB13_AS_ANALOG();
CONFIG_RB12_AS_ANALOG();
CONFIG_LED2();
configADC1_AutoScanIrqCH0( ADC_SCAN_AN0 | ADC_SCAN_AN1 | ADC_SCAN_AN4 | \
ADC_SCAN_AN5 | ADC_SCAN_AN10 | ADC_SCAN_AN11 | ADC_SCAN_AN12,
31, ADC_12BIT_FLAG);
wait for first conversion to finish before proceeding
while ( !AD1CON1bits.DONE) {};
while (1) {
while (u8_waiting) {}; // wait for valid data in ISR
u8_waiting = 0;
for ( u8_i=0; u8_i<16; u8_i++) {
u16_pot = au16_buffer[u8_i];
f_pot = 3.3 / ADC_NSTEPS * u16_pot;
printf("r");
if (u8_i < 10) outChar( '0'+u8_i );
else outChar( 'A'-10+u8_i );
printf(":0x%04X=%1.3fV ", u16_pot, (double) f_pot );
if ((u8_i % 4) == 3) printf("\n");
} //end for()
printf("\n");
doHeartbeat();
DELAY_MS(1500);
} //endof while()
} // endof main()
#endif