This thread has been locked.

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.

Problem with sd16_A module of MSP430FG479 for negative voltage levels

Other Parts Discussed in Thread: MSP430FG479

Hello friends,

I would like to know if someone has already had this same problem with the MSP430FG479 SD16_A module.
I'm using this device to read analog POSITIVE voltage levels on channels A0+ and A1+ (both A0- and A1- are connected to AGND) from 0.0 V to 0.6 V and they are working fine. I'm also using another channel, A2+ (again with A2- connected to AGND) to read NEGATIVE and POSITIVE voltage levels but this is not working properly, because when I put negative signals below -330 mV DC on the A2+ pin, the error between the read and the measured (with a HP 3468A voltmeter) voltage levels seems to increase. In fact, the more negative the signal, the larger is the error of the voltage measured. For example:


1) For -500 mV applied to the A0+ pin, the 450-point averaged (signed) SD16MEM0 reads -21762, which means -398 mV;

2) For -400 mV applied to the A0+ pin, the 450-point averaged (signed) SD16MEM0 reads -20266, which means -371 mV;

3) For -350 mV applied to the A0+ pin, the 450-point averaged (signed) SD16MEM0 reads -18726, which means -343 mV;

4) For -300 mV applied to the A0+ pin, the 450-point averaged (signed) SD16MEM0 reads -16518, which means -302 mV;


For less negative values and every positive value applied to A0+ the measured values are in conformity with that measured with the voltmeter.

I also tried this same test with A1+ and A2+ and the results were pretty much the same, and I also downloaded and ran all the code examples for this device on it, but the results were still the same.
The routine I'm using to run these tests is as follows:

#include <msp430fg479.h>
#include <intrinsics.h>


volatile unsigned int i;
signed long int teste[450];


//=============================================================================
// Clock Conifg
//=============================================================================

void config_clock_xtal (void)
{
SCFQCTL = 29; // (N+1) x 32768 = fDCO
SCFI0 |= FN_2; // fDCOCLK = 1.4-12MHz
FLL_CTL0 |= XCAP14PF;
}

//=============================================================================

//=============================================================================
// SD16_A Conifg
//=============================================================================

void config_ad (void)
{
P6SEL = BIT0 + BIT1 + BIT3 + BIT4;
P1SEL2 &= ~(BIT6 + BIT7);
SD16AE |= BIT6 + BIT7;

SD16CTL |= SD16DIV_0 + SD16SSEL_1 + SD16REFON;
SD16CCTL0 |= SD16BUF_3 + SD16OSR_128;
}

//=============================================================================


//=============================================================================
// Read channel A0
//=============================================================================

void read_A0 (void)
{

SD16INCTL0 |= SD16INCH_0 + SD16GAIN_1;
SD16CCTL0 |= SD16UNI;
SD16CCTL0 &= ~SD16DF;
SD16CCTL0 |= SD16SC;

for (i=0; i<450; i++)
{
while (!(SD16CCTL0 & SD16IFG));
teste[i] = SD16MEM0;
}

SD16CCTL0 &= ~SD16SC;
SD16INCTL0 &= ~SD16INCH_0;

}

//=============================================================================

//=============================================================================
// Read channel A1
//=============================================================================

void read_A1 (void)
{

SD16INCTL0 |= SD16INCH_1 + SD16GAIN_1;
SD16CCTL0 |= SD16UNI;
SD16CCTL0 &= ~SD16DF;
SD16CCTL0 |= SD16SC;

for (i=0; i<450; i++)
{
while (!(SD16CCTL0 & SD16IFG));
teste[i] = SD16MEM0;
}

SD16CCTL0 &= ~SD16SC;
SD16INCTL0 &= ~SD16INCH_1;

}

//=============================================================================

//=============================================================================
// Read channel A2
//=============================================================================

void read_A2 (void)
{

SD16INCTL0 |= SD16INCH_2 + SD16GAIN_1;
SD16CCTL0 &= ~SD16UNI;
SD16CCTL0 |= SD16DF + SD16BUF_0;
SD16CCTL0 |= SD16SC;

for (i=0; i<450; i++)
{
while (!(SD16CCTL0 & SD16IFG));
teste[i] = (signed)SD16MEM0;
}

SD16CCTL0 &= ~SD16SC;
SD16INCTL0 &= ~SD16INCH_2;

}


//=============================================================================

//=============================================================================
// MAIN
//=============================================================================

void main (void)
{

WDTCTL = WDTPW + WDTHOLD; // Stop WDT

config_clock_xtal ();

config_ad ();

while (1)
{

read_A0 ();
read_A1 ();
read_A2 ();
}

}

//=============================================================================
// END
//=============================================================================

Along with the MSP430FG479 SD16_A module, voltage measurements are being made with a HP 3468A multimeter and these voltage levels are being applied to it with a Agilent 33220A arbitrary waveform generator.
I think I've tried everything and the results are still the same, so please if someone else has already faced this problem share your experience.


Thanks!


Alex
State University of Campinas
Campinas, SP - Brazil

  • This is expected behavor. If you read datasheet then you would notice that "Absolute Maximum voltage applied to any pin (see Note 2) --0.3 V to VCC + 0.3 V". Also in SD16_A chapter says that analog input range specified is AVSS-0.1V to AVCC. So you shall not be trying to measure voltages more than -0.1V below AVSS/GND. Other option would be level shifting of input signal so it falls into ADC input range.

  • This is 2nd post because something weird happened with first. In short: you shall read datasheet where you will see that absolute maximum voltage applied for pin is AVSS-0.3V and SD16 can measure signals down to AVSS-0.1V. Solution for you is: to shif input signal into _valid_ ADC input range.
  • Hello Ilmars,
    Thank you very much for the help.
    Regards,
    Alex
  • Be my guest. Forgot to say that applying voltages outside absolute maximum range can damage whole chip or input pin/port. So you shall check that your chip is fine after you did something like this:
    >>1) For -500 mV applied to the A0+ pin, the 450-point averaged (signed) SD16MEM0 reads -21762, which means -398 mV;