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 query; tm4c123gxl laucnhpad; internal temperature sensor

Genius 3300 points
Other Parts Discussed in Thread: TM4C123GH6PM

1. I have made adc code using sample sequencer 3. using keil 5.13.0.0 & driverlib 2.1.1.71.

2.In ADCClockConfigSet, what is the purpose of ADC_CLOCK_RATE_FULL,

ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 25U);

This function write 0x07 to register ADCSPC (page 844 of tm4c123gh6pm datasheet) which means "ADC sample lags by 157.5°".

What does that mean & how does it make clock rate full.

3. Page 38 of peripheral driver library says that, if ADCReferenceSet is used with ADC_REF_INT then reference is 3V.

However datasheet of MCU says that its 3.3V (voltage at Vdda & vssa). So i think its 3.3V right?

4. I took 100 samples of Internal temperature sensor, ignoring first two samples, the difference between max & min values is around 6 degree. Is it ok to have this large difference. Although datsheet says accuracy could be +-5C. But does that mean samples taken at a time could have such large variation.

Range is 30 to 35.5.

Edit: When turn on debug option goes into error in function ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 25U);

In this function error pint is :

ASSERT(((ui32ClockDiv - 1) & (ADC_CC_CLKDIV_M >> ADC_CC_CLKDIV_S)) == 0);

The left hand expression comes out to be 0x180 & code into error.

5. Below is my code. Are the steps to configure adc are correct:

    uint32_t ready_count;
    uint32_t pui32ADC0Value[1];
    uint32_t temp_c;

/* enable adc0 */    
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)))  &&  (--ready_count));
    if(0U == ready_count)   /* if periph not ready take action */
    {
    }    
    
    
/* disable any sequence, over-under flow, int before setting parasmeters of adc  */
    ADCSequenceDisable(ADC0_BASE , 3U);
    ADCSequenceOverflowClear(ADC0_BASE , 3U);
    ADCSequenceUnderflowClear(ADC0_BASE , 3U);
    ADCIntDisable(ADC0_BASE , 3U);
    ADCIntClear(ADC0_BASE , 3U);
    ADCComparatorIntDisable(ADC0_BASE , 3U);
    ADCComparatorIntClear(ADC0_BASE , 3U);
    ADCSequenceDMADisable(ADC0_BASE , 3U);
    
/* set clock & other functions */
    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 25U);  
    ADCReferenceSet(ADC0_BASE , ADC_REF_INT);   
    ADCSequenceConfigure(ADC0_BASE, 3U, ADC_TRIGGER_PROCESSOR, 0U);  
    ADCSequenceStepConfigure(ADC0_BASE, 3U, 0U, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);    
    ADCSequenceEnable(ADC0_BASE, 3U);
    
    while(1)
    {
        ADCProcessorTrigger(ADC0_BASE, 3U);
        while(!ADCIntStatus(ADC0_BASE, 3U, false));
        ADCIntClear(ADC0_BASE, 3U);
        ADCSequenceDataGet(ADC0_BASE, 3U, pui32ADC0Value);
        temp_c = (uint32_t)( 147.5f -  ((75U * 3.3f * pui32ADC0Value[0]) / 4096U) );
        
        wait_delay_us(10000);
        
        temp[cnt++] = temp_c;
        
        if(cnt >= 100U)
        {
            while(1);
        }    
        
    }    

  • Hello Vindhyachal

    1. The function ADCClockConfigSet is required for TM4C129 devices. Also if you look at the function it does not modify the ADCSPC register
    2. Yes, the internal reference is the VDDA pin voltage.
    3. To check the temperature accuracy just taking 100 samples is not sufficient. You need to keep the device at a constant temperature using a thermostream.
    4. Yes, we know of the issue and it is been documented on the forum. Plan is to fix the same in 2.1.2 release of TivaWare.
    5. For TM4C123 ADCClockConfigSet is not required.

    Regards
    Amit
  • Hi Amit,

    I was reading SPMZ849E, silicon errata. I am using driverlib 2.1.1.71 with TM4C123gh6pmi7
    looking at adc error: ADC#07, #08 , #09 , #14.


    1.ADC#07: ADC Sample Sequencers Priorities are Different Than Expected
    I didn't exactly get workaround in case I am using all sample sequencer.
    Should priority sequnce be SS0, SS1, SS2, SS3 (high to low).

    2. ADC #08: ADC Sample Sequencer Only Samples When Using Certain Clock Configurations
    You had said that ADCClockConfigSet is not required in case of TM4C123.
    Does that mean that ADC always use internal PIOSC as its clock source?
    If yes, consider when I am using PIOSC as both system & adc clock source. So in this case I have to go with workaround point 3 here?

    3. ADC #09: First two ADC Samples From the Internal Temperature Sensor Must be Ignored

    Does that mean when I sample internal temperature sensor, I have to take three readings i.e with SS0, or 1, or2
    & that SS should have highest priority so that three continuous samples can be taken?


    4. ADC #14: The First two ADC Samples may be Incorrect

    Edit: After this workaround I don't have to discard first two samples right?


    Is this the right way as workaround says to reset it again once clock is enabled:
    SysCtlPeripheralDisable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0))) && (--ready_count));
    if(0U == ready_count) /* if periph not ready take action */
    {
    }

    SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
    while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0))) && (--ready_count));
    if(0U == ready_count) /* if periph not ready take action */
    {
    }

  • Hello VT,

    ADC#07: Yes.
    ADC#08: For TM4C123 device you would need to change the ADC Clock Source to PIOSC from default configuration of PLL/25 (when using PLL)
    ADC#09: No. You can use any SS to read the Temp Sense. The first 2 samples should be discarded before using the TS value.
    ADC#14: The first section of the WA (as given below) is sufficient. You do not need to reset it again.

    SysCtlPeripheralDisable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0))) && (--ready_count));
    if(0U == ready_count) /* if periph not ready take action */
    {
    }

    Regards
    Amit
  • Hi Amit,

    Rest of query are closed except ADC#08.
    There may be four cases:

    1. using internal 16Mhz as system clock (no external osc connected).
    Then I think workaround #3 will work. How to do that in code?

    It says:
    a) enable pll (how to do that)
    b) configure PIOSC as adc clock source (ADCCC = 0x01)
    c) configire PIOSC as system clock source
    d) disable PLL (HWREG(0x400fe060) !=0x00000200)

    How to put in it code. Is it like this:
    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ );
    ADCCC = 0x01;
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHZ );
    HWREG(0x400fe060) !=0x00000200;


    2. Using external 16Mhz as sys clock.
    Then I think this will work. Workaround #2:

    SysCtlClockSet(SYSCTL_SYSDIV_1 |SYSCTL_USE_OSC |SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ );
    ADCCC = 0x01;


    3. using internal 16Mhz & pll
    Then I think this will work. Workaround #1:
    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_INT| SYSCTL_XTAL_16MHZ);

    ADCCC = 0x01; /* if want to operate ADC in deep sleep */
    or
    ADCCC = 0x00; /* defualt PLL / 25 */


    4. using external 16Mhz & pll
    Then I think this will work. Workaround #1 :

    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ );

    ADCCC = 0x01; /* if want to operate ADC in deep sleep */
    or
    ADCCC = 0x00; /* defualt PLL / 25 , extrnal clock */
  • Hello VT,

    For conditions 3 and 4 ADCCC = 0x01 will not work as expected if the Deep Sleep Clock source is switched to PIOSC or MOSC. Also MOSC is not a valid clock source for deep sleep mode.

    Regards
    Amit