Other Parts Discussed in Thread: MSP430F2274, MSP430G2553, MSP430G2231
Here's a fact: the code quoted everywhere for sampling the ADC10 (e.g. in Grace) does not work 100%:
// ADC Start Conversion - Software trigger
ADC10CTL0 |= ADC10SC;
// Loop until ADC10IFG is set indicating ADC conversion complete
while ((ADC10CTL0 & ADC10IFG) == 0);
// Read ADC conversion result from ADC10MEM
ADC_Conversion_Result = ADC10MEM;
At least, with this setup: MSP430F2274, 1MHz MCLK, ADC running from ADC10SC/6, (ADC10SC also for trigger source and sample rate clock), S/H time 64x clocks.
The code that sleeps the processor and wake on interrupt does work:
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled value = ADC10MEM;/**
* sample an ADC channel and return the result.
*/
int readADC( int channel )
{
int i;
ADC10CTL0 &= ~ENC; //disable so we can modify control bits
ADC10CTL1 &= 0x0FFF; //clear input source
ADC10CTL1 |= channel; //select new input
ADC10CTL0 |= ENC | ADC10SC; // Sampling and conversion start
for( i = 0; i < 1000; i++); // wait for flag since we're running on a slow clock, can't check immediately
while (!(ADC10CTL0 & ADC10IFG));
return ADC10MEM;
}
If you take out the delay loop, you will always get ADC10MEM == 0.
My theory is that ADC10SC is slow compared to MCLK and the ADC10IFG is taking a while to set after conversion start, and is being rushed past and missed unless you delay a bit.
Note: this routine is 'blocking', that is it'll sit there and make your whole program wait til the conversion is done. For my application that's acceptable.
Perhaps someone from TI can comment.
Regards,
Marc