3
\$\begingroup\$

I am trying to measure a power device's voltage using TI's MSP430. The voltage source is connected to A1 (i.e. P4) and ground (i.e. P1) on the target board.

Here is the relevant code:

ADC10CTL1 = INCH_1 + CONSEQ_0; //A1, single measurement
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR; //same as sample temperature sensor code
ADC10CTL1 &= ~ADC10DF; //setting binary format for ADC10MEM
ADC10CTL0 |= ENC + ADC10SC; //Sampling and conversion start
 __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
//read result in a uint8_t[2]
incomingVoltage[0] = ((uint8_t *)&ADC10MEM)[0]; //this is Least-significant-byte
incomingVoltage[1] = ((uint8_t *)&ADC10MEM)[1]; //this is most-significant-byte

I am having following problems:

  1. I am printing the ADC10MEM contents on the AP, and I see that the leading 6 bits of ADC10MEM are all 1, instead of 0. I am unable to get the reason for the same.

  2. If I consider only the last 10 bits of ADC10MEM, I can see that the value increases and decreases with rise and fall in voltage, but if I obtain Vin using the formula:

N = 1023 * ((Vin - VR- ) / (VR+ - VR-)), I do not get the correct value. (VR+ = 1.5V, VR- = 0V, as batteries power the target board) N: the value in ADC10MEM, in decimal

I am unable to find where I am going wrong. Do I have to enable the pin for analog input (ADC10AE0 |= 0x02), and set direction (P4DIR &= 0x00) as well?

Thanks!

EDIT 1: Vin Values: These are the ADC10MEM values I am getting, considering last 10 bits. Following calculations use Vr+ = 1.5, Vr- = 0. For input voltage 0.38V, N=1100000010 i.e. 770, and Vin=1.12. For input voltage 0.5V, N=1101010110 i.e. 854, and Vin=1.25. For input voltage 1V, N=1110101001 i.e. 937, and Vin = 1.37. For input voltage 1.45V, N=1111011000 i.e. 984, and Vin = 1.44. As I said, the value is increasing/decreasing with increase/decrease in input, but it isn't correct.

EDIT 2: Interrupts: I am modifying the sample temperature sensor code. I see

__bis_SR_register(LPM3_bits+GIE);  // LPM3 with interrupts enabled 

at the start of while(1) loop in linkTo()/main_ED.c, and there's

 __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled

after 'sampling and conversion start' and before 'read results'

EDIT 3: Code based on msp430x22x4_adc_10_02.c from TI's code samples

ADC10CTL1 = INCH_1 + CONSEQ_0;
ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE;
ADC10AE0 |= 0x02;
P4DIR |= 0x00;
ADC10CTL0 |= ENC + ADC10SC; //Sampling and conversion start

I am getting similar values even with this code.

\$\endgroup\$
14
  • \$\begingroup\$ What is the value of $V_{IN}$ you are trying to measure? \$\endgroup\$
    – MikeJ-UK
    Apr 13, 2011 at 15:27
  • \$\begingroup\$ what is FF22x4? \$\endgroup\$
    – markrages
    Apr 13, 2011 at 15:32
  • \$\begingroup\$ do you mean 430f22x4? you should not refer to pin numbers on a part with multiple pinouts. \$\endgroup\$
    – markrages
    Apr 13, 2011 at 15:32
  • \$\begingroup\$ are you sure there are no other interrupts enabled? \$\endgroup\$
    – markrages
    Apr 13, 2011 at 15:39
  • \$\begingroup\$ These are the ADC10MEM values I am getting, considering last 10 bits. Following calculations use Vr+ = 1.5, Vr- = 0. For input voltage 0.38V, N=1100000010 i.e. 770, and Vin=1.12. For input voltage 0.5V, N=1101010110 i.e. 854, and Vin=1.25. For input voltage 1V, N=1110101001 i.e. 937, and Vin = 1.37. For input voltage 1.45V, N=1111011000 i.e. 984, and Vin = 1.44. As I said, the value is increasing/decreasing with increase/decrease in input, but it isn't correct. \$\endgroup\$
    – Chaitanya
    Apr 13, 2011 at 15:40

1 Answer 1

1
\$\begingroup\$

This is the code that worked:

ADC10CTL1 = INCH_1 + CONSEQ_0;
ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE;
for (countDown = 240; countDown > 0; countDown--); //delay to allow references to settle
ADC10AE0 |= 0x02;
ADC10CTL0 |= ENC + ADC10SC; //Sampling and conversion start
__bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
result = ADC10MEM; //result is a int
incomingVoltage[0] = result&0xFF; //incoming voltage is an array of uint8_t, send it to AP
incomingVoltage[1] = (result>>8)&0xFF; //this and previous line is similar to temperature sensing code sample

Thanks for the help!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.