Tutorial 2 Timer and Music Examples

Task 1. Complete the music note spreadsheet and play them with two buttons. (30 points)

The goal of this tutorial is to output a sound when a button is pressed. The strategy is when the button is pressed (slow compared to a computer system), the timer will count, overflow, and reset for many times, each time it overflows (as a flag), the digital I/O is toggled. The counts in a timer can be modified so the time it takes to overflow a timer is customizeable. In this case, it creates a certain frequency at the I/O which becomes a certain tone for a music note.


Let's calculate the TIMER1 counts first.

Duplicate the following tabel into a excel spreadsheet.

Index Note Freq (Hz) 3 sig figs Period (ms) 3 sig figs Half period (ms) 3 sig figs TMR1 cnts
0 A4 440      
1 A#4 466      
2 B4 494      
3 C4 523      
4 C#4 554      
5 D4 587      
6 D#4 622      
7 E4 659      
8 F4 698      
9 F#4 740      
10 G4 784      
11 G#4 831      
12 A5 880      
13 A#5 932      
14 B5 987      
15 C5 1046      
16 C#5 1108      
17 D5 1174      
18 D#5 1244      
19 E5 1318      
20 F5 1396      
21 F#5 1479      
22 G5 1567      
23 G#5 1660      
24 A6 1759      
25 A#6 1864      
26 B6 1975      
27 C6 2092      
28 C#6 2216      
29 D6 2348      
30 D#6 2488      
31 Ultrasonic 31,000      

Music scale has the following properties:





This is how Column C were calculated.





Apply the function shown in the following snapshot. It is basically 1.059453^1, and rounded to 0 number of digits after the decimal points (intergers only).



For column D, find the periods in mlli seconds.



In column E, find the half peiod in milli seconds.



Timers 0 and 2 are 8-bit timers; Timers 1, 3, 4, and 5 are 16-bit timers.
Here is the example code for this tutorial.

Given that the prescaler is set at 1:1 which will be counted 16x10^6 per second (16 MHz). The TIMER1 counts should be calculated as follows:

For example 3 ms is the half period, counts should be 3*16000000/1000, it oscillates 16M times a second to counts to 3/1000 second, it should count up to 16M * 3/1000
Timer1 is 16 bits so if it counts from 0, it will count for 2^16 times until overflow occurs. When the counter is up, the speaker pin toggles once.
In column F, find the counts needed within this half period using this timer.

Here are the relevant registers for this example.









Here is the demo video:



Task 2. Play a longer song automatically (70 points)

From the kid songs website you can select the song you prefer. 
The goal of this task is to play longer music notes automatically. Since no one is going to press a button to play a note so certain time intervals must be defined.

Program requirements:
uint16_t scale[6] = {9088, 8112, 7232, 12144, 10816, 9632};  // Frequencies as timer counts
uint8_t notes[14] = {E4, E4, B5, B5, C_5, C_5, B5, A5, A5, G_4, G_4, F_4, F_4, E4};//The song

C_5 means C#5 in the spreadsheet.

The symbols in the notes array "B5", "A5", etc. are #defined to index in the scale array which contains the half period of that note. For example, since the half period of a E4 note is 12144 timer 3 counts (which is index 4 in the scale array defined above), my code contains the following #define at the top of the program:

            #define E4 3

The 1:256 prescaler will slow down the 16MHz clock by 256 times for TIMER1. Which gives you 16000000/256 = 62500 Hz. 62500 counts/s * 0.5 seconds gives you 31250 counts.

Play the first two lines of the song Twinkle Twinkle Little Star




The demo video: