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.

MSP430FG6626 A/D

Other Parts Discussed in Thread: MSP430FG6626, MSP-TS430PZ100AUSB

Hi,

I'm using A/D (6-channel single ended) for  MSP430FG6626  with External reference (1.25 v)  and I'm having some troubles with it, I don't get the right value .

when I apply 0.6v on the input I get (15728 in decimal) from the A/D and this is half what I should get (31457) .

I'm using the code provided from ti (msp430fg662x_ctsd16_07.c) with some change. and here the code . I'm using "MSP-TS430PZ100AUSB" for the micro  

MSP430FG6626
// ------------------
// 32.768 kHz Watch crystal
// CH1 -->|P6.0/A0 |
// CH2 -->|P6.1/A1 |
// CH3 -->|P6.2/A2 
// CH4 -->|P6.3/A3 |
// CH5 -->|P5.1/A4 |
// CH6-->|P5.6/A5 |
// P5.0-->VREF+ 1.25 v

#include <msp430.h>

#define Num_of_Channels 6

/* Arrays to store CTSD16 conversion results */
unsigned int Chresults[Num_of_Channels];
unsigned int index = 0;

void main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog



P6SEL |= BIT0 | BIT1 | BIT2 | BIT3; // Select A0 to A3...
P5SEL |= BIT1 | BIT6; // Select A4,A5
P5SEL |= BIT0;

CTSD16INCTL0 |= CTSD16INCH_0; 
CTSD16IFG &= ~CTSD16IFG0; // Clear CH0 result interrupt flag
CTSD16IE |= CTSD16IE0; // Enable CH0 result interrupts

__delay_cycles(2000); // Delay ~120us for 1.2V ref to settle

while(1) {
CTSD16CCTL0 |= CTSD16SC; // Set bit to start conversion
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
__no_operation(); // For debugger

if (index >= Num_of_Channels) {
index = 0; // SET BREAKPOINT HERE
CTSD16INCTL0 = CTSD16INCH_0; // Reset input to CH0
} else {
CTSD16INCTL0 += 1; // Increment CH count by 1
}
}
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=CTSD16_VECTOR
__interrupt void CTSD16_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(CTSD16_VECTOR))) CTSD16_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch (__even_in_range(CTSD16IV,CTSD16IV_CTSD16MEM0)) {
case CTSD16IV_NONE: break;
case CTSD16IV_CTSD16OVIFG: break;
case CTSD16IV_CTSD16MEM0:
Chresults[index++] = CTSD16MEM0; // Save CH0 result (clears IFG)
__bic_SR_register_on_exit(LPM0_bits); // Wake up
break;
default: break;
}
}

  • Hi Khaled,

    For an input reference VeREF+ of 1.25 V and a CTSD16GAIN of 1, VFSR+ = 1.25 V and VFSR- = -1.25 V (Table 5-35 from the Datasheet). According to Figure 30-7 of the User's Guide for offset binary format, -FSR equates to a CTSD16MEM of 0x0000 and +FSR is 0xFFFF (65535), with, GND being 0x8000 (32768). Your description, however, insinuates that twos complement is being used, where +FSR is 7FFF and GND is 0x0000, which does not make much sense seeing as how the CTSD16DF bit is never set. Any value under 32768 should not be possible with a positive input voltage.

    Does the msp430fg662x_ctsd16_07.c example provided the expected results with your setup? How does it react if CTSD16DF is not set? Have you tried using the internal reference voltage to see if this makes any difference? What value is measured if you ground the analog input pin A0?

    Regards,
    Ryan
  • thanks for replay,
    when I connect pin A0 to analog ground I get( 0) which right but when I connect it to VFSR+ = 1.25 (P5.0) it gives me (32000)!! and I am not using the twos complement and I did not set the CTSD16DF bit
  • It is acting exactly if the external reference was 2.5v !! but my external reference is 1.25v
  • Upon further inspection of Section 7.2.1.4.3 it appears that VFSR+ = 2*VeREF+ and VFSR- = 0 for single-ended input mode (controlled by CTSDINCHx bits of the CTSD16INCTLx registers) with GAIN = 1. With this new understanding your code appears to be operating as intended.

    Regards,
    Ryan
  • one more thing about this A/D (6-channels single ended/A0 --- A5) for MSP430FG6626 . I'm using Continuous conversion, So the A/D gives me the right result for all 6-channels for the very first scan then start giving me bad result. is there a certain way to initialize the A/D every time after I read the 6-channels ? and here is the code I use


    #include <msp430.h>

    #define Num_of_Channels 6

    /* Arrays to store CTSD16 conversion results */
    unsigned int Chresults[Num_of_Channels];
    unsigned int index = 0;
    void ToDAC_LTC2666(unsigned char C_A_WORD , unsigned int DATA);
    void main(void) {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog
    P6SEL |= BIT0 | BIT1 | BIT2 | BIT3; // Select A0 to A3...
    P5SEL |= BIT1 | BIT6; // Select A4,A5
    P5SEL |= BIT0;


    CTSD16INCTL0 |= CTSD16INCH_0;
    CTSD16IFG &= ~CTSD16IFG0; // Clear CH0 result interrupt flag
    CTSD16IE |= CTSD16IE0; // Enable CH0 result interrupts
    __delay_cycles(2000); // Delay ~120us for 1.2V ref to settle
    CTSD16CCTL0 |= CTSD16SC; // Set bit to start conversion


    while(1) {

    __bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
    __no_operation(); // For debugger

    }
    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=CTSD16_VECTOR
    __interrupt void CTSD16_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(CTSD16_VECTOR))) CTSD16_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch (__even_in_range(CTSD16IV,CTSD16IV_CTSD16MEM0)) {
    case CTSD16IV_NONE: break;
    case CTSD16IV_CTSD16OVIFG: break;
    case CTSD16IV_CTSD16MEM0:
    Chresults[index++] = CTSD16MEM0;
    if (index >= Num_of_Channels) {
    index = 0; // SET BREAKPOINT HERE
    CTSD16INCTL0 = CTSD16INCH_0; // Reset input to CH0
    }
    else {
    CTSD16INCTL0 += 1; // Increment CH count by 1
    }
    __bic_SR_register_on_exit(LPM0_bits); // Wake up
    break;
    default: break;
    }
    }
  • Please refer to section 30.2.9 of the User's Guide. Single channel, continuous conversion mode was not intended to constantly switch between channels during operation. Group conversions (CTSD16GRP) or a single conversion of 6 input channels (refer to TI example msp430fg662x_ctsd16_07.c) should be used instead.

    Regards,
    Ryan
  • This example ( msp430fg662x_ctsd16_07.c) shows a single conversion for 3 channels and repeated with while loop. if I need to use the same example but with continuous conversion mode is not working, it is just working for the first reading for those 3 channels then start giving me a wrong result.
    My understanding that there is one register for all channels (CTSD16MEM0) so for channels (A0,A1,A2,A3,A4,A5) I initial CTSD16 channel counter to start from A0 (CTSD16INCTL0 |= CTSD16INCH_0), the first interrupt I read CTSD16MEM0 which has A0 result then I increase the channel counter by 1 (CTSD16INCTL0 += 1) so the next interrupt I read (CTSD16MEM0) A1 result ... until A5 then I reset the channel input to CH0 ( CTSD16INCTL0 = 0) and repeat it a gain .. is my understanding not right or am I missing something ?

**Attention** This is a public forum