adc4simul.c - Simultaneous sampling of 4 channels (only for PIC24 CPUs without DMA)ΒΆ
Simultaneously samples four channels and uses a timer used to trigger conversions. Ping-pong buffering is used. Conversion results are printed to screen. (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
setup an output to help us measure ADC IRQ responses
#define CONFIG_LED2() CONFIG_RB5_AS_DIG_OUTPUT()
#define LED2 _LATB5
#define ADC_LEN 10
#define ADC_NSTEPS 1024
#define ADC_12BIT_FLAG 0
uint16_t au16_buffer[8];
volatile uint16_t au16_sum[8];
volatile uint8_t u8_gotData;
/***
*** HERE IS THE CODE!
***
***/
void _ISR _ADC1Interrupt (void) {
static uint8_t u8_adcCount=64;
uint8_t u8_i;
uint16_t* au16_adcHWBuff = (uint16_t*) &ADC1BUF0;
If ADC is writing in the 2nd half of the buffer, so determine which half of the buffer is valid (and caused this interrupt), then fetch that half into our local array of ADC results.
if (AD1CON2 & ADC_ALT_BUF_STATUS_2) {
for ( u8_i=0; u8_i<8; u8_i++) {
au16_buffer[u8_i] += au16_adcHWBuff[u8_i];
} //end for()
} else {
for ( u8_i=8; u8_i<16; u8_i++) {
au16_buffer[u8_i-8] += au16_adcHWBuff[u8_i];
} //end for()
} // end if-else
_AD1IF = 0; //clear the interrupt flag
we got the data, so start the sampling process again
SET_SAMP_BIT_ADC1();
u8_adcCount--;
if (u8_adcCount==0) {
u8_adcCount = 64;
u8_gotData = 1;
for ( u8_i=0; u8_i<8; u8_i++) {
au16_sum[u8_i] = au16_buffer[u8_i];
au16_buffer[u8_i] = 0;
} //end for()
};
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;
uint32_t u32_ticks;
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_RB0_AS_ANALOG();
CONFIG_RB12_AS_ANALOG();
CONFIG_LED2();
u8_gotData = 0;
configure T2/T3 as 32-bit timer to trigger every 1/64 second
T3CONbits.TON = 0;
T2CONbits.TON = 0;
T2CON = T2_32BIT_MODE_ON | T2_PS_1_1 | T2_SOURCE_INT;
TMR3 = 0;
TMR2 = 0;
u32_ticks = usToU32Ticks(15625, getTimerPrescale(T2CONbits)) - 1; // # of ticks for 1/64 seconds
PR3 = u32_ticks>>16;
PR2 = u32_ticks & 0xFFFF;
T2CONbits.TON = 1;
configADC1_Simul4ChanIrq(12, ADC_CH123_POS_SAMPLEA_AN0AN1AN2, ADC_CONV_CLK_10Tcy );
SET_SAMP_BIT_ADC1();
while (1) {
while (!u8_gotData) {
doHeartbeat();
}
u8_gotData = 0;
for ( u8_i=0; u8_i<4; u8_i++) {
u16_pot = au16_sum[u8_i];
f_pot = (3.3 / 1023 / 64 ) * u16_pot;
printf("r");
outChar( '0'+u8_i );
printf(":0x%04X=%1.3fV ", u16_pot, (double) f_pot );
} //end for()
printf("\n");
} //endof while()
} // endof main()
#endif