Part Number: MSP430FR2111
Hi,
I'm running a project on the following configuration: MSP430FR2111, driverlib 2.80.0.01, CCS 8.1.0.00011, optimization level 4 in favor of size
I initialize the ADC :
ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_1024_CYCLES, ADC_MULTIPLESAMPLESENABLE);
And I sample some pretty stable voltage every 1 Sec - I get pretty stable readout ~540 ADC counts.
As the voltage is pretty stable and output impedance is low (decoupling capacitor), I'vet tried to reduce sample&hold time
Now, When I initialize with the sampling timer with any value other than ADC_CYCLEHOLD_512_CYCLES (even down to 4 cycles) I get approximately the same readout (~540)
BUT when I initialize it with ADC_CYCLEHOLD_512_CYCLES I receive an alternating readout: 415 - 670 - 415 -670 which on average is ~540 (the steady value)
As I have very limited code memory, I must use the highest optimization level which makes it a pain to debug. The basic flow is as follows:
- Every 1 sec -
- Configure ADC to sample channel 2: ADC_configureMemory(ADC_BASE, ADCINCH_2, ADC_VREFPOS_INT, ADC_VREFNEG_AVSS);
- Start single channel repeated conversion (channel 2): ADC_startConversion(ADC_BASE, ADC_REPEATED_SINGLECHANNEL);
- Within the ISR -
- I sum up ADC readout to a global array <<< This one I inspect in Memory view
- I do the summation for 4 times and then disable conversion ADC_disableConversions(ADC_BASE, true);
- I averaging the 4 samples sum and get an averaged readout on which I act
- If sampled channel == ADCINCH_2
- Configure ADC to sample channel 1: ADC_configureMemory(ADC_BASE, ADCINCH_1, ADC_VREFPOS_INT, ADC_VREFNEG_AVSS);
- Start single channel repeated conversion (channel 1): ADC_startConversion(ADC_BASE, ADC_REPEATED_SINGLECHANNEL);
- Repeat after 1 sec
What can be the cause of this super-awkward behavior? Is it an optimization issue? Why only for ADC_CYCLEHOLD_512_CYCLES ???
Any direction would be appreciated.
Thanks
#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR (void)
{
static uint8_t avgCycle = AVG_FACTOR; // 4
uint8_t source;
switch (__even_in_range(ADCIV,12)){
case 0: break; //No interrupt
case 2: break; //conversion result overflow
case 4: break; //conversion time overflow
case 6: break; //ADCHI
case 8: break; //ADCLO
case 10: break; //ADCIN
case 12: //ADCIFG0
//Automatically clears ADCIFG0 by reading memory buffer
source = ADCMCTL0 & ADCINCH;
Measurement[source] += ADC_getResults(ADC_BASE); // Gloabl. Inspected in Memory window
avgCycle--;
if(avgCycle == 0) { // avgCycle == 0 && source==0. End of sampling sequence
ADC_disableInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
ADC_disableConversions(ADC_BASE, true);
avgCycle = AVG_FACTOR;
Measurement[source] /= AVG_FACTOR;
// ......
if(source == ADCINCH_2) {
ADC_configureMemory(ADC_BASE, ADCINCH_1, ADC_VREFPOS_INT, ADC_VREFNEG_AVSS);
ADC_enableInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
ADC_startConversion(ADC_BASE, ADC_REPEATED_SINGLECHANNEL);
}
} // if avgCycle == 0
break; // case 12
} // switch __even_in_range()
LPM3_EXIT; // inside ISR exit LPM3
}
