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.

Launch Pad EK-LM4F120XL, duty 0 not work of PWM mode of GPTM

Other Parts Discussed in Thread: TM4C123GH6PM

Stellaris Launch Pad : EK-LM4F120XL CPU : LM4F120H5QR
Tool Soft CCS V5.5

I refer to "StellarisR LM4F120H5QR Microcontroller" ,
but I can not make the PWM output duty to 0 ,using the PWM mode of GPTM.
I was sure the output waveform on an oscilloscope by changing the parameters.
I changed the comment out of the parameters in order,below.
How do I parameter value?

I am not good at English,sorry.

-------------------------------------------------------------
Parameter summary

pulse cycle
4ms


pulse width
1. full ----OK
I refer to "Figure 11-6. CCP Output, GPTMTnMATCHR > GPTMTnILR" of "StellarisR LM4F120H5QR Microcontroller".

2. full ? 1 clock ----OK

3. 3ms ----OK
I refer to "Figure 11-8. CCP Output, GPTMTnILR > GPTMTnMATCHR" of "StellarisR LM4F120H5QR Microcontroller".

4. 1 clock ----OK

5. 0 ----NG
I refer to "Figure 11-7. CCP Output, GPTMTnMATCHR = GPTMTnILR " of "StellarisR LM4F120H5QR Microcontroller".


-------------------------------------------------------------
source "main.c"

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_timer.h"

#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/timer.h"


void main(void) {
unsigned long ulCycle = 0, // PWM frequency counter
ulDuty = 0, // duty counter
ulSysClock = 0, // system clock frequency
ulDelay = 0 ; // set change delay

unsigned long ulCycleScale = 0, //freequency prescale counter
ulDutyScale = 0; //duty prescale counter
unsigned long ulPwmN = 0 ;


//SysClock frequency 40MHz
SysCtlClockSet( SYSCTL_SYSDIV_5|SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN );
ulSysClock = SysCtlClockGet() ; //40,000,000 = 40 MHz

//400,000 :1s -> 1s/100 ->*1 = 3 ms
ulDelay = ulSysClock / 1000 * 1 ;

//configure gptm
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM);
TimerControlLevel(TIMER0_BASE, TIMER_B, 0); // Timer0-A High-Active


// GPIO configure
// GPIO_PIN_2: PWM set change timing monitor blue
// GPIO_PIN_1: PWM out Timer0-A port B6 red
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x00);

GPIOPinConfigure(GPIO_PF1_T0CCP1);
GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_1);

// TimerEnable(TIMER0_BASE, TIMER_B); //Timer0 start


//PWM value SET
//PWM cycle 4ms
ulCycle = ulSysClock / 1000 * 4;
ulCycleScale = ulCycle >> 16;
ulCycle &= 0xFFFF;

TimerPrescaleSet(TIMER0_BASE, TIMER_B, ulCycleScale);
TimerLoadSet(TIMER0_BASE, TIMER_B, ulCycle);


//Pulse width SET

/* full
ulDutyScale = ulCycleScale;
ulDuty = ulCycle + 1;
*/

/* full-1
ulDutyScale = 0;
ulDuty = 1;
*/

/* 3 ms
ulCycle = ulSysClock / 1000 * 4;

ulDuty = ulCycle - ( ulSysClock / 1000 * 3 ) ;
ulDutyScale = ulDuty >> 16;
ulDuty &= 0xFFFF;
*/

/* 1
ulDutyScale = ulCycleScale;
ulDuty = ulCycle -1 ;
*/

/* 0 NG */
ulDutyScale = ulCycleScale;
ulDuty = ulCycle ;
/* */


TimerPrescaleMatchSet(TIMER0_BASE, TIMER_B, ulDutyScale);
TimerMatchSet(TIMER0_BASE, TIMER_B, ulDuty);

TimerEnable(TIMER0_BASE, TIMER_B); //Timer0 start


//set change timing monitor
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,4);
SysCtlDelay(ulDelay);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,0);
}

  • Hello Kechan,

    I don;t think the 0% DC with the timer is possible for PWM. There was a thread in the forum few months back where the same issue we debugged to be a limitation from the GPT's PWM mode.

    Regards

    Amit

  • Agree - w/Amit - many ARM MCUs have difficulty in reaching PWM extremes - either 0 or 100% PWM duty.

    As a work-around you may gate the MCU's PWM output - so that an additional GPIO provides both the 0 or 100% duty cycles - as/if/when needed.

    Our group has found that for many applications - the necessity for 0 and 100% PWM is minimal - we drive Brushless Motors & various lighting schemes quite effectively via 3-97% PWM duty range.

  • I can confirm that 0% and 100% duty will not work. 

    I did had a application that i needed 0% duty but  it's 1 rare application. You need to configure a pin to be a GPIO and use it as a GPIO to set 0% and 100% duty. To use it as a timer pwm output again you have to re-configure it back.

  • Luis Afonso said:
    ...to use it as a timer pwm output again you have to re-configure it back.

    And while that may work for some applications - the earlier suggestion of using the added GPIO as a "gating" signal (or control) eliminates the time/effort penalty imposed by any such, "re-configuration" - thus proves a superior solution...

  • Is that possible without external hardware (yes i know it's just a few transistors)?

  • A properly chosen series R upon PWM output enables a simple GPIO to, "pull down" that PWM - yielding 0 duty cycle.  That GPIO reverts to open-drain (off) when 0 duty is not ordered.

    To force the output to 100% duty cycle the GPIO is switched to push-pull and driven high.  No transistors are required.

    To gain performance a small (SOT-23) gate (available from this vendor) may be imposed between the MCU's PWM output and the external device's PWM input.  GPIO then is employed @ PWM extremes...

    In either case - the original PWM signal & set-up/configuration is untouched...

  • Hi,

    Yes, there are some other brands which build micros with this feature. 

    Petrei

  • Petrei said:
    other brands which build micros with this feature

    Quite true - we use ARM MCUs (currently) from 4 makers - and each/every one enjoys/displays this PWM, "feature!"

    But again - series R and extra GPIO creates 0% duty-cycle - and for most all other Apps - 97-98% duty-cycle - achieved via these MCUs w/out modification - proves, "Good for G'ovt work."

    I'd bet that poster experimented (which is good) and noted this PWM limitation.  Yet - in the "real world" such should not prove "game-breaker" (and if not acceptable) work-arounds have been described...

  • Hi,

    Although I did not expressed, this is better than having that feature and then looking for some other circuitry to detect the missing pulse - I am in the area where this is a dangerous, so thanks to ARM/TI to avoid such. The user is free to choose whatever is more convenient. But your solution is of coarse much more simpler to realise than detecting a missing pulse and stopping the micro and the rest of hardware.

    Regards,

    Petrei

  • cb1- said:

    A properly chosen series R upon PWM output enables a simple GPIO to, "pull down" that PWM - yielding 0 duty cycle.  That GPIO reverts to open-drain (off) when 0 duty is not ordered.

    To force the output to 100% duty cycle the GPIO is switched to push-pull and driven high.  No transistors are required.

    To gain performance a small (SOT-23) gate (available from this vendor) may be imposed between the MCU's PWM output and the external device's PWM input.  GPIO then is employed @ PWM extremes...

    In either case - the original PWM signal & set-up/configuration is untouched...

    alright, no argues there. gonna try it out latter (to see if i understood it also)

  • Helio TI Emplyee,

    Question1
    "Figure 11-7. CCP Output, GPTMTnMATCHR = GPTMTnILR
    CCP not set if GPTMnMATCHR = GPTMnILR" of "11 General-Purpose Timers"in device datasheet.
    Is Stellaris LM4F120H5QR and Tiva TM4C123GH6PM data sheet description incorrect?


    When data sheet is incorrect,

    Question2
    To the duty to zero, what to zero by the GPIO as follows and next PWM set reconfig as follows?

    ---------------------------------------------------------------------------------
    test soft sorce

    duty    full-1 -> 0 ->  full-1 change example


    //*************************************
    // pwm width full-1
    //*************************************
        //Timer0 stop
        TimerDisable(TIMER0_BASE, TIMER_B);

        //PWM value SET  PWM cycle 4ms
        ulCycle = ulSysClock / 1000 * 4;
        ulCycleScale = ulCycle >> 16;
        ulCycle &= 0xFFFF;
        TimerPrescaleSet(TIMER0_BASE, TIMER_B, ulCycleScale);
        TimerLoadSet(TIMER0_BASE, TIMER_B, ulCycle);

        //Pulse width SET
        ulDutyScale = 0;
        ulDuty =  1;
        TimerPrescaleMatchSet(TIMER0_BASE, TIMER_B, ulDutyScale);
        TimerMatchSet(TIMER0_BASE, TIMER_B, ulDuty);

        TimerEnable(TIMER0_BASE, TIMER_B);  //Timer0 start

        //set change timing monitor
     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,4);
        SysCtlDelay(ulSysClock / 1000 * 1);  //3ms
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,0);


        //delay
        SysCtlDelay(ulSysClock / 1000 * 4);  //12ms


    //*************************************
    // pwm width 0  GPIO:0
    //*************************************

         //GPIO_PIN_1: PWM out   Timer0-A  port B6 red
         GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
         GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x00);


        //set change timing monitor
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,4);
        SysCtlDelay(ulSysClock / 1000 * 1);  //3ms
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,0);


        //delay
        SysCtlDelay(ulSysClock / 1000 * 4);  //12ms

     


    //next pwm

    //*************************************
    // reconfig
    //*************************************
        //configure gptm
            SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
            TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM);
            TimerControlLevel(TIMER0_BASE, TIMER_B, 0);      // Timer0-A High-Active


        // GPIO configure
            GPIOPinConfigure(GPIO_PF1_T0CCP1);
            GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_1);


    //*************************************
    // full-1
    //*************************************
            //Timer0 stop
            TimerDisable(TIMER0_BASE, TIMER_B);

            //PWM value SET  PWM cycle 4ms
            ulCycle = ulSysClock / 1000 * 4;
            ulCycleScale = ulCycle >> 16;
            ulCycle &= 0xFFFF;
            TimerPrescaleSet(TIMER0_BASE, TIMER_B, ulCycleScale);
            TimerLoadSet(TIMER0_BASE, TIMER_B, ulCycle);

            //Pulse width SET
            ulDutyScale = 0;
            ulDuty =  1;
            TimerPrescaleMatchSet(TIMER0_BASE, TIMER_B, ulDutyScale);
            TimerMatchSet(TIMER0_BASE, TIMER_B, ulDuty);

            TimerEnable(TIMER0_BASE, TIMER_B);  //Timer0 start

            //set change timing monitor
         GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,4);
            SysCtlDelay(ulSysClock / 1000 * 1);  //3ms
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,0);

     

  • Hello Kechan,

    There are multiple such data sheet issues which we need to fix. When!!! I can't give a date right now, but not soon enough.

    Regarding the second point of making it 0 or 1, a better way has been shown before by cb1. The way to implement it in TM4C would be different on the SW side. Do you want to use tat method or the custom method you have shown?

    Regards

    Amit

  • Hello TI Emplyee,

    Excuse me, Which source I mistake is different from method that cb1 shown?

     

     

     

  • Hello Kechan,

    cb1 mentioned using the Open Drain feature and Push Pull with driven '1' for 0 and 100% Duty Cycle. The above method is not inline with that. That is what I was stating.

    Regards

    Amit

  • Mes Amis,

    As this PWM @ extremes (i.e. near 0 and 100% duty cycle) plagues many - and appears not unique to this vendor - believe it best that I produce a separate post with schematic and Tek scope caps - proving the methodology.  (posting here insures post will have limited viewability/value...)

    I'll include SW for both Timer and PWM Generator impementations - both methods should benefit from this technique.

    Few days away - fortunately our order book continues to grow - I arrive here if/when time/strength allows...