I am having the worst time conceivable understanding and using the PWM module for my Tiva TM4C1294NCPDT. I am trying to do the two following base tasks:
- Set the Period (target: 20ms)
- Set the Pulse Width (target: any value 0-20ms)
I have consulted the Peripheral Library Reference Manual and the provided example code (TivaWare_C_Series-2.1.3.156/examples/peripherals/pwm) and am very painfully unable to correctly set Period or Pulse Width. See the attached code ZIP, and code below for full illustration.
Problems
- I cannot successfully change the period
- I cannot understand how the math here works
- e.g. how to calculate the values for the set functions below. I can provide numeric examples of my results and confusion in them if needed
Questions (the starters I think...!)
-
How to get a PWM signal with a 20ms pulse??
- How does the math work for setting the period?
This feels mystical and confusing, in strong contrast to my MSP430 experiences. What am I missing here?? :(
#define F_CPU_MHZ (20000000) #define PWM_PER (6400000) int main(void) { /* Begin TivaWare Peripheral Driver Library Example (p.433) Note: Uses 'PWM_BASE', replaced here with valid 'PWM0_BASE' Changes - PWM_GEN_0 -> PWM_GEN_1 OUT_0 -> OUT_2, OUT_1 -> OUT_3 OUT_0_BIT -> OUT_2_BIT, OUT_1_BIT -> OUT_3_BIT Goal - Set the period of the PWM signal Goal - Set each pulse width, OUT_2 and OUT_3 A Target - Set PWM0 to 20ms period, with 1ms pulse on OUT_2 and 19ms pulse on OUT_3 Ultimate Goal - Have this dang thing make sense, and be able to use it like TivaWare states it can! */ //<Begin Added Code> g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_OSC), F_CPU_MHZ); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); GPIOPinConfigure(GPIO_PF2_M0PWM2); GPIOPinConfigure(GPIO_PF3_M0PWM3); GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2); GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_3); //<End Added Code> //The following example shows how to use the PWM API to initialize the PWM0 with a 50 KHz frequency, and with a 25% duty cycle //on PWM2 and a 75% duty cycle on PWM3. // Enable the PWM0 peripheral SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); // Wait for the PWM0 module to be ready. while(!SysCtlPeripheralReady(SYSCTL_PERIPH_PWM0)); // Configure the PWM generator for count down mode with immediate updates to the parameters. PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC); // Set the period. For a 50 KHz frequency, the period = 1/50,000, or 20 microseconds. For a 20 MHz clock, this translates to 400 // clock ticks. Use this value to set the period PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, 400); // Set the pulse width of PWM2 for a 25% duty cycle PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, 100); // Set the pulse width of PWM3 for a 75% duty cycle PWMPulseWidthSet(PWM0_BASE, PWM_OUT_3, 300); // Start the timers in generator 0 PWMGenEnable(PWM0_BASE, PWM_GEN_1); // Enable the outputs. PWMOutputState(PWM0_BASE, (PWM_OUT_2_BIT | PWM_OUT_3_BIT), true); for(;;); }