We all like things that sound..About a month ago, A friend of mine asked me to make her a musical card..which she wanted to gift to a friend who is a guitarist( She herself knows Piano). She wanted to dedicate the song she made to her..So, she gave me the tones and durations of each tone..So that i can code it and play the tune..Since, Its all monotonic ..so it didnt felt like a piano..but the tone was clear.
The one I gave her had a MSP430g2211. Just to test the tune settings earlier, I had played Happy Birthday..By borrowing the notes from a website.
The notes were:
c c d c f e
c c d c g f
c c highc a bflat g
a a bflat f g f
Earlier.. I made it using the traditional delay way. But later, I figured out how to do it using the Hardware PWM. The trick is that every note has a particular frequency.If we set the channel for half the duration and then reset it for the next half. We get a PWM of 50% Duty cycle at the given frequency..Taddaa..Thats all..instead of generating a sine wave, we are making a square wave.
The exact tested frequency for the notes are available here !
This is the function i coded:
void tone(int tone,int duration) //Tone macro and duration in millisecs.Play other frq simply divide it (smclk/notef) to get the counter period and feed it into the function
{ int i;
for(i=0;i<duration;i++)
{ CCR0=tone; //Tone length
CCR1=tone/2; //Half Tone ON and Half tone OFF i.e 50% duty!
_delay_cycles(1000);
}
}
Now another problem ..was that how to stop the Tone..since it(tone generation) is not done using software bit-banging ..I can`t set the Output to Zero just by clearing the bit..but we can definitely make the period zero. This is how i coded the notone function:
void notone(int i) //To stop the tone can`t use delay_ms as its a hardware PWM not software!
{
CCR0=0; //make main period zero..it doesnt work when you set CCR1 to zero because it will always set-reset at zero.
delay_ms(i);
}
Now we need a toneInit() Function..to initialize the PWM:
void toneInit() //Initialise The Timers
{
CCTL1 = OUTMOD_7; // CCR1 reset/set
TACTL = TASSEL_2 + MC_1; // SMCLK, up mode
}
Hope You all like it. If anyone wants the Complete Code..He/She can comment with the email id. The comments are moderated.So don`t worry about your mail ids going public. 🙂
Here`s the video..Wish a geek Happy Birthday!
I know the camera is bad! The tone can be tinkered/tuned a bit..I leave to the reader.. 😛
UPDATE: 30th Nov`12
Pingback: Littlebirdelectronics.com
Update 6th Dec:
You can fork the code from github here.
