Compilation
===========
The sofware is a standalone assembler program. It was compiled using Microchip Studio, which is a rebadged Atmel Studio 7. The .hex file can be uploaded to any ATmega328P using the usual methods (such as avrdude).
Calculations
============
The square waves are generated on the transition of Timer 1 running with a prescale of 8. With a 16MHz instruction clock this is 2MHz. If a fixed number of Timer 1 intervals are used between transitions, the frequencies are sufficiently inaccurate that the error is audible. To overcome this, the interval is extended at intervals by 500ns. The resultant notes are within 0.1Hz of the desired notes.
To calculate the values used by the program, first an accurate frequency is required. This is easily calculated by first calculating the logarithmic interval
10^(log10(2)/12) = 1.0594630943592952645618252949463
By multiplying any desired base frequency by this value 12 times, the twelve notes of the octave are derived. This has been done in the table below.
Next, the note period is required - e.g.
for A7 this is 1/3520 = 2.8409090909090909090909090909091e-4 seconds
This is double the required period between transitions of the output pin, as each cycle of the square wave has a high and a low period. To get the number of 2MHz cycles divide by 2 and multiply by 2,000,000 (or easier, multiply by 1,000,000)
= 284.09090909090909090909090909091
A transition is required every 284 Timer 1 cycles, plus inserting a 285 cycle period every 1/0.09090909090909090909090909091 = 11 cycles. In the program, this is approximated by adding a dither value to a byte, and every time the byte overflows, the period is extended. The dither value is calculated by 0.09090909090909090909090909091 * 256 with rounding = 23. This overflows approximately every 11.13 additions.
To find the generated frequency, the calculation is reversed:
1,000,000/(284+23/256) = 3,520.0132000495001856256960963604 Hz
Here are the calculated values used in the two sources:
Desired Hz Count for half cycle 2MHz clock Dither byte Actual
A7 3520 284 23 3,520.01
A#7 3,729.3100921447193312576250382111 268 37 3,729.33
B7 3,951.0664100489928946460363348707 253 25 3,951.04
C8 4,186.0090448095781548455998963729 238 228 4,186.02
C#8 4,434.9220956299535399805813376194 225 124 4,434.90
D8 4,698.6362866785209642045282217693 212 212 4,698.63
D#8 4,978.0317395532945717819443092181 200 226 4,978.03
E8 5,274.0409106059188757734681767449 189 156 5,274.00
F8 5,587.6517029280621511260038502385 178 247 5,587.69
F#8 5,919.9107633861503829391233526818 168 236 5,919.90
G8 6,271.9269757079887053711924873572 159 113 6,271.90
G#8 6,644.8751612791222163590686229394 150 126 6,644.86
A8 7040 142 12 7,039.93
A#8 7,458.6201842894386625152500764222 134 19 7,458.56
B8 7,902.1328200979857892920726697414 126 140 7,902.21
C9 8,372.0180896191563096911997927458 119 114 8,372.03