I'm new to arduino but have coded a few projects in AVR ASM years ago.
Now I'd like to manipulate t1/t2 to get high speed pwm. I can lower the resolution from 511(?) to 63. And maybe mess with the prescaler. It would be nice if millis() are left intact. Can it be done, or do I need to get out of the arduino umbrella?
Best Answer
I assume that "an arduino" refers to an ATmega328 -based arduino board.
The arduino initializes timer 0 for keeping count of elapsed microseconds/milliseconds, allowing us to use timer 1 and timer 2 as we please.
Since you asked if the resolution can be set to 511, we have to use the 16-bit timer 1 which can count from 0 to 65535 (actually 65536 steps, not 65535 as your thinking seems to imply). Timer 2 is an 8-bit timer, so it can only count from 0 to 255 (256 steps). You can configure either timer to restart counting at any arbitrary value.
In this configuration the timer is in fast PWM mode. The timer counts up from 0. After the counter value matches with TOP(ICR1 in this configuration), the next cycle will set the timer to 0 instead of incrementing it.
The current setup would produce a 31311.15 kHz PWM output. If you want a lower frequency, you could set the prescaler to a higher value, but it would lower the resolution. It makes more sense to just increase the TOP value. For example,
ICR1 = 15999
would produce a 1 kHz output with a resolution of 16000 steps, no prescaling required.The output duty cycle is controlled by the respective output compare registers. The value can range anywhere from 0 to TOP (inclusive), but going higher would cause the output to never reset. For example, to generate a 10% duty cycle at 20 kHz you would set
ICR1
to 799 andOCR1A
to 80.For more in-depth information, refer to the datasheet