I've been experimenting with the PWM Waveform Generation Modes on the ATMega328P. I've been getting some strange results and I can't figure out if its a problem with how I'm writing the firmware or how I'm interpreting the datasheet.
Here's the first piece of code that I wrote to emulate the analogWrite() function:
// Waveform Generation Mode 0
// Table 15-4 of the datasheet
void setup()
{
DDRB = (1<<PB1); // set pin 9 as output
TCCR1A |= (1<<COM1A1);
OCR1A = 125;
}
void loop()
{
}
The above code produces an average voltage output of around 2.5V (49% duty cycle) out of pin 9. The strange thing (for me) is that according to the datasheet, TIMER1 is a 16bit timer, so it should overflow at 65536 ticks. From what I understand setting OCR1A between 0 and 65535 will change the duty cycle of the pulse. So, having set the OCR1A at 125, shouldn't I be getting an output of around 0.01 V instead of 2.5V? The results seem to imply that the clock is overflowing at 255.
For my second foray into PWM land, I wanted to try and create a 2.5V signal using the ATMega's fast PWM mode. Here's what I got:
// Waveform Generation Mode 14
// Table 15-4 of the datasheet
void setup()
{
DDRB = (1<<PB1);
TCCR1A |= (1<<COM1A1) | (1<<WGM11);
TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS10);
ICR1 = 19999;
OCR1A = 10000;
}
void loop()
{
}
I set ICR1 (the overflow value) arbitrarily to 20000 ticks then set OCR1A (the compare value) to about half that. I set Channel A to non-inverting mode, but (I think) it wouldn't have made a difference if I set it to inverting mode. When I flashed this onto the Arduino I was getting a steady voltage average of 5V (100% duty cycle) out of pin 9, and I can't for the life of me figure out why.
I would appreciate any insight you can offer.