TIMER_A: PWM Programming

Like with UART, many of the Timer_A DriverLib functions can utilize a struct that holds the configuration for the Timer_A module for generating PWM.

typedef struct _Timer_A_PWMConfig

{

    uint_fast16_t clockSource;

    uint_fast16_t clockSourceDivider;

    uint_fast16_t timerPeriod;

    uint_fast16_t compareRegister;

    uint_fast16_t compareOutputMode;

    uint_fast16_t dutyCycle;

} Timer_A_PWMConfig;

The clockSource parameter, as in previous structs, selects the source of the clock signal to be used with the Timer_A. There are four sources to choose from, but for our purposes, you will likely find TIMER_A_CLOCKSOURCE_SMCLK the most useful. The clockSourceDivider parameter acts as a prescalar, of which you can choose from several different macros. There are many options to choose from, so take a look at the timer_a.h file and locate the one that will be most useful for you. The timerPeriod parameter is, as implied, the period of the timer in terms of counter cycles. Keep this in mind; you will need to convert a period in seconds to one in counter cycles in order to make this work! The compareRegister parameter selects the compare register that the Timer_A module will use. The macros associated with this parameter follow the following format: TIMER_A_CAPTURECOMPARE_REGISTER_#, where # is a number 0 through 6. When driving peripherals with Timer_A, be sure to check your documents to see which compare registers those peripherals will use. For example, if you are using P2.5 as the output, the TA0.2 should be programmed, or TIMER_A_CAPTURECOMPARE_REGISTER_2.

The compareOutputMode parameter determines the behavior of the Timer_A by setting its output mode. Refer to the Modes of Operation section to evaluate which output mode will be most useful for your application. Finally, the dutyCycle parameter can be misleading. This parameter holds the OC value that changes the output once the Timer_A counter reaches it. If you are operating in SET_RESET mode, then dutyCyle would be the amount of time that the generated waveform is low (rather than high, as the usual definition of duty cycle would pertain to) expressed in counter cycles.

Just like UART and many other peripherals, the GPIO pins associated with the Timer_A should be configured to work with Timer_A. Otherwise, the default to their general i/o pin form. For this we use the following function:

extern void GPIO_setAsPeripheralModuleFunctionOutputPin(

        uint_fast8_t selectedPort, uint_fast16_t selectedPins,

        uint_fast8_t mode);

Unlike UART, once we have the Timer_A struct configured, there is no special function to initialize the Timer_A. If your Timer_A is being tied to a GPIO, you will need to initialize the necessary pins and their peripheral module functions, but otherwise, you can start using the Timer_A right away. In order to generate a pulse-width modulated waveform, use the following function:

extern void Timer_A_generatePWM(uint32_t timer,

                                const Timer_A_PWMConfig *config);

Where the timer parameter is the Timer_A module needed to generate a PWM signal: TIMER_A0_BASE, TIMER_A1_BASE, TIMER_A2_BASE, and TIMER_A3_BASE. Like with the compare registers, check to see which Timer_A base is needed to operate your peripheral. The *config parameter, as with UART, is a pointer to the Timer_A_PWMConfig struct containing all the configuration settings for the Timer_A module.

There are many cases that we like to stop the Timer_A. We have a simple function at our disposal to accomplish such a task.

extern void Timer_A_stopTimer(uint32_t timer);

Where, once again, timer is the Timer_A module needed to generate a PWM signal. Note that a single Timer_A module has more than one output channel. If the same Timer_A base is driving several peripherals across different output channels, stopping the timer will cease all of those peripherals.