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.

EK-TM4C123GXL: EK-TM4c123GXL

Part Number: EK-TM4C123GXL

Hello everyone.

I  started working with PWM module in TIVA TM4C123G, I want the period to be same as the System clock ,and then i want to vary the duty cycle to be 50% ,30%, 70% etc.The PF1 pin i have connected with A DSO to check the width variation and same is refelected on onboard RED LED with brightness variations.I tried to do for 50% and its working fine but when i try for some other duty cycle,it is not working as expected. Kindly check the code below.

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

Int main(void)

unsigned long ulPeriod;


SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);


SysCtlPWMClockSet(SYSCTL_PWMDIV_1);


SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);


SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); 

ulPeriod = SysCtlClockGet(); 


GPIOPinConfigure(GPIO_PF1_M1PWM5);

GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);


PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN);

PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, ulPeriod );

PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5,ulPeriod/2);// when i divide the uIPeriod by any other value,its not giving the results as expected.

PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT , true);


while(1)
{

}


}

Thank You

  • The problem is that the period for the PWM is a 16-bit counter and you loaded it with a number that is bigger than can be represented by 16 bits. The function SysCtlClockGet() is returning 16,000,000 the system frequency in Hz. The maximum value for the period is 65,535. I modified your code using a smaller value for the period. I also added a call to PWMGenEnable(). If a longer period is needed, set the PWM pre-scale divider with the function: SysCtlPWMClockSet().

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_gpio.h"
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pwm.h"
    #include "driverlib/adc.h"
    
    int main(void)
     { 
    
    	unsigned long ulPeriod;
    
     	SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
     	SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
     	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
     	SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); 
    	ulPeriod = 10000u;
     	GPIOPinConfigure(GPIO_PF1_M1PWM5);
     	GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);
     	PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN);
    	PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, ulPeriod );
    	PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5,ulPeriod/3u);// Now works with different dividers
    	PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT , true);
    	PWMGenEnable(PWM1_BASE,PWM_GEN_2);
    	while(1)
     	{
    	}
    }
    

  • Hi,
    I don't think you enable the PWM_GEN_2 block. Please enable by using PWMGenEnable() and see if it works.

    When you use ulPeriod = SysCtlClockGet() it returns the processor clock rate which will be something like 16000000 for 16MHz. You are trying to set the PWM period with this value which is 0xF42400. The period reload register is only 16 bit while your value is larger. Only the 0x2400 is taken. Is this what you observe on the scope?
  • Hi

    Thank You Bob & Charles Tsai for helping me out.I just edited the code and its working fine with all dividers.

    Regards

    Sajad