EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

ADC converter

Started by plutoterraneo October 2, 2003
I use ADC to convert 2 channels analogs.
I use internal Vref at 2.5 volt.
I use a repeat sequence of channels.
If the input channal is 1.25 volt I don't measure 0x7FF, but 0x7BC, 
there is a error! Why? 

My code is:
// external clock = 5.0688 MHz
#include 
void main(void)
{ 
unsigned char i;
// setup WDT
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
// setup clock CPU
BCSCTL1|=XTS; // LFXT1 = high frequency
do {
IFG1 &= ~OFIFG; // clear OSCFault flag
for (i=0xff;i>0;i--); 
} while((IFG1 & OFIFG)!=0); 
BCSCTL2|=SELM_3|SELS; 
_BIS_SR(SCG0); 
// setup porte I/O
P1DIR = 0xFF; // P1.0-1.7 output
P2DIR = 0xFF; // P2.0-2.7 output
P3DIR |= 0x07; // P3.0, 3.1, 3.2 output
P6SEL = 0x03; // pin 6.0, 6.1 analogs channels
// setup ADC 
ADC12CTL0 = ADC12ON + REFON + REF2_5V + MSC + SHT0_0; 
ADC12CTL1 = CONSEQ_3 + ADC12SSEL_1 + ADC12DIV_7 + SHP; 
ADC12MCTL0 = INCH_0 + SREF_1; 
ADC12MCTL1 = INCH_1 + SREF_1+EOS; 
ADC12IE = 0x02; 
ADC12CTL0 |= ENC ; 
_EINT(); // Enable interrupts 
ADC12CTL0 |= ADC12SC; // start conversion 

for (;;) 
{ }
}
// Timer ADC interrupt service routine
interrupt[ADC_VECTOR] void ADC12 (void)
{
static unsigned int a=0,b=0;
a = ADC12MEM0; 
b = ADC12MEM1; 
P1OUT = a & 0x0F;
P2OUT = a >> 4; 
}








Beginning Microcontrollers with the MSP430

I didn't check your code, but what comes immediately to my mind is 
that the internal ref has max +/-4% error. The error in your 
measurement is -3.3%.
Also, when you switch the internal reference on, you have to wait the 
referece settling time, which depends largely on the capacitor on 
Vref+ (if you have any).
(See slas272e, p. 33.)

Maybe this is your problem.

Wolfgang




--- In msp430@msp4..., "plutoterraneo" <enrico.terraneo@l...> 
wrote:
> I use ADC to convert 2 channels analogs.
> I use internal Vref at 2.5 volt.
> I use a repeat sequence of channels.
> If the input channal is 1.25 volt I don't measure 0x7FF, but 0x7BC, 
> there is a error! Why? 
> 
> My code is:
> // external clock = 5.0688 MHz
> #include 
> void main(void)
> { 
> unsigned char i;
> // setup WDT
> WDTCTL = WDTPW + WDTHOLD; // Stop WDT
> // setup clock CPU
> BCSCTL1|=XTS; // LFXT1 = high frequency
> do {
> IFG1 &= ~OFIFG; // clear OSCFault flag
> for (i=0xff;i>0;i--); 
> } while((IFG1 & OFIFG)!=0); 
> BCSCTL2|=SELM_3|SELS; 
> _BIS_SR(SCG0); 
> // setup porte I/O
> P1DIR = 0xFF; // P1.0-1.7 output
> P2DIR = 0xFF; // P2.0-2.7 output
> P3DIR |= 0x07; // P3.0, 3.1, 3.2 output
> P6SEL = 0x03; // pin 6.0, 6.1 analogs channels
> // setup ADC 
> ADC12CTL0 = ADC12ON + REFON + REF2_5V + MSC + SHT0_0; 
> ADC12CTL1 = CONSEQ_3 + ADC12SSEL_1 + ADC12DIV_7 + SHP; 
> ADC12MCTL0 = INCH_0 + SREF_1; 
> ADC12MCTL1 = INCH_1 + SREF_1+EOS; 
> ADC12IE = 0x02; 
> ADC12CTL0 |= ENC ; 
> _EINT(); // Enable interrupts 
> ADC12CTL0 |= ADC12SC; // start conversion 
> 
> for (;;) 
> { }
> }
> // Timer ADC interrupt service routine
> interrupt[ADC_VECTOR] void ADC12 (void)
> {
> static unsigned int a=0,b=0;
> a = ADC12MEM0; 
> b = ADC12MEM1; 
> P1OUT = a & 0x0F;
> P2OUT = a >> 4; 
> }


Plus you can always bring the ref. outside and actually measure it.!

Karl.
  ----- Original Message ----- 
  From: Wolfgang Reich 
  To: msp430@msp4... 
  Sent: Thursday, October 02, 2003 7:43 AM
  Subject: [msp430] Re: ADC converter


  I didn't check your code, but what comes immediately to my mind is 
  that the internal ref has max +/-4% error. The error in your 
  measurement is -3.3%.
  Also, when you switch the internal reference on, you have to wait the 
  referece settling time, which depends largely on the capacitor on 
  Vref+ (if you have any).
  (See slas272e, p. 33.)

  Maybe this is your problem.

  Wolfgang




  --- In msp430@msp4..., "plutoterraneo" <enrico.terraneo@l...> 
  wrote:
  > I use ADC to convert 2 channels analogs.
  > I use internal Vref at 2.5 volt.
  > I use a repeat sequence of channels.
  > If the input channal is 1.25 volt I don't measure 0x7FF, but 0x7BC, 
  > there is a error! Why? 
  > 
  > My code is:
  > // external clock = 5.0688 MHz
  > #include 
  > void main(void)
  > { 
  > unsigned char i;
  > // setup WDT
  > WDTCTL = WDTPW + WDTHOLD; // Stop WDT
  > // setup clock CPU
  > BCSCTL1|=XTS; // LFXT1 = high frequency
  > do {
  > IFG1 &= ~OFIFG; // clear OSCFault flag
  > for (i=0xff;i>0;i--); 
  > } while((IFG1 & OFIFG)!=0); 
  > BCSCTL2|=SELM_3|SELS; 
  > _BIS_SR(SCG0); 
  > // setup porte I/O
  > P1DIR = 0xFF; // P1.0-1.7 output
  > P2DIR = 0xFF; // P2.0-2.7 output
  > P3DIR |= 0x07; // P3.0, 3.1, 3.2 output
  > P6SEL = 0x03; // pin 6.0, 6.1 analogs channels
  > // setup ADC 
  > ADC12CTL0 = ADC12ON + REFON + REF2_5V + MSC + SHT0_0; 
  > ADC12CTL1 = CONSEQ_3 + ADC12SSEL_1 + ADC12DIV_7 + SHP; 
  > ADC12MCTL0 = INCH_0 + SREF_1; 
  > ADC12MCTL1 = INCH_1 + SREF_1+EOS; 
  > ADC12IE = 0x02; 
  > ADC12CTL0 |= ENC ; 
  > _EINT(); // Enable interrupts 
  > ADC12CTL0 |= ADC12SC; // start conversion 
  > 
  > for (;;) 
  > { }
  > }
  > // Timer ADC interrupt service routine
  > interrupt[ADC_VECTOR] void ADC12 (void)
  > {
  > static unsigned int a=0,b=0;
  > a = ADC12MEM0; 
  > b = ADC12MEM1; 
  > P1OUT = a & 0x0F;
  > P2OUT = a >> 4; 
  > }


        
             
       
       

  .



   





As Wolfgang and Karl suggest it is probably irrelevant to supply your 
code. It is unlikely that this is a coding error. First of all sum all 
of the errors in your system, reference error, ground error, conversion 
error etc, adn therein will lie you problem. Your reading is actually 
within specification. You may also have other issues. Some common 
problems are:-

1. Your Analog Ground is not adequately isolated from digital ground, 
and carries digital noise.

2. You're analog and digital grounds have a resistive path between them, 
thus analog ground is level shifted.

3. Your capacitor on Vref is too small, anfd Vref is either inaccurate, 
or unstable or both.

4. You are not allowing adequate sample time, this looks possible as you 
have set SHT0 to just 4 ADC12clks.

5. Your source impedance is too high, resulting in an inaccurate sample, 
again sample time is too short.

Check these out first.

Al

plutoterraneo wrote:
> I use ADC to convert 2 channels analogs.
> I use internal Vref at 2.5 volt.
> I use a repeat sequence of channels.
> If the input channal is 1.25 volt I don't measure 0x7FF, but 0x7BC, 
> there is a error! Why? 
> 
> My code is:
> // external clock = 5.0688 MHz
> #include 
> void main(void)
> { 
> unsigned char i;
> // setup WDT
> WDTCTL = WDTPW + WDTHOLD; // Stop WDT
> // setup clock CPU
> BCSCTL1|=XTS; // LFXT1 = high frequency
> do {
> IFG1 &= ~OFIFG; // clear OSCFault flag
> for (i=0xff;i>0;i--); 
> } while((IFG1 & OFIFG)!=0); 
> BCSCTL2|=SELM_3|SELS; 
> _BIS_SR(SCG0); 
> // setup porte I/O
> P1DIR = 0xFF; // P1.0-1.7 output
> P2DIR = 0xFF; // P2.0-2.7 output
> P3DIR |= 0x07; // P3.0, 3.1, 3.2 output
> P6SEL = 0x03; // pin 6.0, 6.1 analogs channels
> // setup ADC 
> ADC12CTL0 = ADC12ON + REFON + REF2_5V + MSC + SHT0_0; 
> ADC12CTL1 = CONSEQ_3 + ADC12SSEL_1 + ADC12DIV_7 + SHP; 
> ADC12MCTL0 = INCH_0 + SREF_1; 
> ADC12MCTL1 = INCH_1 + SREF_1+EOS; 
> ADC12IE = 0x02; 
> ADC12CTL0 |= ENC ; 
> _EINT(); // Enable interrupts 
> ADC12CTL0 |= ADC12SC; // start conversion 
> 
> for (;;) 
> { }
> }
> // Timer ADC interrupt service routine
> interrupt[ADC_VECTOR] void ADC12 (void)
> {
> static unsigned int a=0,b=0;
> a = ADC12MEM0; 
> b = ADC12MEM1; 
> P1OUT = a & 0x0F;
> P2OUT = a >> 4; 
> }
> 
> 
> 
> 
> 
> 
> 
> 
> 
> .
> 
>  
> 
> ">http://docs.yahoo.com/info/terms/ 
> 
> 
> 



The 2024 Embedded Online Conference