If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

• Resolved

# MSP430F2122: MSP430F2132

Part Number: MSP430F2122

Good morning,

The ADC10 is not always supplying reliable results in the program I am currently developing. I am trying to monitor five analog voltages critical to the operation of the hardware. The values returned from A0 through A4 appear to be accurate except for A2. The value returned from this channel if always in the range of 10 to 20 counts when its count should be about 350, depending on the values of A0 and A1. These values are typically in the range of 650 to 800 and A2 should be about half the value of the other two. I have verified the analog input to the A2 pin is correct so I am puzzled at this result, especially since I have tested 10 to 12 different identical cards with the same result. I have used code similar to the attachments below in other designs with good results so I'm not sure what's wrong with my code this go-around.

Regards, Harvey

Initialization Code:

//
// These bits select the channel for a single-conversion sequence, beginning with the highest channel.
//
// Analog to Digital Converter (ADC) initialization.

ADC10AE0 |= 0x1F; // Set P3.0 and P2.4 through P2.0 pins as inputs to ADC.
ADC10CTL1 = INCH_4 + ADC10DIV_7 + CONSEQ_1; // Select maximum channel number in sequence (A5)

Data Capture Code:

{
/*
case Acquire_A5: // Analog input A5 - spare analog, currently assigned digital output UCLK.
Ch_A5[8] -= Ch_A5[ADC_POINTER]; // Subtract oldest sample from sum of all samples.
Ch_A5[ADC_POINTER] = Analog_data; // Save latest sample.

Analog5 = Ch_A5[8] >> 3; // Average of spare input A5 = sum/8.

break;
*/
Ch_A4[8] -= Ch_A4[ADC_POINTER]; // Subtract oldest sample from sum of all samples.
Ch_A4[ADC_POINTER] = Analog_data; // Save latest sample.

VREF = Ch_A4[8] >> 3; // Ch A4 - 777, Average voltage of the reference.

break;

case Acquire_A3: // Analog input A3 - I_Sns_Volt - Current into or out of the cell string.
Ch_A3[8] -= Ch_A3[ADC_POINTER]; // Subtract oldest sample from sum of all samples.
Ch_A3[ADC_POINTER] = Analog_data - Ipwr_Offset; // Save latest sample less the sensor offset.

if( ( Ch_A3[ADC_POINTER] < I_Maximum_Neg ) || ( Ch_A3[ADC_POINTER] > I_Maximum_Pos ) ) {
P1OUT &= ~Str_En; // Disconnect the cell string.
Over_Current_Timer = 34; // Give the batteries a chance to cool before allowing a restart.

I_Monitor_state = I_Mon_Max; // Absolute maximum exceeded, go wait for the current to go to zero.
}

I_Sense = Ch_A3[8] >> 3; // Ch A3 - Average current in or out of the cell string.

break;

Ch_A2[8] -= Ch_A2[ADC_POINTER]; // Subtract oldest sample from sum of all samples.
Ch_A2[ADC_POINTER] = Analog_data; // Save latest sample.

MID_STRING = Ch_A2[8] >> 3; // Ch A2 - Average voltage at cell string center tap.

break;

Ch_A1[8] -= Ch_A1[ADC_POINTER]; // Subtract oldest sample from sum of all samples.
Ch_A1[ADC_POINTER] = Analog_data; // Save latest sample.

CELL_POS = Ch_A1[8] >> 3; // Ch A1 - Average voltage on the top cell.

break;

Ch_A0[8] -= Ch_A0[ADC_POINTER]; // Subtract oldest sample from sum of all samples.
Ch_A0[ADC_POINTER] = Analog_data; // Save latest sample.

BATTERY_BUS = Ch_A0[8] >> 3; // Ch A0 - Average voltage on the battery bus.

// Housekeeping
//

if( ++ADC_POINTER > 7 ) { ADC_POINTER = 0; } // Point to next elements in the arrays.

if( Turn_On_Delay != ( Turn_On_Delay & System_Flags ) ) {
if( Real_Data_Count != 0) { Real_Data_Count--; }
else { ADC_Flags |= ADC_REAL; } // Tell the main loop data is now reliable.
}
}

ADC10CTL0 |= ( ENC + ADC10SC ); // Start new block conversion

if( Wait_Timer > 0 ) { Wait_Timer--; } // If not already 0, decrement the timer.

ADC_data_state = Acquire_A4; // Go get the next block of conversions
break;

default:
Gen_Msg_Flags1 |= Gen_Msg_0;
break;

} // End switch ***** Bottom of ADC Data State Machine *****
} // End if ADC_CC and PACKET_DEFAULT

Interrupt Service Routine:

/* -----------------------------------------
*
* DESCRIPTION:
* Conversion done for the ADC
* set variest process flags
*
*
* ------------------------------------------*/

{
}

• This seems straightforward enough.

It may be worth a quick audit of the rest of the code to make sure someone didn't accidentally "adopt" P2.2 for something else. (Keeping in mind: (1) ADC10AE0 only conditions the pin, it doesn't assign an alternate function in the usual sense (2) P2REN on the F2 series has an effect independent of any other configuration.)

It looks as though the A3 logic (just prior to the A2 conversion) may fiddle something on P1. Is there any chance that could have a side-effect?

• In reply to Bruce McKenney47378:

Good morning Bruce,

Thanks for the help.

I forgot that the JTAG lines are also used during debugging and was using TDO to enable FET switches to connect the ADC10 inputs to the signals being monitored. This was done to conserve power when the card is inactive but the toggling of TDO during debug was effecting the sampling of channel A2 more profoundly than the other channels.

Regards, Harvey

• In reply to Harvey Novak:

Hi Harvey,