This is a continuation of my Timers tutorial and assumes the reader has read and understood that text before beginning this one.
Part Nine - Pulse Width Modulation (PWM)
The previous sections of the timers tutorial have been dealing with a simple task - flashing a LED. We've managed to accomplish that task using a variety of methods which all center around the "Clear On Timer Compare" (or CTC) method of using the timer, in both software and hardware. But what if we want to dim the LED instead? Now we are getting into a new timer concept, that of Pulse Width Modulation, abbreviated to PWM for short.
Pulse Width Modulation allows us to interface our digital components with the analogue world. We can use PWM to adjust a motor's speed, a LED's brightness or a speaker's tone. PWM is a very important concept, which is used all throughout the world of digital electronics. It is a way of approximating an analogue source, which with a little filtering can be used as a real analogue source (albeit with a few limitations).
It's important to note that PWM does not change our AVR's limitations; the signal sent out by the timer is still a true digital signal. However, by altering the on and off time of the signal at a given frequency, we can adjust the average on time to give an approximate analogue signal. This signal is good enough for immediate use in many applications - including motor speed control and LED dimming - without any extra filtering, or with the addition of a capacitor the output can be smoothed to a real analogue wave.
Let's start with a picture representing the different types of signals (modified from Wikipedia):
The top waveform is a traditional analogue signal, varying smoothly from GND to VCC volts. The bottom waveform is a digital representation of the top, using PWM.
PWM allows us to set an overall frequency, and then vary the on and off time (called the duty cycle) of the output within each timer cycle. A longer duty cycle gives a longer on time, resulting in an analogue representation closer to the VCC voltage. A duty cycle of 100% (on for the entire cycle) gives a VCC output, while a duty cycle of 0% (off for the entire cycle) gives a GND output.
When we use the CTC timer mode, what we are actually doing is essentially PWM, but with a fixed duty cycle of 50%, and a variable frequency. For this example, we're using PWM and will conversely be using a fixed frequency and varying the duty cycle to dim our LED.
There are several different PWM modes that the AVR timers can be initialized in, each with slightly different characteristics. These are as follows:
- 1) Fast PWM (8, 9 or 10 bit)
2) Phase Correct PWM
3) Phase and Frequency Correct PWM
Before we can explore the different modes, we need to understand a little of the timer terminology. Frequency, as we know, is the number of cycles per second that the timer runs at - a higher frequency gives us a faster timer. In the PWM world, having a faster PWM frequency gives us finer control over the output, as we can respond faster to new PWM duty cycles. This is especially important when using PWM to produce audio from digital samples; a faster PWM frequency is required to give the full output frequency range by varying the duty cycle.
Next, we have the BOTTOM value. This is the lowest value that the timer will reach in the current mode. In all timer modes on all AVRs, this will be zero. Accompanying BOTTOM is TOP, which is the maximum value that the timer will reach before either (depending on the mode) resetting back to 0x00 or begin counting in reverse back to BOTTOM. For the normal mode, TOP is equal to the maximum value the timer can reach. For CTC mode, TOP is user settable, which gives us our control over the timer period. We are now using PWM, thus TOP is now set to give the PWM frequency.
Finally, we have our PWM COMPARE value. This sets the duty cycle - when this value is reached the waveform is inverted from its current state. Varying the COMPARE value will give us our varying duty cycle.
Now, let's get down to business and go into the three PWM modes.
Fast PWM
Fast PWM is useful for outputting PWM values quickly, at a loss of phase correctness - changes to the duty cycle will be reflected immediately, with the new signal being phase incorrect. When selected, the timer will count up from BOTTOM to TOP, with TOP being fixed at the bit-width of the fast PWM -- we are given a choice of 8, 9 or 10 bits depending on the timer bit width (8 bit timers will obviously not offer Fast PWM in more than 8-bits). The timer, when started, will count up continuously until TOP is reached, when it wraps back to BOTTOM and starts again. Inside this period when the counter reaches the COMPARE value, the output pin is set when the correct value is reached (and cleared when the timer wraps back from TOP to BOTTOM), so that varying COMPARE we get a PWM of a fixed frequency but a variable duty cycle.
This gives us the ability to change the duty cycle rapidly, in applications where the phase change does not matter. Applications such as motor control are particular about the phase, so we need to use the Phase Correct PWM mode.
Phase Correct PWM
Phase correct PWM gives phase-correct output as the duty cycle changes. The concept of phase is foregn to some, so we'll take a look graphically at how phase-incorrect (Fast PWM) and phase-correct PWM waveforms differ:
Notice the difference? In the case of Fast PWM, the high points are always aligned to the start of each period, with a smaller duty cycle resulting in a shorter ON time. Phase Correct PWM by contrast aligns the high points to the center of each period, so that a smaller duty cycle results in a shorter ON time -- but the ON times of all signals are aligned. As inducated in the Fast PWM explanation, this mode is useful in applications where the phase of the signals should not change, even if the duty cycles do. Phase Correct is slower than Fast PWM (as the name of the latter implies) due to the way Phase Correct PWM works.
When selected, the timer will count up from BOTTOM to TOP, and then start counting downwards back to BOTTOM before repeating. When upcounting, reaching COMPARE will turn on the output pin, while reaching the same value when downcounting will turn the output off. This results in the timer period being twice as long as Fast PWM mode (since the timer also has to count back to BOTTOM rather than just wrapping) but produces a phase-correct signal.
In Phase Correct PWM, the TOP value is variable and so the mode supports a variable PWM frequency. For generating simple audio tones from a speaker it is common to use the variable frequence of this mode to change the note pitch, and use the duty cycle to change the volume; a higher duty cycle results in a longer ON timer for the speaker, and so produces a louder sound.
SECTION INCOMPLETE - More updates soon.