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.

Problems with PWM control of TM4C1294NCPDT.

Expert 2780 points
Other Parts Discussed in Thread: EK-TM4C1294XL

Hi,

I have a question for the PWM control of TM4C129.

Set the PWM to the up-down mode, the LED will light up. (You can check the ek-tm4c1294xl)
CompA sets the Period value.
While the output of the PWM, it will reduce the value of CompA by one.
Then, the output of the PWM is changed to 0% from the duty ratio of 100%, LED will be black out.

However, if set a 0 to "CompA", it will be full lighting.

I where it was confirmed, the 1-> 0 and the output to alter the CompA will be next to High,
n-> 0 is varied and CompA Low. (n>=2)
1-> 0 change of only will be High.
CompA is 1, the next time is changed to 0, the rise of the PWM would be executed?
Capture PWM High
Capture PWM Low
PS
If you want to use the PWMPulseWidthSet (), you can achieve and to increment the width from 0 to Period.
Regards,
Da
  • Hello Da

    I failed to understand the question here? What si the Count Value and what is the CompA value we are discussing?
  • When We changed the register A, we asked about the output of the PWM.
    As follows is for the register of change.
    Case 1.
    Change the CompA from 1 to 0.
    Case 2.
    Change the CompA from 2(or more) to 0.

    Result
    In case 1, PWM output is high fixed.
    In case 2, PWM output is low fixed.

    Load / Count should be set to 3 or more.

    Regards,
    Da

  • Hello Da

    What is the PWM clock divisor, PWM configuration, etc. A code would be useful for an analysis of the issue.
  • Hi Amit Ashara.

    >What is the PWM clock divisor,

    Check divisor ...
    1/1, 1/2, 1/32 and 1/64

    >PWM configuration, etc.

    set configuration

    PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC;

    > A code would be useful for an analysis of the issue.

    Use  EK-TM4C1294XL with Terminal (with CCS)

    Terminal Input

    case 1
    19(enter)                        ...> CompA = 1
    20(enter)                        ...> CompA = 0

    case 2
    1(enter)                         ...> CompA = 19
    20(enter)                       ...> CompA = 0

    --- add utils ----

    uartstdio.c

    --- modified startup.c -----

    void (* const g_pfnVectors[])(void) =
    {
           :
    IntDefaultHandler, // PWM Fault
    pwm_isr, // PWM Generator 0
    IntDefaultHandler, // PWM Generator 1
           :
    }

    ---  main. c--

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_ints.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/pwm.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/pins_led.h"

    void InitConsole(void)
    {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioConfig(0, 115200, 16000000);
    }

    typedef struct {
    uint32_t base;
    uint32_t gen;
    uint32_t mode;
    uint32_t period;
    uint32_t duty;
    uint32_t bit;
    uint32_t out;
    uint32_t state;

    uint32_t int_pwm;
    uint32_t int_gen;
    uint32_t int_enable;
    uint32_t int_trigger;
    } PWM_DEF ;

    PWM_DEF pwm0;
    PWM_DEF pwm1;

    uint32_t set_number;

    void pwm_setup( PWM_DEF *pwm )
    {
    if( pwm->int_pwm )
    {
    PWMIntEnable(pwm->base, pwm->int_gen);
    PWMGenIntTrigEnable(pwm->base, pwm->gen, pwm->int_trigger);
    IntEnable(pwm->int_enable);
    }

    PWMGenConfigure(pwm->base, pwm->gen, pwm->mode);
    PWMGenPeriodSet(pwm->base, pwm->gen, pwm->period);
    PWMPulseWidthSet(pwm->base, pwm->out, pwm->duty);
    PWMOutputState(pwm->base, pwm->bit, pwm->state);
    PWMOutputInvert(pwm->base, pwm->bit, false);
    PWMGenEnable(pwm->base, pwm->gen);
    }

    void pwm_duty( PWM_DEF *pwm )
    {
    uint32_t duty;
    duty = PWMPulseWidthGet(pwm->base, pwm->out);
    if( duty != pwm->duty )
    {
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
    PWMPulseWidthSet(pwm->base, pwm->out, pwm->duty);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
    }
    }

    void pwm_period( PWM_DEF *pwm )
    {
    uint32_t duty;
    duty = PWMGenPeriodGet(pwm->base, pwm->out);
    if( duty != pwm->duty )
    {
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
    PWMGenPeriodSet(pwm->base, pwm->out, pwm->duty);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
    }
    }

    //pwm0.int_trigger = PWM_INT_CNT_LOAD|PWM_INT_CNT_AU|PWM_INT_CNT_AD|PWM_INT_CNT_ZERO;

    //#define INT_MODE PWM_INT_CNT_LOAD
    #define INT_MODE PWM_INT_CNT_ZERO
    //#define INT_MODE PWM_INT_CNT_AU
    //#define INT_MODE PWM_INT_CNT_AD

    void pwm_isr()
    {
    uint32_t status;

    uint32_t base;
    uint32_t gen;

    base = PWM0_BASE;
    gen = PWM_GEN_0;

    status = PWMGenIntStatus(base, gen, 0);
    PWMGenIntClear(base, gen, status);

    if(status & INT_MODE)
    {
    pwm0.duty = set_number;
    pwm_duty(&pwm0);
    }
    }

    int main(void)
    {
    uint32_t ui32SysClock;

    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL),120000000);

    InitConsole();

    //
    // Enable Peripheral Clocks
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //
    // Enable pin PF3 for PWM0 M0PWM3
    //
    GPIOPinConfigure(GPIO_PF3_M0PWM3);
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_3);

    //
    // Enable pin PF0 for PWM0 M0PWM0
    //
    GPIOPinConfigure(GPIO_PF0_M0PWM0);
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0);

    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);

    //

    // Set the PWM clock to the system clock.
    //
    //PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1);
    //PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_2);
    PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_32);
    //PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_64);

    UARTprintf("PWM Duty->\n");

    uint32_t period;
    uint32_t duty;

    //period = 4000;
    period = 40;
    duty = period / 2;

    pwm0.base = PWM0_BASE;
    pwm0.gen = PWM_GEN_0;
    pwm0.mode = PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC;
    //pwm0.mode = PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC;
    pwm0.out = PWM_OUT_0;
    pwm0.bit = PWM_OUT_0_BIT;
    pwm0.state = true;
    pwm0.period = period;
    pwm0.duty = duty;
    pwm0.int_pwm = 1;
    pwm0.int_trigger = INT_MODE;
    pwm0.int_enable = INT_PWM0_0;
    pwm0.int_gen = PWM_INT_GEN_0;

    pwm_setup( &pwm0 );

    pwm1.base = PWM0_BASE;
    pwm1.gen = PWM_GEN_1;
    pwm1.mode = PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC;
    pwm1.out = PWM_OUT_3;
    pwm1.bit = PWM_OUT_3_BIT;
    pwm1.state = true;
    pwm1.period = period;
    pwm1.duty = duty;
    pwm0.int_pwm = 0;

    pwm_setup( &pwm1 );

    IntMasterEnable();

    char word;
    char line[8];
    int byte;
    int number;
    int index;
    int flag;

    set_number = duty;

    while(1) {
    UARTgets(&line[0],6);

    flag = 0;
    number = 0;
    for(index=0;index<4;index++) {
    word = line[index];
    if(( '0' <= word ) && ( word <= '9' )) {
    number *= 10;
    byte = (int)(word - '0');
    number += byte;
    flag = 1;
    } else {
    break;
    }
    }

    if(flag)
    {
    if( pwm0.mode & PWM_GEN_MODE_UP_DOWN ) {
    set_number = number*2;
    } else {
    set_number = number;
    }

    byte = number / 1000;
    line[0] = byte + '0';
    number -= byte*1000;
    byte = number / 100;
    line[1] = byte + '0';
    number -= byte*100;
    byte = number / 10;
    line[2] = byte + '0';
    number -= byte * 10;
    line[3] = number + '0';
    line[4] = '\r';
    line[5] = '\n';
    line[6] = '>';
    line[7] = 0;

    UARTprintf(&line[0]);
    }
    }
    }

    Regards,
    Da

  • Hi Amit-san,

    In order to earn the answer, do you need anything else?
    The answer from our customers has been requested so please answer.

    Regards,
    Da

  • Hello Da

    As I said a CCS project (not just a code) would be more useful that just the code. I can take up the code mentioned above above and get a different result.
  • Vendor's Amit is without doubt "atop the mount" of knowledgeable, caring, insightful responders.

    Your presentation is somewhat short & choppy - such forces extra effort upon Amit & other "potential helpers" - rising to your aid.

    ARM MCUs (from many vendors - not just those here) have been (long) noted to become challenged when PWM Duty Cycles are set to extremes!   (both high & low)

    Multiple times here I have posted "workarounds" which enable the foolproof attainment of both 0 and 100% Duty Cycle.   (forum search under cb1 & cb1_mobile should find & reveal.)   The methods my firm/I have developed may require additional MCU GPIO pins & sometimes a simple, external logic gate...

    Providing exactly that which Amit has requested will best assist you - and your "customer."   (although unlikely your "customer" initiated such request...)

  • Hi, cb1_mobile.

    > Vendor's Amit is without doubt "atop the mount" of knowledgeable, caring,
    > insightful responders.
    > Your presentation is somewhat short & choppy - such forces extra effort upon Amit & other "potential helpers" - rising to your aid.

    His advice I am grateful.


    > ARM MCUs (from many vendors - not just those here) have been (long) noted
    > to become challenged when PWM Duty Cycles are set to extremes! (both high & low)

    In your opinion, the function of this PWM is in the specification of TM4C129x?
    (PWM output is high when rewritten from COMPA=1 to COMPA=PWM Period. ( up/down & non Invert ))


    > Multiple times here I have posted "workarounds" which enable the foolproof
    > attainment of both 0 and 100% Duty Cycle. (forum search under cb1 & cb1_mobile
    > should find & reveal.) The methods my firm/I have developed may require
    > additional MCU GPIO pins & sometimes a simple, external logic gate...

    It is this URL?
    e2e.ti.com/.../354826

    I could not understand what can be applied to this problem.
    However, if only I also control of high or low, is also considered to hand to change to the GPIO.


    Regards,
    Da
  • Hi, Amit

    I have attached to the project in the zip file.
    Could you get the file?
    I will be the project you are testing.
    This project runs on EK-TM4C1294XL.

    Regards,
    Da

    pwm_output_check.zip

  • If your issue is the inability of your device to obtain & maintain correct PWM Duty Cycle at/around "Duty Cycle Extremes" (~0 and ~100% Duty) then the imposition of a logic gate between the MCU's PWM pin and your external (PWM recipient) device can serve as a solution. The (added) logic device will gate an "over-ride" signal from an (extra) MCU GPIO to manage and/or create (both) 0% and 100% PWM Duty Cycles.
  • Hello cb1

    The issue I think is that the 0% and 100% behavior changes based on the comparator value transition.

    Hello Da,

    Which compiler version are you using as it is not importing the project. Also I would suggest trying the same with SYNC instead of NOSYNC.
  • Hello Amit

    > Which compiler version are you using as it is not importing the project. Also I would suggest trying the same with SYNC instead of NOSYNC.

    Compiler version is "TI v16.6.0.STS".
    Do NOSYNC is the setting that has a problem?( not used? )



    To clarify the question.

    Q1
    Specification of the next operation is the device?

    When the width of PWM is changed to Period from 1, output of PWM becomes high.
    When the width of PWM is changed to Period from 2 or more, output of PWM becomes high.
    (Up down mode with not Invert with NOSYNC with Period>=2)

    Q2
    Does this use has been written in the manual (or errata)?


    Regards,
    Da
  • Hello Da

    To be 100% sure we are on the same page (as the earlier post of yours seems to contradict the same and so does the image)

    When Period is changed from 1 to 0 => PWM output becomes high
    When Period is changed from 2 or more to 0 => PWM output becomes high
  • Hello Amit

    I am sorry.
    This mistake was to confuse the "Register value" and "TivaWare API of argument".

    Here is the correct

    When Period is changed from 1 to 0 => PWM output becomes high
    When Period is changed from 2 or more to 0 => PWM output becomes low

    Does this operate of the PWM Module has been described in the manual?

    Regards,
    Da

  • Hello Da

    I checked the code today and

    Case-1: I type 1 and then 0 => The output of the PWM was low
    Case-2: I type 2 and then 0 => The output of the PWM was low
  • Hello Amit,

    Thank you for checking.
    I'm very thankful.
    May I ask you to help me?


    Did you use the API of TivaWare?
    If you use the API of TivaWare, you need to set the reverse of a number.

    Value when using the API
    Case-1: I type Period-1 and then Period => The output of the PWM was ___
    Case-2: I type Period-2 and then Period => The output of the PWM was low

    Value when looking the Register

    Case-1: I watch 1 and then 0 => The output of the PWM was ....
    Case-2: I watch 2 and then 0 => The output of the PWM was low

    If the you have done is correct, please tell me how.

    Regards,
    Da

  • Hello Da

    I used your code for the experiment.
  • Hellow Amit.
    Thank you for reply.

    To generate the problem

    0. Write Program Image.

    1. Open & Connect Console.

    2. Push Reset Button
    "PWM Duty" is Displayed.
    3. type "19<enter>"
    "0019" is Displayed.
    4. type "20<enter>"
    "0020" is Displayed.
    >>> PF0 is High, LED is turned on.
    5. type "18<enter>"
    "0018" is Displayed.
    6. type "20<enter>"
    "0020" is Displayed.
    >>> PF0 is Low, LED is turned off.

    Regards,
    Da
  • Hello Da-san,

    I have reproduced the issue now. Also an interesting thing is that it is happening for UP-DOWN mode and not for the DOWN mode.
  • Hellow Amit-san,

    I think ...

    Period-1 is set, when it user-modified, the next PWM waveform starting at Period-1, and end with changed value.
    (need check)

    Other value is set, when it user-modified, the next PWM waveform starting at changed value, and end with changed value.

    If the changed value is more Period( or 0), so Compare is not generated, starting at Period-1, to continue as it is.

    Thus, also occurs in up-down mode is also in the up mode.


    Regards,
    Da
  • Hello Da

    I checked with DOWN mode and it does not occur. The issue seems to be in UP-DOWN only.