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 - How do I set up PWM output 2 and 3?

Other Parts Discussed in Thread: TM4C123GH6PM

Hi guys!

I am doing a PWM project on my TM4C123GH6PM evaluation board.

PWM output 0 and 1 through PWM_GEN_0 are working fine. Pin PD0 and PD1 on J3.

Need some help on getting PWM output 2 and 3. It should go through PWM_GEN_1 (datasheet) and supposedly either pin PE4 and PE5 on J1, or pin PA6 and PA7 on J1.

This is my code so far:

Void pwmInit(Void)
{
// PWM settings
PWM_FREQUENCY = 400;
ui8Adjust = 440;

SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
SysCtlPWMClockSet(SYSCTL_PWMDIV_64);

SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

// PWM PD0, motor A
GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);
GPIOPinConfigure(GPIO_PD0_M1PWM0);

// PWM PD1, motor B
GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_1);
GPIOPinConfigure(GPIO_PD1_M1PWM1);

// PWM PD1, motor C
GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_2);
GPIOPinConfigure(GPIO_PE4_M1PWM2);

// PWM PD1, motor C
GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_3);
GPIOPinConfigure(GPIO_PE5_M1PWM3);

// For pushbuttons
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;
GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_1, GPIO_DIR_MODE_IN);
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

// PWM clk and frequency
ui32PWMClock = SysCtlClockGet() / 64;
ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1;
PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN);
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, ui32Load);

PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN);
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, ui32Load);

// PWM 0 and 1
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, (ui8Adjust * ui32Load) / 1000);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_1, (ui8Adjust * ui32Load) / 1000);
PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT, true);
PWMOutputState(PWM1_BASE, PWM_OUT_1_BIT, true);

// PWM 2 and 3
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, (ui8Adjust * ui32Load) / 1000);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_3, (ui8Adjust * ui32Load) / 1000);
PWMOutputState(PWM1_BASE, PWM_OUT_2_BIT, true);
PWMOutputState(PWM1_BASE, PWM_OUT_3_BIT, true);

PWMGenEnable(PWM1_BASE, PWM_GEN_0);
PWMGenEnable(PWM1_BASE, PWM_GEN_1);
}

Anybody have some inputs for me? Do I maby have my PWM1_BASE mixed up?

  • Mon ami,

    You're close - just bit off-course.  Attention to detail very much demanded - any ARM MCU.

    Look at what works:

    // PWM PD0, motor A
    GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);
    GPIOPinConfigure(GPIO_PD0_M1PWM0);

    // PWM PD1, motor B
    GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_1);
    GPIOPinConfigure(GPIO_PD1_M1PWM1);

    And now - what fails:

    // PWM PD1, motor C
    GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_2);  // Might this "blend" of Port D & E derail you? cb1
    GPIOPinConfigure(GPIO_PE4_M1PWM2);

    // PWM PD1, motor C
    GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_3);  // ditto, per above cb1
    GPIOPinConfigure(GPIO_PE5_M1PWM3);

    Note that upon my older LX4F MCU - PE4 is indeed M1PWM2 - just as you asserted.  And PE5 is M1PWM3.  Thus - with your reconfig of PinTypePWM() away from Port D AND addressing the correct Port E "pin" (both selections your code shows are wrong!) you should quickly/easily be, "On the Air!"

    Our group always employs, "KISS."  I'd avoid use of any calculation w/in your early test/verify of PulseWidthSet - use easily recognizable (measureable) real numbers, instead.  Once proven - you may add the complexity of a calculated value - too often we've seen these fail - wastes time/energy - to little purpose...

    So close - faits attention - tous les jours...

  • Big thanks to cb1_mobile!

    Here is the working code with all changes made in green:

    Void pwmInit(Void)
    {
    // PWM settings
    PWM_FREQUENCY = 400;
    ui8Adjust = 440;

    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    SysCtlPWMClockSet(SYSCTL_PWMDIV_64);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // connector J1, pin PE4 and PE5
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // connector J3, pin PD0 and PD1

    // PWM PD0, motor A
    GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);
    GPIOPinConfigure(GPIO_PD0_M1PWM0);

    // PWM PD1, motor B
    GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_1);
    GPIOPinConfigure(GPIO_PD1_M1PWM1);

    // PWM PE4, motor C
    GPIOPinTypePWM(GPIO_PORTE_BASE, GPIO_PIN_4);
    GPIOPinConfigure(GPIO_PE4_M1PWM2);

    // PWM PE5, motor D
    GPIOPinTypePWM(GPIO_PORTE_BASE, GPIO_PIN_5);
    GPIOPinConfigure(GPIO_PE5_M1PWM3);

    // For pushbuttons
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;
    GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_1, GPIO_DIR_MODE_IN);
    GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

    // PWM clk and frequency
    ui32PWMClock = SysCtlClockGet() / 64;
    ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1;
    PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN);
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, ui32Load);

    PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN);
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, ui32Load);

    // PWM 0 and 1
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, (ui8Adjust * ui32Load) / 1000);
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_1, (ui8Adjust * ui32Load) / 1000);
    PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT, true);
    PWMOutputState(PWM1_BASE, PWM_OUT_1_BIT, true);

    // PWM 2 and 3
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, (ui8Adjust * ui32Load) / 1000);
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_3, (ui8Adjust * ui32Load) / 1000);
    PWMOutputState(PWM1_BASE, PWM_OUT_2_BIT, true);
    PWMOutputState(PWM1_BASE, PWM_OUT_3_BIT, true);

    PWMGenEnable(PWM1_BASE, PWM_GEN_0);
    PWMGenEnable(PWM1_BASE, PWM_GEN_1);
    }

  • You da Man - Alexander!  You were 99% of the way there - big thanks back to you for complete, now updated posting - so helpful to follow-on viewers. 

    Bon chance, mon ami...