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.

TM4C123GH6PM: PWM duty cycle can not be set to 0 with TivaWare

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL

Title says it all. I'm using the EK-TM4C123GXL launchpad. 

#include <stdint.h>
#include <stdbool.h>
#include <inc/hw_memmap.h>
#include <inc/hw_gpio.h>
#include <driverlib/pwm.h>
#include <driverlib/sysctl.h>
#include <driverlib/gpio.h>
#include <driverlib/pin_map.h>


int main(void) {
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB));

    GPIOPinConfigure(GPIO_PB4_M0PWM2);
    GPIOPinConfigure(GPIO_PB7_M0PWM1);
    GPIOPinConfigure(GPIO_PB6_M0PWM0);
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_4);
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6);
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_7);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_PWM0));


    PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
    PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);

    //0xff =256; 256/16MHz = 16us
    //0xff =256; 256/16MHz = 16us
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 0xff);
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, 0xff);

    //blue
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, 0);
    //green
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, 1);
    //red
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, 0x80);

    PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    PWMGenEnable(PWM0_BASE, PWM_GEN_1);

    PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT), true);

    while(1);

	return 0;
}

PWM_OUT_1 gets a duty cycle of 1/256 and I see a tiny pulse on the scope. PWM_OUT_0's duty cycle is set to 0, but it is high (100% duty). Setting a 100% duty cycle gets the expected results.

This issue has been found by at least two others:

https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/643899/2373019?tisearch=e2e-sitesearch&keymatch=pwm%20with%200%25%20duty%20cycle#2373019

https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/448664?tisearch=e2e-quicksearch&keymatch=PWMPulseWidthSet%20to%200

The second one is marked "answered", but I don't understand af36's workaround.

  • Hi Peter,
    0% DC is not possible on the TM4C's PWM module. If you want to have 0% DC, then the PWM output has to be disabled. In your case, you will

    do:
    PWMOutputState(PWM0_BASE, (PWM_OUT_1_BIT | PWM_OUT_2_BIT), true);

    instead of:
    PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT), true);
  • Does the disabled state drive the output low or leave it floating?
  • I didn't intend to mark this resolved. I want to use PWM2 when needed. I want to set GPIOPinConfigure(GPIO_PB4_M0PWM2);

    The pin needs to go low when a 0% duty cycle is desired.

  • Hi Peter,
    It will not float. You can also use the output inversion feature to specify the output state to your liking via the PWMINVERT register. As suggested by cb1 in the other thread you referenced, you can also configure the pin as GPIO pin and force it low for 0%DC.
  • Perfect. Thanks for the help
  • Depending upon your application - and the sensitivity of the device, "in receipt of the PWM signals" - you may, "Avoid the necessity to Switch from PWM to GPIO Config" (which is pretty major) and instead "dial in" the smallest PWM value - which the MCU is capable of producing - with consistency.

    In our experience - in many cases - the difference between 0% and (say) 2-3% PWM - proves little noted. (and impacting)

    Each/every application's case is different - thus this suggestion MUST be evaluated. Yet has proved robust while enabling, "Eased and Faster, "Increase of Duty Cycle"- via this, "Elimination of PWM Config. change."
  • cb1_mobile said:
    In our experience - in many cases - the difference between 0% and (say) 2-3% PWM - proves little noted. (and impacting)

    The issue here may not be the effect on the external device but that of power devices. A low PWM may push a power FET into the linear region without driving much current into the external device but potentially causing cross conduction.

    Robert

  • Yes - under (some) conditions - as you note - such (may) prove true.

    Yet - our "saving" use of, "In many cases" provides "wiggle room" - and absent poster's evaluation (as was directed) that lowered (2-3% duty cycle) has been employed w/out issue - while enabling, "Eased & Faster, Onset of Higher Duty Cycles!"
  • Is it appropriate to turn peripherals all the way off when they are unused? In addition to PWMOutputState(PWM0_BASE, PWM_OUT_6_BIT, false); , should I also call SysCtlPeripheralDisable(SYSCTL_PERIPH_PWM0); ? Is there any harm in leaving it on when unused?

    Disabling the PWM output bits works well. I am mixing colors for an indication RGB with PWM and fets which is cheaper than using a driver IC. Allowing the light components to turn on 1% makes a big difference in this particular application.
  • Hi Peter,
    By default after reset, the PWM modules and other peripherals are off until you enable them using SysCtlPeripheralEnable(). In your particular case the question to ask is if PWM_OUT_6_BIT is the only channel that you want to disable. The PWM0 module will control 8 channels. Are you not using some of the other channels? If you are truly not using the entire PWM0 then it is a good idea to disable it by calling
    SysCtlPeripheralDisable(SYSCTL_PERIPH_PWM0) even though that you might have already disabled all channels' output state via PWMOutputState. You can save some power by not enabling the module.
  • Peter Borenstein said:
    Is it appropriate to turn peripherals all the way off when they are unused?

    This is very much a, "blanket request" - and I suspect - a proper answer requires (much) more detail.

    You asked earlier (of Vendor's Charles) in regard to "added benefits" (if any) resulting from "SysCtlPeripheralDisable()" - I agree w/Charles - in "most all" cases such is NOT  needed.    (OutputState "false" proves sufficient.)     Of course - YOUR RESPONSIBILITY - AS ALWAYS is to comply w/vendor specifications & directions.     (and you may note my "boiler plate" (base of the forum page) regarding "Providers of Content.")

    It has been our experience that your report of, "1% Duty Cycle" - creating a, "big difference" (w/unspecified "light components") proves "unusual." We too have worked w/best/brightest "Hi-Brite & Color Rich LEDs/OLEDs" - I would lean (instead) to your FETs & FET Drivers' behavior - even to pcb layout & component selection - not the  "1% variation"  in Duty Cycle - as "more likely suspects" to such,  "Big difference!"     As always - devil "luxuriates" in such details - rarely fully/properly provided...

  • Peter Borenstein said:
    . I am mixing colors for an indication RGB with PWM and fets which is cheaper than using a driver IC. Allowing the light components to turn on 1% makes a big difference in this particular application.

    Presumably you have an inductor and flyback diode? If not you are likely overstressing your LEDs.

    Are you sensing the LED current or calculating an approximation?

    Robert

  • Robert Adsett said:
    cb1_mobile
    In our experience - in many cases - the difference between 0% and (say) 2-3% PWM - proves little noted.    (and impacting)

    Now firm/I have, "confirmed this (above) method to work" - in many (perhaps most) - yet "not all" - possible "use cases."  

    Into this "picture" arrived your observation (FET entering linear region) - and indeed that  raises concern.     That said - does such (potential),  "Unsought Entry into this Linear Region"  represent a,  "FET & related drive/design shortcoming" - which proves  -  "separate & independent from" -  my suggested,  "0% Duty Cycle, Work-Around?"

    I can (strongly) "Make my case" by presenting the, "General use of such (very) low Duty Cycles"  -  even when  -  and especially when  -  No such, "0% Duty Cycle Work Around has been ordered!"     Such (very) low Duty Cycles - outside (any) "work-around" - ARE LEGAL - are they not?

    This proposed "Work Around" may not be appropriate in "ALL instances."      That said - unwanted, (likely destructive) "Power FET Cross Conduction" should  NOT  result from, "Reduced Duty Cycle" - especially when such reduced Duty Cycle has been noted/expected  - and a  "Proper Power FET Design"   has been implemented...

  • cb1_mobile said:
    Robert Adsett
    cb1_mobile
    In our experience - in many cases - the difference between 0% and (say) 2-3% PWM - proves little noted.    (and impacting)

    Yes. However, particularly for DC motors that's not the whole case.

    First, at 0%. An inability to output a true zero results in a loss of control. AC motors do not have this particular issue since a fixed level output does not result in movement of the motor. This makes the failure to be able to output a PWM of 0 a fairly egregious fault.

    Second at the high end, the inability to go to 100% results in increased losses. It's highly desirable to be able to go to full on and remove the switching losses (including in the DC bus caps).

    This results in the usual control of the PWM as 0%, min on% to max on%, 100%

    There is a third reason. Although there is little difference in speed users can tell by other means that you are not switching at 100% and may not find it acceptable if you do not*.

    Robert

    * I will tell a tale. We had an experienced technical salesman and he would often troubleshoot a motor controller installation in  a customer's vehicle to replace the aging SCR controllers. SCR controller cannot reach 100% output and in fact cannot exceed something like 85% IIRC, SCR losses are also quite high. In order to deal with this manufacturers have installed a contactor that closes to short the motor to the battery at high speed (called a 1A or bypass contactor). On one particular installation the operator kept complaining that the vehicle wasn't going at the same speed as previously. The salesman couldn't find a problem, and tests showed that both the retrofitted vehicle appeared to have the same speed. Out of frustration he hooked up a contactor coils only, no power wiring. When the operator next took the vehicle out, he came back very happy that the speed had been improved to match the previous controller. Hearing the contactor close even though it did not do anything was sufficient to result in a perceived speed increase.

  • All well explained/illustrated - it is assumed that you agree w/the earlier point presented - "Minimal Duty Cycle should NOT Cause the "unsought entry" into Power FET's Linear Region" - when the FET Design implementation is, "aware & proper!"
  • cb1_mobile said:
    All well explained/illustrated - it is assumed that you agree w/the earlier point presented - "Minimal Duty Cycle should NOT Cause the "unsought entry" into Power FET's Linear Region" - when the FET Design implementation is, "aware & proper!"

    Absolutely, deadbands at both ends of the PWM range are customary for that reason.

    Robert

  • This issue is documented in the errata, but the workaround suggest using down count (which my code selects).
  • You should ask an old LM3S programmer about the get-around here, .

    For 0 percent duty cycle, set the duty cycle to 100 percent and invert the output. See what you have on the output.