Part Number: MSP430I2020
Other Parts Discussed in Thread: MSP430WARE
Hi! I'm using MSP430I2020's analog-to-digital converter in single ended configuration to read two analog voltages from a sensor.
I've connected the sensor outputs to A0.0+ and A1.0+, respectively. A0.0- and A1.0- are connected to GND. This is the code I'm using:
void SD24_initialize(void)
{
// Internal ref
SD24_init(SD24_BASE, SD24_REF_INTERNAL);
//Group with Channel 0
SD24_initConverterAdvancedParam param = {0};
param.converter = SD24_CONVERTER_0;
param.conversionMode = SD24_CONTINUOUS_MODE;
param.groupEnable = SD24_GROUPED;
param.inputChannel = SD24_INPUT_CH_ANALOG;
param.dataFormat = SD24_DATA_FORMAT_2COMPLEMENT;
param.interruptDelay = SD24_FOURTH_SAMPLE_INTERRUPT;
param.oversampleRatio = SD24_OVERSAMPLE_256;
param.gain = SD24_GAIN_1;
SD24_initConverterAdvanced(SD24_BASE, ¶m);
//Group with Channel 1
param.converter = SD24_CONVERTER_1;
param.conversionMode = SD24_CONTINUOUS_MODE;
param.groupEnable = SD24_NOT_GROUPED;
param.inputChannel = SD24_INPUT_CH_ANALOG;
param.dataFormat = SD24_DATA_FORMAT_2COMPLEMENT;
param.interruptDelay = SD24_FOURTH_SAMPLE_INTERRUPT;
param.oversampleRatio = SD24_OVERSAMPLE_256;
param.gain = SD24_GAIN_1;
SD24_initConverterAdvanced(SD24_BASE, ¶m);
// Enable interrupt
SD24_enableInterrupt(SD24_BASE, SD24_CONVERTER_1, SD24_CONVERTER_INTERRUPT);
// Delay ~200us for 1.2V ref to settle
__delay_cycles(3200);
}
void SD24_read(float* op1, float* op2)
{
// Start conversion
SD24_startConverterConversion(SD24_BASE, SD24_CONVERTER_1);
// Enter LPM0 w/ interrupts
__bis_SR_register(LPM0_bits | GIE);
SD24_stopConverterConversion(SD24_BASE, SD24_CONVERTER_1);
for (i = 0; i < NUM_OF_RESULTS; i++)
{
Ch0results_float[i] = Int24BitTwoComplementToSignedInt(Ch0results[i]) * LSB * 2.0;
Ch1results_float[i] = Int24BitTwoComplementToSignedInt(Ch1results[i]) * LSB * 2.0;
}
if (NUM_OF_RESULTS > 1) // Mean value
{
float sum0 = 0, sum1 = 0;
for (i = 0; i < NUM_OF_RESULTS; i++)
{
sum0 += Ch0results_float[i];
sum1 += Ch1results_float[i];
}
*op1 = sum0 / NUM_OF_RESULTS;
*op2 = sum1 / NUM_OF_RESULTS;
}
else
{
*op1 = Ch0results_float[0];
*op2 = Ch1results_float[0];
}
}
int32_t Int24BitTwoComplementToSignedInt(uint32_t val)
{
return (0x800000 & val ? (int)(0x7FFFFF & val) - 0x800000 : val);
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=SD24_VECTOR
__interrupt void SD24_ISR(void) {
#elif defined(__GNUC__)
void __attribute__ ((interrupt(SD24_VECTOR))) SD24_ISR (void) {
#else
#error Compiler not supported!
#endif
switch (__even_in_range(SD24IV,SD24IV_SD24MEM3)) {
case SD24IV_NONE: break;
case SD24IV_SD24OVIFG: break;
case SD24IV_SD24MEM0: break;
case SD24IV_SD24MEM1:
// Save CH0 results (clears IFG)
Ch0results[i] = SD24_getResults(SD24_BASE, SD24_CONVERTER_0);
// Save CH1 results (clears IFG)
Ch1results[i] = SD24_getResults(SD24_BASE, SD24_CONVERTER_1);
i++;
if (i == NUM_OF_RESULTS) {
i = 0;
__bic_SR_register_on_exit(LPM0_bits); // Wake up
}
break;
case SD24IV_SD24MEM2: break;
case SD24IV_SD24MEM3: break;
default: break;
}
}
The values read by the ADC are half than those measured with a voltmeter. So I've multiplied them with 2.
My questions: is it expected for SD24 to return half values when working in single ended configuration, with 2's complement output format? Am I reading the values correctly?
