// A sketch that creates an 8MHz, 50% duty cycle PWM and a 250KHz,
// 6bit resolution PWM with varying duty cycle (changes every 5μs
// or about every period.
#include <avr/io.h>
#include <util/delay.h>
void setup() {
// put your setup code here, to run once:
pinMode(3, OUTPUT); // output pin for OCR2B
pinMode(5, OUTPUT); // output pin for OCR0B
// Set up the 250KHz output
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(WGM22) | _BV(CS20);
OCR2A = 63;
OCR2B = 0; // <= This line does not generate 0% duty cycle
}
However when I make OCR2B zero the duty cycle on the scope still shows up at around 1.6%.
I don't have a clue what it takes to make it zero. I guess the line with OCR2B = 0 should have got it to 0.
Any ideas what is going wrong in the code?
You have to disconnect the hardware counter from the pin for 0%. The function analogWrite() has
special cases for 0 and 255, if you do direct register access to the hardware you'll have to special
case 0% too.
I guess the line with OCR2B = 0 should have got it to 0.
With 6 bit PWM there are 65 states, from 0/64 to 64/64 inclusive, yet 6 bits can only represent 64
states, so one state will be missing. It turns out with those settings 0 maps to 1/64, 63 maps to 64/64
MarkT:
You have to disconnect the hardware counter from the pin for 0%. The function analogWrite() has
special cases for 0 and 255, if you do direct register access to the hardware you'll have to special
case 0% too.
With 6 bit PWM there are 65 states, from 0/64 to 64/64 inclusive, yet 6 bits can only represent 64
states, so one state will be missing. It turns out with those settings 0 maps to 1/64, 63 maps to 64/64
Ok thanks, that's a pretty neat explanation.
So for 0% output is it a good idea to make that pin an input, or are there cooler ways of disconnecting the hardware counter from the pin?