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.

CCS/MSP432P401R: MSP432 ADC's sample rate

Part Number: MSP432P401R


Tool/software: Code Composer Studio

FlashCtl_setWaitState(FLASH_BANK0, 2);
    FlashCtl_setWaitState(FLASH_BANK1, 2);
    PCM_setCoreVoltageLevel(PCM_VCORE1);
    CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
    CS_initClockSignal(CS_SMCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_2);//40K


    ADC14_enableModule();

    ADC14_initModule(ADC_CLOCKSOURCE_SMCLK,ADC_PREDIVIDER_4,ADC_DIVIDER_5,0); //40K
ADC14_setSampleHoldTime(14,0);//set sample adcclk and convert adcclk,total 30 adcclk; /* Configuring GPIOs (5.4 A19) */ GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN7|GPIO_PIN6, GPIO_TERTIARY_MODULE_FUNCTION); P8SEL1|=BIT6; P8SEL0|=BIT6; /* Configuring ADC Memory */ MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true); MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_EXTPOS_VREFNEG_EXTNEG, ADC_INPUT_A19, false); /* Configuring Sample Timer */ ADC14_enableSampleTimer(ADC_MANUAL_ITERATION); /* Enabling/Toggling Conversion */ MAP_ADC14_enableConversion(); MAP_ADC14_toggleConversionTrigger(); /* Enabling interrupts */ MAP_ADC14_enableInterrupt(ADC_INT0); MAP_Interrupt_enableInterrupt(INT_ADC14); MAP_Interrupt_enableMaster(); /*Set resolution*/ ADC14_setResolution(ADC_14BIT);

eUSCI_SPI_MasterConfig SPI0MasterConfig =
{
     EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
     1000000,
     500000,
     EUSCI_B_SPI_MSB_FIRST,
     EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT,
     EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH,
     EUSCI_B_SPI_3PIN
};

above is spi configure

adc rate is 48M/2/4/5/30=40K, the last 30 is 16 sample adcclk plus 14 convert adcclk.

when i set ADC 40KHz sample rate, i transport ADC  result through SPI,it is  just not 40KHz,for example ,I sample 1 min,signal is 1KHz, it should be 40K *14bit*60=4800KB,through spi i just save 3600KB,

i want to know if the ADC sample rate is correcta and spi rate can speed up ,

  • > MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true);
    [...]
    > ADC14_enableSampleTimer(ADC_MANUAL_ITERATION);
    These set CONSEQ=2, MSC=0. Along with SHS=0 (since you haven't set it) your software must be doing the triggering, which means there will be some latency. Maybe the second line should have been:
    > ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION); // MSC=1
  • > CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
    > CS_initClockSignal(CS_SMCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_2);//40K
    [...]
    > EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
    > 1000000,
    > 500000,
    As I read this, your SPI setup says SMCLK is 1MHz, and you want a 500kHz SPI clock, so the divider will be 2. However, it looks like your SMCLK is actually 48MHz/2=24MHz, so your SPI will be running at 24MHz/2=12MHz, which is plenty fast enough for the 40K*16=640kbps you need.
  • I would recommend using the definitions for the sample and hold time described here,

    , for the API ADC_setSampleHoldTime.  I am not  sure what the number '14' will do.

    #define ADC_PULSE_WIDTH_4        ADC14_CTL0_SHT1_0
    #define ADC_PULSE_WIDTH_8        ADC14_CTL0_SHT1_1
    #define ADC_PULSE_WIDTH_16       ADC14_CTL0_SHT1_2
    #define ADC_PULSE_WIDTH_32       ADC14_CTL0_SHT1_3
    #define ADC_PULSE_WIDTH_64       ADC14_CTL0_SHT1_4
    #define ADC_PULSE_WIDTH_96       ADC14_CTL0_SHT1_5
    #define ADC_PULSE_WIDTH_128      ADC14_CTL0_SHT1_6
    #define ADC_PULSE_WIDTH_192      ADC14_CTL0_SHT1_7
    #define ADC14_CTL0_SHT1_0                        ((uint32_t)0x00000000)          /*!< 4 */
    #define ADC14_CTL0_SHT1_1                        ((uint32_t)0x00001000)          /*!< 8 */
    #define ADC14_CTL0_SHT1_2                        ((uint32_t)0x00002000)          /*!< 16 */
    #define ADC14_CTL0_SHT1_3                        ((uint32_t)0x00003000)          /*!< 32 */
    #define ADC14_CTL0_SHT1_4                        ((uint32_t)0x00004000)          /*!< 64 */
    #define ADC14_CTL0_SHT1_5                        ((uint32_t)0x00005000)          /*!< 96 */
    #define ADC14_CTL0_SHT1_6                        ((uint32_t)0x00006000)          /*!< 128 */
    #define ADC14_CTL0_SHT1_7                        ((uint32_t)0x00007000)          /*!< 192 */

    Regards,

    Chris

  • this is  my figure.the ad data  sent to sd card through spi, picture lost some data and has distortion, i dont konw why

  • Are you taking a bunch of samples and then writing to the SD card, or trying to read from the ADC and write at the same time?
  • sample data first then writing to SD

  • ADC14_enableModule();
    ADC14_initModule(ADC_CLOCKSOURCE_SMCLK,ADC_PREDIVIDER_4,ADC_DIVIDER_5,0); //40K

    ADC14_setSampleHoldTrigger(ADC_TRIGGER_ADCSC ,false);


    ADC14_setSampleHoldTime(ADC_PULSE_WIDTH_64,ADC_PULSE_WIDTH_16);

    /* Configuring GPIOs (5.4 A1) */
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN7|GPIO_PIN6,
    GPIO_TERTIARY_MODULE_FUNCTION);
    P8SEL1|=BIT6;
    P8SEL0|=BIT6;

    /* Configuring ADC Memory */
    MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true);
    MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_EXTPOS_VREFNEG_EXTNEG,
    ADC_INPUT_A19, false);

    /* Configuring Sample Timer */
    ADC14_enableSampleTimer(ADC_MANUAL_ITERATION);
    //ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
    /* Enabling/Toggling Conversion */
    MAP_ADC14_enableConversion();
    MAP_ADC14_toggleConversionTrigger();

    /* Enabling interrupts */
    MAP_ADC14_enableInterrupt(ADC_INT0);
    MAP_Interrupt_enableInterrupt(INT_ADC14);
    MAP_Interrupt_enableMaster();
    /*Set resolution*/
    ADC14_setResolution(ADC_14BIT);


    ADC14_setSampleHoldTime(ADC_PULSE_WIDTH_64,ADC_PULSE_WIDTH_16),this  configration does influence ADC sample rate,does it mean ADC sample rate 48M/2/4/5/(64+16)=15KHz?

    and what difference between ADC14_enableSampleTimer(ADC_MANUAL_ITERATION) and  ADC_AUTOMATIC_ITERATION?

  • The setSampleHoldTime API sets the sample and hold time for 'first' and 'second' pulse widths. ***EDIT THIS SENTENCE IS INCORRECT *** Please note that if you are using channel A19 only, then the sample and hold time is defined by second pulse width value. First -> 0-7 and 24-31 and Second -> 8-23 (see also the TRM register ADC14CTL0).  So the equation is incorrect, it should be 48M/2/4/5/16.  Please note, that applying 48Mhz to the ADC is beyond the specification of the device, it may work but operation is not guaranteed. 

    *** THE TRM STATES THAT IT IS THE ADCMEM LOCATION AND NOT THE CHANNEL LOCATION *** 

    *** Since A19 is configured to be written to MEM0, then the first paramter in the setSampleHoldTime API is applicable.  In later threads the SMCLK is identified as 24Mhz, so the ADC clock is 24Mhz/20 and the number of clocks for sample and conversion is 39 clocks or 24Mhz/20/39 -> 32.5us. ***

    The difference between ADC_MANUAL_ITERATION and ADC_AUTOMATIC_ITERATION is related to the repeated or sequences of channels.  This means that the next channel to be measured either happens automatically after the previous conversion is finished or it requires a manual trigger as defined in the setSampleHoldTrigger.  Please note that in order to start conversions a trigger must be provided. The automatic/manual is regarding the next conversion. The SHP and MSC bits are also defined in the ADC14CLT0 control register (slau356).

    bool ADC14_enableSampleTimer(uint32_t multiSampleConvert)
    {
        if (ADCIsConversionRunning())
            return false;
    
        BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_SHP_OFS) = 1;
    
        if (multiSampleConvert == ADC_MANUAL_ITERATION)
        {
            BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_MSC_OFS) = 0;
        } else
        {
            BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_MSC_OFS) = 1;
        }
    
        return true;
    }

    Regards,

    Chris

     

  •  Please note, that applying 48Mhz to the ADC is beyond the specification of the device, it may work but operation is not guaranteed. what does it  means?

    CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
    CS_initClockSignal(CS_SMCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_2);
    
    ADC14_enableModule();
    ADC14_initModule(ADC_CLOCKSOURCE_SMCLK,ADC_PREDIVIDER_4,ADC_DIVIDER_5,0); //1200K=ADCCLK
    
    ADC14_setSampleHoldTrigger(ADC_TRIGGER_ADCSC ,false);
    
    
    ADC14_setSampleHoldTime(ADC_PULSE_WIDTH_4,ADC_PULSE_WIDTH_16);
    
    /* Configuring GPIOs (5.4 A1) */
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN7|GPIO_PIN6,
    GPIO_TERTIARY_MODULE_FUNCTION);
    P8SEL1|=BIT6;
    P8SEL0|=BIT6;
    ADC14->CTL0|=ADC14_CTL0_SHP;
    
    /* Configuring ADC Memory */
    MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true);
    MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_EXTPOS_VREFNEG_EXTNEG,
    ADC_INPUT_A19, false);
    
    /* Configuring Sample Timer */
    ADC14_enableSampleTimer(ADC_MANUAL_ITERATION);
    
    /* Enabling/Toggling Conversion */
    MAP_ADC14_enableConversion();
    MAP_ADC14_toggleConversionTrigger();
    
    /* Enabling interrupts */
    MAP_ADC14_enableInterrupt(ADC_INT0);
    MAP_Interrupt_enableInterrupt(INT_ADC14);
    MAP_Interrupt_enableMaster();
    /*Set resolution*/
    ADC14_setResolution(ADC_14BIT);

    data sampled by A19 and stored  in ADCMEM0,does this influence SHT reg?

    also 14bit resolution has 16 adcclk,so total is 16(reslution)+16(samplehold)=32 adcclk?

    we can easily see data lost during saving to SD,what happened,what i  most want to know is about the ADC SAMPLE RATE?plz ,it's urgent!

  • Please note, that applying 48Mhz to the ADC is beyond the specification of the device, it may work but operation is not guaranteed. what does it means?
    - This means that the frequency applied to any peripheral should not exceed 24Mhz, except the ADC which supports up to 25Mhz. Up to this point I did not see a definition of SMCLK, and wanted to make you aware of this requirement.

    data sampled by A19 and stored in ADCMEM0,does this influence SHT reg?
    - This was a mistake on my part. The TRM states that the application is on a per register basis, ADC14MEMx, and not on a channel basis. This means that if A19 is stored in ADCMEM0, then the value found in ADC14SHT0 is applied because ADC14SHT0 applies to registers ADCMEM0 to ADC14MEM7 and to ADC14MEM24 to ADC14MEM31. Sorry for the confusion on that and I will edit the post above accordingly.

    ADC14_setSampleHoldTrigger(ADC_TRIGGER_ADCSC ,false); -> This API means that the sample rate is dictated by how fast you can call the API, MAP_ADC14_toggleConversionTrigger();. If you wait to do that in an ISR then there will be an additional delay (~10MCU cycles) to enter the ISR as well as execute the instructions within the API.

    ADC14_enableSampleTimer(ADC_MANUAL_ITERATION); -> This API and parameter means that you are in is pulse sample mode with ADC14MSC = 0. This means that the total time will be 23 ADCClock cycles plus the number of clock cycles defined for the sample time. So for example if you chose 16 samples, then the total time would be 39 clocks. e2e.ti.com/.../2928000

    If you are saving data to the SD card, then how do you trigger the ADC? I would recommend using the DMA to ping-pong between sets of measurements and use the timer to trigger the ADC. Something similar is done here where instead of writing to the SD card the data is sent to a display. dev.ti.com/.../

    Regards,
    Chris

**Attention** This is a public forum