Sometimes you need to generate a pulse-width-modulation (PWM) signal for your circuit to simulate a certain behavior. The technique described here generates a simple programmable PWM signal for less than a dollar.
The technique uses an MSP430F20xx 14-pin microcontroller (MCU). The devices in this series incorporate Timer_A2, which allows you to generate one PWM signal without CPU intervention. The timer houses two capture-compare registers, called CCR0 and CCR1, which select the duty cycle and the period of the PWM signal.
Designers can purchase the MSP430F2013 MCU, emulator, and integrated development environment by ordering the eZ430-F2013, a $20 USB-stick-based MCU emulation and development tool. There's no need to solder or add any components. Once this project is finished, you can reuse the tool because it supports all devices within the MSP430F20xx series. The lowest-cost MCU in the series costs $0.55 and will implement the PWM signal, as it also has Timer_A2.
The software implementation, written in assembly, is extremely simple (click here to download the code):
- Initialization: For this section, the watchdog timer is turned off to avoid resetting the MCU. The general-purpose I/Os (GPIOs) are configured as outputs to avoid floating nodes and to reduce current consumption. GPIOs P1.2 and P1.4 are configured as follows: P1.2 outputs the PWM signal and P1.4 outputs the system clock signal (SMCLK), which effectively is 50% duty cycle.
- Setting the clock frequency: The MSP430F20xx can run its internal clock referred to DCO (digital control oscillator) at 1% at 25 C after calibration. To achieve this accuracy, the calibration values must be loaded to the clock registers depending on the clock speed, which takes only two instructions. The calibration values are factory programmed in flash.
Setting the PWM signal: The configuration illustrated is called up-down "toggle/set" mode (see the figure). However, Timer_A2 also supports other
output modes. For the toggle/set
mode, half the period is loaded to
CCR0, and half the duty cycle is loaded to CCR1. For a period of 20 ms, a 70%
duty cycle, and a clock speed of 1 MHz
(period of 1 s), CCR0 and CCR1 are
calculated as follows:
CCR0 = 20 ms/(1µs × 1000 ms/µs)/2 = 10,000
CCR1 = (100% - 70%) × CCR0 = 3000
Assuming the timer starts with a value of zero, which is typical, the up-down toggle/set mode functions as follows: The timer starts by increasing the counter; when CCR1 is equal to the counter, the port pin toggles. When CCR0 equals the counter value, the counter starts to count down. Again, during countdown, the port pin is toggled when CCR0 equals the counter. When the timer reaches the value of zero, the cycle repeats and the timer starts to count up.
- Turning off the CPU: As noted earlier, Timer_A2 outputs a PWM signal without CPU intervention. With a single instruction, the CPU is turned off, while the DCO continues to supply a high-speed clock to the Timer. Lower power consumption can be achieved by using the 32.768kHz crystal as the clock source for the timer to implement the PWM instead of using the DCO. To do so, the DCO must be turned off.