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.

Reg - MSP430 ADC SW Support

Other Parts Discussed in Thread: MSP430F5529

Hi,

Can you review this code because it is not working for me. This is ADC Code, In this code i configured internal reference and perform repeated conversions on a single channel using "repeat-single-channel" mode.

#include <msp430.h>

#define Num_of_Results 8

volatile unsigned int results[Num_of_Results];
// Needs to be global in this
// example. Otherwise, the
// compiler removes it because it
// is not used for anything.

int main(void)
{
WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
P6SEL |= 0x01; // Enable A/D channel A0
REFCTL0 &= ~REFMSTR; // Reset REFMSTR to hand over control to
// ADC12_A ref control registers ADC12CTL0 =
ADC12CTL0 = ADC12ON+ADC12SHT02+ADC12REFON+ADC12REF2_5V; // Turn on ADC12, set sampling time
// set multiple sample conversion
ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2; // Use sampling timer, set mode
ADC12IE = 0x01; // Enable ADC12IFG.0
ADC12CTL0 |= ADC12ENC; // Enable conversions
ADC12CTL0 |= ADC12SC; // Start conversion

__bis_SR_register(LPM4_bits + GIE); // Enter LPM4, Enable interrupts
__no_operation(); // For debugger

}


#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
#else
#error Compiler not supported!
#endif
{
static unsigned char index = 0;

switch(__even_in_range(ADC12IV,34))
{
case 0: break; // Vector 0: No interrupt
case 2: break; // Vector 2: ADC overflow
case 4: break; // Vector 4: ADC timing overflow
case 6: // Vector 6: ADC12IFG0
results[index] = ADC12MEM0; // Move results
index++; // Increment results index, modulo; Set Breakpoint1 here

if (index == 8)
{
index = 0;
}
case 8: break; // Vector 8: ADC12IFG1
case 10: break; // Vector 10: ADC12IFG2
case 12: break; // Vector 12: ADC12IFG3
case 14: break; // Vector 14: ADC12IFG4
case 16: break; // Vector 16: ADC12IFG5
case 18: break; // Vector 18: ADC12IFG6
case 20: break; // Vector 20: ADC12IFG7
case 22: break; // Vector 22: ADC12IFG8
case 24: break; // Vector 24: ADC12IFG9
case 26: break; // Vector 26: ADC12IFG10
case 28: break; // Vector 28: ADC12IFG11
case 30: break; // Vector 30: ADC12IFG12
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}
}

I am reading wrong hex value @ ADC12MEM0.

For 1.93V at A0 I am reading 0x094F but I need read 0x0C5F. I dont know whether i configured internal reference correctly.

Thanks

Sathiyan

  • You need to set the ADC12MSC bit for repeated single channel conversions and include a small delay for the reference to start up before enabling and starting conversions. Furthermore, ADC12SREF_1 should be set to select VREF+ instead of AVCC.

    Regards,
    Ryan
  • Hi Ryan,

    Thanks for your reply.

    TI have any MSP430 example code for ADC repeated conversion configured with internal reference. 

    Thanks

    Sathiyan

  • I combined MSP430F55xx_adc_0[2&7].c to analyze your code, stating the exact MSP430 variant would be helpful.

    Regards,
    Ryan
  • I am not seen any attachment in your reply Ryan.

    Thanks
    Sathiyan
  • No attachments have been provided, examples can be found on the product's Tools & software page inside of the C examples folder: www.ti.com/.../slac300

    Regards,
    Ryan
  • Hi Ryan,

    Can you review this code? Please let me know if you find any mistake. I am electrical guy.

    #include <msp430.h>

    #define Num_of_Results 8

    volatile unsigned int results[Num_of_Results];
    // Needs to be global in this
    // example. Otherwise, the
    // compiler removes it because it
    // is not used for anything.

    int main(void)
    {
    volatile unsigned int i;
    WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
    P6SEL |= 0x01; // Enable A/D channel A0
    REFCTL0 &= ~REFMSTR; // Reset REFMSTR to hand over control to
    // ADC12_A ref control registers
    ADC12CTL0 = ADC12ON+ADC12SHT02+ADC12REFON+ADC12REF2_5V;
    // Turn on ADC12, Sampling time
    // On Reference Generator and set to
    // 2.5V
    ADC12CTL1 = ADC12SHP; // Use sampling timer
    ADC12MCTL0 = ADC12SREF_1; // Vr+=Vref+ and Vr-=AVss

    for ( i=0; i<0x30; i++); // Delay for reference start-up

    ADC12CTL0 |= ADC12ENC; // Enable conversions

    while (1)
    {
    ADC12CTL0 |= ADC12SC; // Start conversion
    while (!(ADC12IFG & BIT0));
    __no_operation(); // SET BREAKPOINT HERE

    }
    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    static unsigned char index = 0;

    switch(__even_in_range(ADC12IV,34))
    {
    case 0: break; // Vector 0: No interrupt
    case 2: break; // Vector 2: ADC overflow
    case 4: break; // Vector 4: ADC timing overflow
    case 6: // Vector 6: ADC12IFG0
    results[index] = ADC12MEM0; // Move results
    index++; // Increment results index, modulo; Set Breakpoint1 here

    if (index == 8)
    {
    index = 0;
    }
    case 8: break; // Vector 8: ADC12IFG1
    case 10: break; // Vector 10: ADC12IFG2
    case 12: break; // Vector 12: ADC12IFG3
    case 14: break; // Vector 14: ADC12IFG4
    case 16: break; // Vector 16: ADC12IFG5
    case 18: break; // Vector 18: ADC12IFG6
    case 20: break; // Vector 20: ADC12IFG7
    case 22: break; // Vector 22: ADC12IFG8
    case 24: break; // Vector 24: ADC12IFG9
    case 26: break; // Vector 26: ADC12IFG10
    case 28: break; // Vector 28: ADC12IFG11
    case 30: break; // Vector 30: ADC12IFG12
    case 32: break; // Vector 32: ADC12IFG13
    case 34: break; // Vector 34: ADC12IFG14
    default: break;
    }
    }

    Thanks
    Sathiyan
  • Hi Ryan,

    Review this code

    #include <msp430.h>

    #define Num_of_Results 8

    volatile unsigned int results[Num_of_Results];
    // Needs to be global in this
    // example. Otherwise, the
    // compiler removes it because it
    // is not used for anything.

    int main(void)
    {
    WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
    P6SEL |= 0x01; // Enable A/D channel A0
    REFCTL0 &= ~REFMSTR; // Reset REFMSTR to hand over control to
    // ADC12_A ref control registers
    ADC12CTL0 = ADC12ON+ADC12SHT02+ADC12REFON+ADC12REF2_5V;
    // Turn on ADC12, Sampling time
    // On Reference Generator and set to
    // 2.5V
    ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2; // Use sampling timer, set mode
    ADC12MCTL0 = ADC12SREF_1; // Vr+=Vref+ and Vr-=AVss
    ADC12IE = 0x01; // Enable ADC12IFG.0
    ADC12CTL0 |= ADC12ENC; // Enable conversions
    ADC12CTL0 |= ADC12SC; // Start conversion

    __bis_SR_register(LPM4_bits + GIE); // Enter LPM4, Enable interrupts
    __no_operation(); // For debugger

    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    static unsigned char index = 0;

    switch(__even_in_range(ADC12IV,34))
    {
    case 0: break; // Vector 0: No interrupt
    case 2: break; // Vector 2: ADC overflow
    case 4: break; // Vector 4: ADC timing overflow
    case 6: // Vector 6: ADC12IFG0
    results[index] = ADC12MEM0; // Move results
    index++; // Increment results index, modulo; Set Breakpoint1 here

    if (index == 8)
    {
    index = 0;
    }
    case 8: break; // Vector 8: ADC12IFG1
    case 10: break; // Vector 10: ADC12IFG2
    case 12: break; // Vector 12: ADC12IFG3
    case 14: break; // Vector 14: ADC12IFG4
    case 16: break; // Vector 16: ADC12IFG5
    case 18: break; // Vector 18: ADC12IFG6
    case 20: break; // Vector 20: ADC12IFG7
    case 22: break; // Vector 22: ADC12IFG8
    case 24: break; // Vector 24: ADC12IFG9
    case 26: break; // Vector 26: ADC12IFG10
    case 28: break; // Vector 28: ADC12IFG11
    case 30: break; // Vector 30: ADC12IFG12
    case 32: break; // Vector 32: ADC12IFG13
    case 34: break; // Vector 34: ADC12IFG14
    default: break;
    }
    }

    This working but count difference i am getting is 500.

    Thanks
    Sathiyan
  • I still don't see the ADC12MSC bit set in ADC12CTL0 and the delay you had correctly placed in the code is now once again missing. But adding ADC12SREF_1 is the greatest step in the right direction. If your input analog signal is not a steady voltage and oscillates then you will need to describe it in detail as this greatly affects the sample-and-hold time.

    Regards,
    Ryan
  • #include <msp430.h>

    #define Num_of_Results 8

    volatile unsigned int results[Num_of_Results];
    // Needs to be global in this
    // example. Otherwise, the
    // compiler removes it because it
    // is not used for anything.

    int main(void)
    {
    WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
    P6SEL |= 0x01; // Enable A/D channel A0
    ADC12CTL0 = ADC12ON+ADC12SHT0_8+ADC12MSC+ADC12REFON+ADC12REF2_5V; // Turn on ADC12, set sampling time
    // set multiple sample conversion
    ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2; // Use sampling timer, set mode
    ADC12IE = 0x01; // Enable ADC12IFG.0
    ADC12CTL0 |= ADC12ENC; // Enable conversions
    ADC12CTL0 |= ADC12SC; // Start conversion

    __bis_SR_register(LPM4_bits + GIE); // Enter LPM4, Enable interrupts
    __no_operation(); // For debugger

    }


    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    static unsigned char index = 0;

    switch(__even_in_range(ADC12IV,34))
    {
    case 0: break; // Vector 0: No interrupt
    case 2: break; // Vector 2: ADC overflow
    case 4: break; // Vector 4: ADC timing overflow
    case 6: // Vector 6: ADC12IFG0
    results[index] = ADC12MEM0; // Move results
    index++; // Increment results index, modulo; Set Breakpoint1 here
    if (index == 8)
    {
    index = 0;
    }
    case 8: break; // Vector 8: ADC12IFG1
    case 10: break; // Vector 10: ADC12IFG2
    case 12: break; // Vector 12: ADC12IFG3
    case 14: break; // Vector 14: ADC12IFG4
    case 16: break; // Vector 16: ADC12IFG5
    case 18: break; // Vector 18: ADC12IFG6
    case 20: break; // Vector 20: ADC12IFG7
    case 22: break; // Vector 22: ADC12IFG8
    case 24: break; // Vector 24: ADC12IFG9
    case 26: break; // Vector 26: ADC12IFG10
    case 28: break; // Vector 28: ADC12IFG11
    case 30: break; // Vector 30: ADC12IFG12
    case 32: break; // Vector 32: ADC12IFG13
    case 34: break; // Vector 34: ADC12IFG14
    default: break;
    }
    }

    Tell me Ryan now whether it is corrected now.

    I tested this code but giving wrong count.

  • It is difficult to continue helping debug your system without first discussing the nature of your ADC input. Does the count vary in between readings? Have you tried changing your sample-and-hold time to see if this makes any changes?

    Regards,
    Ryan
  • Hi Ryan,

    I am giving ADC Input from PWS2326 DC Power Supply (0 to 2.5V).

    Thanks

    Sathiyan

  • Verify your register settings with the Register window inside of the debugger. You still have yet to provide your device derivative. Are the ADC12RES bits set for 12-bit resolution?

    Regards,
    Ryan
  • Hi Ryan,

    Yes 12-bit resolution.

    Please find the ADC Register Configuration Snapshot for your reference as you requested.

    External I connected 1.0V to P6.0 pin, expecting hex value about ~0x0666 (count : 1638) but i am getting hex value about ~0x04D1 (count: 1233) @ADC12MEM0 (which is showed in snapshot).

    I am using MSP430F5529.

    Thanks
    Sathiyan
  • The following code worked as expected on my MSP-EXP430F5529:

    #include <msp430.h>
    
    #define   Num_of_Results   8
    
    volatile unsigned int results[Num_of_Results];
                                                // Needs to be global in this
                                                // example. Otherwise, the
                                                // compiler removes it because it
                                                // is not used for anything.
    
    int main(void)
    {
      WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer
      P6SEL |= 0x01;                            // Enable A/D channel A0
      REFCTL0 &= ~REFMSTR;
      ADC12CTL0 = ADC12ON+ADC12SHT0_8+ADC12MSC+ADC12REFON+ADC12REF2_5V; // Turn on ADC12, set sampling time
                                                // set multiple sample conversion
      ADC12CTL1 = ADC12SHP;                     // Use sampling timer
      ADC12MCTL0 = ADC12SREF_1;                 // Vr+=Vref+ and Vr-=AVss
      ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2;       // Use sampling timer, set mode
      ADC12IE = 0x01;                           // Enable ADC12IFG.0
      ADC12CTL0 |= ADC12ENC;                    // Enable conversions
      ADC12CTL0 |= ADC12SC;                     // Start conversion
    
      __bis_SR_register(LPM4_bits + GIE);       // Enter LPM4, Enable interrupts
      __no_operation();                         // For debugger
    
    }
    
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      static unsigned char index = 0;
    
      switch(__even_in_range(ADC12IV,34))
      {
      case  0: break;                           // Vector  0:  No interrupt
      case  2: break;                           // Vector  2:  ADC overflow
      case  4: break;                           // Vector  4:  ADC timing overflow
      case  6:                                  // Vector  6:  ADC12IFG0
        results[index] = ADC12MEM0;             // Move results
        index++;                                // Increment results index, modulo; Set Breakpoint1 here
    
        if (index == 8)
        {
          index = 0;
        }
      case  8: break;                           // Vector  8:  ADC12IFG1
      case 10: break;                           // Vector 10:  ADC12IFG2
      case 12: break;                           // Vector 12:  ADC12IFG3
      case 14: break;                           // Vector 14:  ADC12IFG4
      case 16: break;                           // Vector 16:  ADC12IFG5
      case 18: break;                           // Vector 18:  ADC12IFG6
      case 20: break;                           // Vector 20:  ADC12IFG7
      case 22: break;                           // Vector 22:  ADC12IFG8
      case 24: break;                           // Vector 24:  ADC12IFG9
      case 26: break;                           // Vector 26:  ADC12IFG10
      case 28: break;                           // Vector 28:  ADC12IFG11
      case 30: break;                           // Vector 30:  ADC12IFG12
      case 32: break;                           // Vector 32:  ADC12IFG13
      case 34: break;                           // Vector 34:  ADC12IFG14
      default: break;
      }
    }

    Make sure that the GND of your DC power supply is also connected.

    Regards, Ryan

  • Thanks Ryan I will Test.

  • Its working Ryan. Thanks for your great support.

    Regards
    Sathiyan

**Attention** This is a public forum