Written by: David Dubins, 17-Nov-2018 Tested on Arduino IDE version 1.8.7
This story began because I needed to do something that I thought would be simple, but ended up being quite challenging. I wanted a 370 kHz wave on Pin 3 of my Arduino Uno, because I needed to move a clock out from another pin to avoid a hardware conflict with an external chip (the 23LC1024 - here is a cheap plug for the library I wrote for it: https://github.com/dndubins/SRAMsimple). Little did I know that this was not a quick or easy problem. What the fclk! There are lots of explanations and code snippets out there to create custom frequency clock signals, but I quickly learned that I lacked the basic understanding of registers to do this.
One week spent with an oscilloscope later, I feel as though I am good here, and I'd like to pass on what I've learned to the beginner (or me, one week ago, if time travel is ever invented). So with very little explanation and jumping in right to the code, here goes! Apologies to people here who actually know what they are doing - don't bother looking at this code. It's crude, it's probably inefficient, there are a number of facets I've ignored, and yes it's probably wrong in places. There are better resources out there. This brief article is for cutting right to the chase for the beginner, with the few useful timer modes I played with.
There are three timers in the ATmega328P that time various important things. Timer 0 controls pins 5 and 6, along with the arduino time-related functions (e.g. delay() and millis()). Timer 1 controls pins 9 and 10. Finally, Timer 2 controls pins 3 and 11. So let's start with Timer 0. I will organize this page by what you might looking to do, so that hopefully you can find "the answer" quickly.
Timer 0 is a 8-bit clock, so the counters are limited to 255.
There are two counters involved in this mode: OCR0A and OCR0B. Setting OCR0A will change the frequency of the output signal. The prescaler value is a multiplier which puts you in a different frequency range. In this mode (inverting, fast PWM), the formula for the output signal is:
output frequency=fclk/((OCR0A+1)*N), where fclk=16000000, and N is the prescaler you selected by un-commenting the appropriate line in the above code (which can just go in your setup loop if you like).
The duty cycle for this signal will be defined by OCR0B, and calculated by the formula: duty cycle=OCR0B/OCR0A. The example code above creates a signal on Pin 5 with a frequency of 390 kHz and a duty cycle of 50%.
Here is a chart of the frequencies you will get (in Hz), spanning the OCR0A range and prescalers you can use:
OCR0A N=1 N=8 N=64 N=256 N=1024
1 8000000 1000000 125000 31250 7813
5 2666667 333333 41667 10417 2604
10 1454545 181818 22727 5682 1420
20 761905 95238 11905 2976 744
40 390244 48780 6098 1524 381
60 262295 32787 4098 1025 256
80 197531 24691 3086 772 193
100 158416 19802 2475 619 155
120 132231 16529 2066 517 129
140 113475 14184 1773 443 111
160 99379 12422 1553 388 97
180 88398 11050 1381 345 86
200 79602 9950 1244 311 78
255 62500 7813 977 244 61
You can try generating this chart in Excel with the above formula. You can use any integer between 0-255 for the counter OCROA, I just wanted to make my tables a bit smaller by skipping rows.
OCR0B is left out of the picture here, and you are limited to a 50% duty cycle in this mode. The formula for frequency is slightly different (by a factor of 2):
output frequency=fclk/((OCR0A+1)*2*N)
The example code above creates a signal on Pin 6 with a frequency of 727 kHz and a duty cycle of 50%.
Here is a nice chart spanning the range of OCR0A and prescaler values:
OCR0A N=1 N=8 N=64 N=256 N=1024
1 4000000 500000 62500 15625 3906
5 1333333 166667 20833 5208 1302
10 727273 90909 11364 2841 710
20 380952 47619 5952 1488 372
40 195122 24390 3049 762 191
60 131148 16393 2049 512 128
80 98765 12346 1543 386 96
100 79208 9901 1238 309 77
120 66116 8264 1033 258 65
140 56738 7092 887 222 55
160 49689 6211 776 194 49
180 44199 5525 691 173 43
200 39801 4975 622 155 39
255 31250 3906 488 122 31
So far, so good? How about if you'd like to output a signal on both Pins 5 and Pin 6 at the same time?
So you can also create a signal on both pins; however, in the modes I've tried, you can't make them have distinct (different) frequencies. They will have the same frequency, which is (less) tweakable. You can however assign them different duty cycles, which is nice.
The formula for the output frequency is now only dependent on the prescaler you select, since the counter will run out to the end of its cycle. The frequencies you have at your disposal then are governed by the formula fclk/(256*N), giving rise to the following options:
N=1 N=8 N=64 N=256 N=1024 62500 7813 977 244 61 Hz
The duty cycle for pin 6 is adjusted by changing OCR0A to a number between 0-255. For a duty cycle of 50%, select 128. The formula for the duty cycle is (255-OCR2A)/255, so a duty cycle of 25% would need an OCR2A value of 191. Pin 5's duty cycle can be adjusted independently using OCR0B, using the same formula as A. How great is that?!
The example code above creates a signal on Pin 5 with a frequency of 62.5 kHz and a duty cycle of 80%, and a signal on Pin 6 with the same frequency (62.5 kHz) and a duty cycle of 50%.
Timer 1 is a 16 bit clock, so there is a bit more flexibility here (largest counter value is now 65535). The code for Pin 10 bears resemblance to that of Pin 5 only above, so I'm putting these code snippets in the same order.
Like before, setting OCR1A will change the frequency of the output signal. The formula for the output signal is: output frequency=fclk/((OCR1A+1)*N), where fclk=16000000, and N is the prescaler you selected by uncommenting the appropriate line above. The duty cycle is calculated using the formula: duty cycle = OCR1B/OCR1A (use half of 0CR1A for a 50% duty cycle)
The example code above creates a signal on Pin 10 with a frequency of 390.2 kHz and a duty cycle of 25%.
Here is a chart of the frequencies you will get, spanning the OCR1A range and prescalers you can use:
OCR1A N=1 N=8 N=64 N=256 N=1024
1 8000000.0 1000000.0 125000.0 31250.0 7812.5
10 1454545.5 181818.2 22727.3 5681.8 1420.5
50 313725.5 39215.7 4902.0 1225.5 306.4
100 158415.8 19802.0 2475.2 618.8 154.7
500 31936.1 3992.0 499.0 124.8 31.2
1000 15984.0 1998.0 249.8 62.4 15.6
5000 3199.4 399.9 50.0 12.5 3.1
10000 1599.8 200.0 25.0 6.2 1.6
50000 320.0 40.0 5.0 1.2 0.3
65535 244.1 30.5 3.8 1.0 0.2
Like with Pin 6, OCR1B is left out of the picture here, and you are limited to a 50% duty cycle in this mode. As with Pin 6, the formula is:
output frequency=fclk/((OCR1A+1)*2*N)
The example code above creates a signal on Pin 9 with a frequency of 195.1 kHz and a duty cycle of 50%.
Here is a chart spanning the range of OCR1A and prescaler values:
OCR1A N=1 N=8 N=64 N=256 N=1024
1 4000000.0 500000.0 62500.0 15625.0 3906.3
10 727272.7 90909.1 11363.6 2840.9 710.2
50 156862.7 19607.8 2451.0 612.7 153.2
100 79207.9 9901.0 1237.6 309.4 77.4
500 15968.1 1996.0 249.5 62.4 15.6
1000 7992.0 999.0 124.9 31.2 7.8
5000 1599.7 200.0 25.0 6.2 1.6
10000 799.9 100.0 12.5 3.1 0.8
50000 160.0 20.0 2.5 0.6 0.2
65535 122.1 15.3 1.9 0.5 0.1
Again, the frequencies are limited with the mode I played with (modulated only by changing the prescaler value). However, you can set the duty cycles of 9 and 10 individually.
The formula for the resulting frequency on both Pins 9 and 10 is: output frequency = fclk/(1024*N). Frequency depends only on the prescaler value, giving rise to the following options:
N=1 N=8 N=64 N=256 N=1024 15625 1953 244 61 15 Hz
The duty cycle for pin 9 is adjusted by changing OCR1A to a number between 0-1024. For a duty cycle of 50%, select 512. The formula for the duty cycle is (OCR1A)/1024, so a duty cycle of 25% would need an OCR1A value of 256. Pin 10's duty cycle can be adjusted independently using OCR1B, using the same formula as A.
The example code above creates a signal on Pin 9 with a frequency of 15.6 kHz and a duty cycle of 50%, and a signal on Pin 10 with the same frequency (15.6 kHz) and a duty cycle of about 10%.
Timer 2 is a lot like Timer 0 (it's also an 8 bit clock and the registers are structured very similarly). One important distinction is that the options for the prescaler values are a little different. Also, changing Timer 2 doesn't mess up the arduino time functions.
You can see that this is almost identical to the code for Pin 5 only, but with the Timer2 register names, and the prescaler options are different. The formula for the signal frequency is: output frequency=fclk/((OCR2A+1)*N). The duty cycle is set by the ratio of OCR2B/OCR2A.
The example code above creates a signal on Pin 3 with a frequency of 390.2 kHz and a duty cycle of 50%.
Here is a table spanning practical values of OCR2A and prescalers:
OCR2A N=1 N=8 N=32 N=64
1 8000000 1000000 250000 125000
5 2666667 333333 83333 41667
10 1454545 181818 45455 22727
20 761905 95238 23810 11905
40 390244 48780 12195 6098
60 262295 32787 8197 4098
80 197531 24691 6173 3086
100 158416 19802 4950 2475
120 132231 16529 4132 2066
140 113475 14184 3546 1773
160 99379 12422 3106 1553
180 88398 11050 2762 1381
200 79602 9950 2488 1244
255 62500 7813 1953 977
Again, this mode is limited to a 50% duty cycle, and the output frequency is governed by the formula: fclk/((OCR2A+1)*2*N).
The example code above creates a signal on Pin 11 with a frequency of 727.2 kHz and a duty cycle of 50%.
Here is a table of output frequencies spanning the ranges of OCR2A and prescaler values:
OCR2A N=1 N=8 N=32 N=64
1 4000000 500000 125000 62500
5 1333333 166667 41667 20833
10 727273 90909 22727 11364
20 380952 47619 11905 5952
40 195122 24390 6098 3049
60 131148 16393 4098 2049
80 98765 12346 3086 1543
100 79208 9901 2475 1238
120 66116 8264 2066 1033
140 56738 7092 1773 887
160 49689 6211 1553 776
180 44199 5525 1381 691
200 39801 4975 1244 622
255 31250 3906 977 488
Once again (assuming you have skipped down to this part and not read the above cases), the frequencies in this mode can only be changed by selecting the prescaler value, and once set, Pins 3 and 11 will have the exact same frequencies. However, you can set the duty cycles of pins 3 and 11 individually in this mode.
The formula for the frequency of the signal output by both Pins 3 and 11 is: output frequency=fclk/(256*N). This gives rise to the last table (yay!):
N=1 N=8 N=32 N=64 62500 7813 1953 977 Hz
OCR2A and OCR2B are separately used to define the duty cycles of Pins 11 and 3, respectively, using the formula: duty cycle=(255-OCR2A)/255 for Pin 11, and duty cycle=(255-OCR2B)/255 for pin 3.
The example code above creates a signal on Pin 11 with a frequency of 62.5 kHz and a duty cycle of 90%, and a signal on Pin 3 with the same frequency (62.5 kHz) and a duty cycle of 50%.
So there you have it! You need to make a square wave with a specific frequency? I hope this page saves you some time.
https://withinspecifications.30ohm.com/2014/02/20/Fast-PWM-on-AtMega328/ https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM https://playground.arduino.cc/Main/TimerPWMCheatsheet https://www.eprojectszone.com/how-to-modify-the-pwm-frequency-on-the-arduino-part1/
The ATmega328p datasheet from Atmel: https://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_datasheet.pdf