Tone Library for MSP430

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.

Connection Diagram!

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.