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.

ADC Conversion Time (SD16_A)

Other Parts Discussed in Thread: MSP430F47197, MSP430F47186

Hi

I'm working on msp430f47197

I have chosen the 1MHz SMCLK Clock for ADC(SD16_A)  for Six channels, in continuous grouping conversion. The conversion time too higher for the even 64 samples, any possibility to increase of conversion time or plz provide the conversion time data for msp430f47197

thanks & regards

kanagaraj

  • I'm a bit puzzled. What is your exact problem? Do you need more or less samples per second? Do you not get any at all? Is the reading noisy or unreliable?

    There is no 'conversion time data' for the SD16. It just takes samples at each clock pulse and feeds the result of the sampling stage (one bit per conversion) into a digital filter which provides a result after the given oversampling ratio.

    What do you mean with 'in continuous grouping conversion'? The register description in the datasheet tells that SD16GRP bit for grouping is reserved on 47x devices (no grouping available). You'll have to manually start all conversions (which will then sample continuously, but not synchronized to each other). The module description tells differently, but I bet the text has been written before the 47xx devices were out and the register description is more up-to-date.

    What is your clock divider? If it is 0, you'll need to set SD16BUFx = 3 for the input buffer (1MHz sampling frequency).

    With 64x oversampling, you should get 15625 interrupts per channel per second. A bit much. Leaves you about 100 clock cycles per conversion result.

    Going to a higher oversampling will reduce the number of conversions. the lower rate of 32x will double the maximum sampling frequency, which is ~32kHz then. More isn't possible with the SD16A. you can also increase conversion time (and therefore lower the sampling frequency) by setting the SMCLK input divider to something other than 1.
    This does not increase quality. The SD16 provides about 9 usable digits when used with 32x oversampling; everything below is noise. You'll need 1024x oversampling to get full 16 (or at least 15) usable bits.
    Also, the SD16 requires an external cutoff filter to prevent aliasing if the sampling time is too long. This is different for the ADC12, where there is a gate open for the sampling time (forming a virtual low-pass filter) and then the conversion is taken from the buffered voltage level while the gate is closed. The SD16 is different here as it just takes momentary samples each clock pulse and feeds them into the digital filter.

  • Hi 

    Main problem is I need to take 64 samples for every cycle in 50Hz Frequency totally 3200 samples per second. For conversion of six channels requires 260us.  So i reduced the 32 samples per second.

    In voltage measurement i'm not  getting the linearity in counts .

    ADC Intialisation Code

               mov.w   #SD16SSEL_1+SD16DIV_3,SD16CTL         ; 1.2V  External ref, SMCLK=8Mhz ADC clock= 8/8 = 1 MHz
              
               bis.w   #SD16OSR_256+SD16GRP+SD16DF+06000h,&SD16CCTL0     ; Group CH0 with CH1,bipolar
               bis.w   #SD16OSR_256+SD16GRP+SD16DF+06000h,&SD16CCTL1     ; Group CH1 with CH2
               bis.w   #SD16OSR_256+SD16GRP+SD16DF+06000h,&SD16CCTL2     ; Group CH2 with CH3,
               bis.w   #SD16OSR_256+SD16GRP+SD16DF+06000h,&SD16CCTL3     ; Group CH3 with CH4
               bis.w   #SD16OSR_256+SD16GRP+SD16DF+06000h,&SD16CCTL4     ; Group CH4 with CH5
               bis.w   #SD16OSR_256+SD16DF+06000h,&SD16CCTL5  

              bis.w   #SD16IE,&SD16CCTL5      ; CH5 Interrupt  enabled
              bic.w   #SD16SC,&SD16CCTL5     ; Clear the Start Conversion 

    There is bit Confusion in Input clock to ADC. What the maximum limit for input clock to ADC?

    Regards and Thanks

    Kay


          

  • Please don't say ADC if you mean the SD16_A. Other MSPs have an ADC12(A) and this is a completely different thing. Without looking at the thread topic, this can lead to confusion. (also, the SD16_A modules for the 2xx and 4xx series are different! I don't have any datasheet at hand with an SD16_A with parallel sampling (the 2xx series only has one simultaneous sampling channel)

    The maximum SD16 input clock depends on the device. This information is in the device-specific datasheet (which I don't have but you should). For other devices with an SD16 module (in this case the f2013), it is typ. 1MHz (max 1.1MHz) in full power mode and 0.5MHz in low power mode.

    In best case, teh SD16 requires 32x oversampling. This reduces the maximum sampling rate to Fsd16/32. But then, you'll get only 9-10 significant bits. The highest resolution of 16 significant bits is only achieved with 1024x oversampling. With significant bits, I mean the bits that definitely hold a relevant part of the measured signal by taking the resulting signal-to-noise-ratio into account. All other bits are possible noise.

    So with 1MHz and OSR32, you can get 31250 samples per second, with your SD16 for all 6 channels simultaneously. With OSR256, this is 3906.25 samples. If you need it synchroneous to the AC frequency of 50Hz, you'll need to either find a combination of possible SMCLK frequencies and OSR (Don't forget that there is SD16DIVx and SD16XDIVx) or adjust your crystal/DCO frequency, maybe by implementing a software FLL that runs on the AC frequency (zero-voltage-detection). if your MSP has an FLL hardware, you may feed the 100Hz zero-voltage signal to the LFXT1 input to feed the FLL hardware. This keeps your sampling synchroneous to the AC frequency for best results.
    Or you retrigger your 60 samples per wave cycle by a zero-voltage detection. It may, however, introduce some jitter (63/64/65 samples). It depends on the required accuracy.
    The minimum SD16 frequency is listed as 30kHz for the 2013.

    kanagaraj NP said:
    For conversion of six channels requires 260us.  So i reduced the 32 samples per second.


    ? why that?
    64 samples per wave @50Hz leaves you 312.5us per sample, with Fsd16=1MHz and OSR256, you need 256us. Since all 6 channels are converted simultaneously, there's plenty of time.

  • Hi,

     

    I'm facing similar problem with sample rate of SD16_A. I set up my PC with a serial port that supports 460800bps. (USB2Serial Converter).  My purpose is receiving every grouped channels sample in my PC. On MSP430F47186 side, I configured UCA1 as an UART and tested at baud rate 460800bps. Sending my packet that is TSample(26 bytes) takes only 600us for MSP.

     

    Well, for the SD16_A module, I have 6 channels to measure. SMCLK of MSP430 is 8.388608 Mhz. So I used 1/8 divider of SD16_A module so that fM will be 1.048576 Mhz. Also I want to test skills of SD16_A, so I set OSR to 1024. With this configuration, I was expecting 1048 samples/sec includes all channels value in my PC. But now MSP only sends 4 samples/sec ! If I reduce OSR to 256, then I receive 16 samples/sec on my PC.

     

    Could you tell me what is wrong with my test code below?

     

    Thanks,

    BP.

     

     

    #include <intrinsics.h>

    #include <stdint.h>

    #include <stdbool.h>

    #include  "msp430x471x6.h"

     

    typedef struct

    {

        unsigned char  START[6];

        unsigned long   Counter;

        unsigned int    Ch0;

        unsigned int    Ch1;

        unsigned int    Ch2;

        unsigned int    Ch3;

        unsigned int    Ch4;

        unsigned int    Ch5;

        unsigned char  STOP[4];

    } TSample; // totally 26 bytes

     

    TSample Sample = {"@START", 0, 0, 0, 0, 0, 0, 0, "STOP"};

     

    void send2pc(unsigned char* bin, unsigned char length)

    {

        while(length--)

        {

            while(!(UC1IFG & UCA1TXIFG));

            UCA1TXBUF = *bin++;

        }

    }

     

    volatile bool SEND_SAMPLES;

    volatile bool SAMPLE_READY;

     

    void main(void)

    {

        WDTCTL = WDTPW+WDTHOLD;     // Stop WDT

        FLL_CTL0 |= DCOPLUS + XCAP10PF;

        SCFI0 |= FLLD_2 + FN_2;

        SCFQCTL = 127;      // 8.388608 Mhz

       

        do

        {

            IFG1 &= ~OFIFG;                         // Clear OSCFault flag

            for (volatile unsigned int i = 0x47FF; i > 0; i--); // Time for flag to set

        }

        while ((IFG1 & OFIFG));             // OSCFault flag still set?

       

        // ref on, ref buffer on, 1/1 and 1/8 divider, SMCLK, ov interrupt disabled

        SD16CTL   = SD16XDIV_0 + SD16DIV_3 + SD16SSEL1 + SD16VMIDON + SD16REFON;

       

        // OSR 1024, Bipolar, DF, grouped

        SD16CCTL0 = SD16OSR_1024 + SD16DF + SD16GRP;

     

        // OSR 1024, Bipolar, DF, grouped

        SD16CCTL1 = SD16OSR_1024 + SD16DF + SD16GRP;

     

        // OSR 1024, Bipolar, DF, grouped

        SD16CCTL2 = SD16OSR_1024 + SD16DF + SD16GRP;

     

        // OSR 1024, Bipolar, DF, grouped

        SD16CCTL3 = SD16OSR_1024 + SD16DF + SD16GRP;

     

        // OSR 1024, Bipolar, DF, grouped

        SD16CCTL4 = SD16OSR_1024 + SD16DF + SD16GRP;

     

        // OSR 1024, Bipolar, DF, NOT grouped, interrupt enable

        SD16CCTL5 = SD16OSR_1024 + SD16DF + SD16IE;

       

        __delay_cycles(1000);  

       

       

        UCA1CTL1 |= UCSWRST;

        P1SEL |= BIT6+BIT7; // P1.6,7 = USCI_A1 RXD/TXD

        UCA1CTL1 |= UCSSEL_2;   // SMCLK

        UCA1BR0 = 18;       // 460800bps

        UCA1BR1 = 0x00;     //

        UCA1MCTL = 4;           // Modulation

       

        UCA1CTL1 &= ~UCSWRST;       // **Initialize USCI state machine**

        UC1IE |= UCA1RXIE           // Enable USCI_A" RX interrupt

        __enable_interrupt();

       

       

        SD16CCTL5 |= SD16SC     // Set bit to start conversion

       

        while(1)

        {

            if(SEND_SAMPLES)

            {

                if(SAMPLE_READY)

                {

                    send2pc((void*)&Sample, sizeof(TSample));

                    SAMPLE_READY = false;

                }

            }

        }

       

    }

     

    #pragma vector=USCIAB1RX_VECTOR

    __interrupt void USCIA1RX_ISR (void)

    {

        unsigned char  dmy = UCA1RXBUF;

           

        SEND_SAMPLES = !SEND_SAMPLES;

    }

     

    #pragma vector=SD16A_VECTOR

    __interrupt void SD16AISR(void)

    {

        switch (__even_in_range(SD16IV, 16))

        {

          case 2:                                   // SD16MEM Overflow

            break;

          case 4:                                   // SD16MEM0 IFG

            break;

          case 6:                                   // SD16MEM1 IFG

            break;

          case 8:                                   // SD16MEM2 IFG

            break;

          case 10:                                  // SD16MEM3 IFG

            break;

          case 12:                                  // SD16MEM4 IFG

            break;

          case 14:                                  // SD16MEM5 IFG

            ++Sample.Counter;

            Sample.Ch0 = SD16MEM0;           // Save CH0 results (clears IFG)

            Sample.Ch1 = SD16MEM1;           // Save CH1 results (clears IFG)

            Sample.Ch2 = SD16MEM2;           // Save CH2 results (clears IFG)

            Sample.Ch3 = SD16MEM3;           // Save CH3 results (clears IFG)

            Sample.Ch4 = SD16MEM4;           // Save CH4 results (clears IFG)

            Sample.Ch5 = SD16MEM5;           // Save CH5 results (clears IFG)

           

            SAMPLE_READY = true;

           

            break;

        }

    }

     

     

  • Ohh, I found a silly bug provided by TI sample codes (msp430x471x7_sd16_01.c, SD16SSEL1 doesn't correspond to SMCLK, it should be SD16SSEL_1) :

     

    In my code, this line

        // ref on, ref buffer on, 1/1 and 1/8 divider, SMCLK, ov interrupt disabled

        SD16CTL   = SD16XDIV_0 + SD16DIV_3 + SD16SSEL1 + SD16VMIDON + SD16REFON;

     

    should be:

        SD16CTL   = SD16XDIV_0 + SD16DIV_3 + SD16SSEL_1 + SD16VMIDON + SD16REFON;

    Now it works like expected, thanks :)

  • Yes, this bit-naming is quite confusing. Without an underscore, it means the bit, with underscore, it means the value of the bitfield.
    So SD16SSEL_1 is equal to SD16SSEL0, while SD16SSEL1 equals SD16SSL_2.

**Attention** This is a public forum