Part Number: MSP430FR5994
I have a problem with a system that is powered by a 3.6V LiSOCl2 lithium cell. These batteries sometimes have the strange behaviour that they have a low capacity although their voltage is above the cutoff level. The system is performing a ratiometric measurement of a resistive sensor against a reference sensor with an external 2-channel ADC. If the battery has the mentioned problem the voltage will fall during the measurement of the two resistors (the 2 ADC channels) which causes a big measurement error. To detect this error I am measuring the battery voltage after the conversion of each channel with the ADC12 BATTMAP input and check if they are nearly equal. But from time to time this values differ significantly although the voltage is stable between the two conversions. Sometimes more than 100 AD steps. I guess it must be a kind of timing problem but I can't find the reason
bool batFlag = false;
void ADC12_init(void)
{
while (Ref_A_isRefGenBusy(ADC12_B_BASE));
REFCTL0 |= REFVSEL_1 | REFON; // 2,0 V
ADC12_B_configureMemoryParam configureMemoryParam = {0};
configureMemoryParam.memoryBufferControlIndex = ADC12_B_MEMORY_0;
configureMemoryParam.inputSourceSelect = ADC12_B_INPUT_BATMAP;
configureMemoryParam.refVoltageSourceSelect = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS;
configureMemoryParam.endOfSequence = ADC12_B_NOTENDOFSEQUENCE;
configureMemoryParam.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE;
configureMemoryParam.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
ADC12_B_initParam initParam = {0};
initParam.sampleHoldSignalSourceSelect = ADC12_B_SAMPLEHOLDSOURCE_SC;
initParam.clockSourceSelect = ADC12_B_CLOCKSOURCE_ADC12OSC; // = 5 MHz MODOSC / ALT: ADC12_B_CLOCKSOURCE_ACLK _MCLK _SMCLK
initParam.clockSourceDivider = ADC12_B_CLOCKDIVIDER_5; // -> 1 MHz ALT: ADC12_B_CLOCKDIVIDER_1;
initParam.clockSourcePredivider = ADC12_B_CLOCKPREDIVIDER__1;
initParam.internalChannelMap = ADC12_B_BATTMAP; // Interner Kanal: Spannungsteiler Versorgungsspannung (1/2 AVCC
ADC12_B_init(ADC12_B_BASE, &initParam);
ADC12_B_enable(ADC12_B_BASE);
ADC12_B_setResolution(ADC12_B_BASE, ADC12_B_RESOLUTION_12BIT); //ADC12_B_RESOLUTION_8BIT);
ADC12_B_setAdcPowerMode(ADC12_B_BASE, ADC12_B_LOWPOWERMODE);
ADC12_B_setupSamplingTimer(ADC12_B_BASE,
ADC12_B_CYCLEHOLD_512_CYCLES,
ADC12_B_CYCLEHOLD_512_CYCLES,
ADC12_B_MULTIPLESAMPLESDISABLE);
ADC12_B_configureMemory(ADC12_B_BASE, &configureMemoryParam);
ADC12_B_enableInterrupt(ADC12_B_BASE, ADC12_B_IE0, 0, 0);
while(!(REFCTL0 & REFGENRDY));
}
void ADC12_measure(void)
{
ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_MEMORY_0, ADC12_B_SINGLECHANNEL);
}
uint16_t ADC12_getResult(void)
{
return ADC12_B_getResults(ADC12_B_BASE, ADC12_B_MEMORY_0);
}
#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR(void)
{
switch (__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG))
{
case ADC12IV_ADC12IFG0:
batFlag = true;
__bic_SR_register_on_exit(LPM0_bits | GIE); // Exit CPU, clear interrupts
break;
default: break;
}
}
The main thread will check if the batFlag is true and will call the ADC12_getResult function and go back to LPM0. The measurement will be triggered by the main thread with ADC12_measure() after the conversion of the external ADC. I have already tried to lower the clock speed and to increase sampling times of the ADC with no effect. In the fastest measurement mode the battery voltage will be measured 6 times per second. What could be the problem?