Something that comes up all the time, PWM resolution. Engineers are often disappointed when they find out that the achievable resolution of the PWM is not nearly what they expected from the headline claims made in the microcontroller datasheet. Here is just one example of a typically perplexed customer.
Most of the time this is not due to dishonest advertising but rather a easily overlooked property of how PWM's work, so lets clear that up so that we can avoid the disappointment.
A conventional PWM will let you set the period and the duty cycle something like the image to the right shows.
Additionally you can set the duty cycle register, which will let you choose for how many of the Tsys clocks that fit into one Tpwm the output should remain high. In the example the duty cycle is set to 3.
It is typical for a microcontroller datasheet to advertise that it can accomodate a duty cycle of 12-bits or 16-bits or something in that order. Of course this is an achievable number of clocks for the PWM to remain high, but the range of the number is always going to be limited by the period of the PWM.
That means that if we select the period to be 2^16 = 65536 clocks, then we will also be able to control the duty cycle up to 16 bits. It is easy to make the mistake of believing that you will get 16 bits of resolution over the achievable range, but this is very rarely the case.
Let's look at some real numbers as an example using the PIC16F1778.
The first page from the datasheet can be seen to the right. It advertises here that the PWM on this device is 16-bit. Importantly it also shows that the timer capability is limited to 16-bit.
Looking at the PWM's on this device we will try to see what is the highest frequency (lowest period) at which we can get 16-bits of PWM resolution.
The fastest clock this PWM can use as it's time base is the system clock, which is limited to 32MHz on this device. That means in terms of Figure 1 above that Tsys would be the period of one clock at 32MHz = 31.25ns.
If we want to achieve the full resolution of the PWM we have to run the timer at it's 16-bit limit, which means that the PWM frequency will be 32MHz / 2^16 = 488Hz !
So if you need the PWM frequency to be anything more than that you will have to compromise on the resolution in order to achieve a faster switching frequency.
Typically engineers will try to run at switching frequencies above 20kHz because this is roughly the audible range of the human ear. If you switch at a lower frequency people will hear a hum or a high pitched tone which can be very irritating.
So let's say we compromise to the lowest limit here and try to run the PWM at 20kHz, how much of the PWM resolution will we be giving up by using a higher frequency?
The easiest way to calculate this is to simply realize that one clock is 31.25ns and the resolution of the PWM will be limited to how many times 31.25ns fits into the period of the PWM.
At 488Hz the period is 1/488Hz = 2ms and we can calculate that 2ms/31.25ns = 65536. We can determine how many bits are required to represent that by taking log(65536)/log(2) = 16-bits of resolution.
This would mean that to get the number of usable options for duty cycle at 20kHz we need to calculate (1/20kHz)/31.25ns = 1600. So with 1600 divisions the resolution of the PWM is reduced to log(1600)/log(2) = 10.64bits, which means that we achieve slightly better than 10-bits of resolution.
This is the point where people are usually unhappy that the advertised 16-bits of resolution has somehow evaporated and turned into only 10 bits!
So the advice I have for you is this. When selecting a device where you have PWM resolution requirements you better make sure you do all the math to make sure that you can run at the resolution you need with the clocks you have available. And remember that when it comes to PWM resolution the PWM clock speed is always going to be king, so it is typically better to select the device with the higher clock speed instead of the one that claims the highest PWM resolution (at a snail's pace...)
And you you feel adventurous you can always try something more exotic like using the NCO to generate a high resolution PWM at high frequencies as described in this application note