This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Simple tune player on MSP430 Launchpad with MSP430G2553



A little project I've been trying to complete for the past 25 years, since I saw (heard) it on my first 80286 PC. A small executable Bach.exe was playing C.P.E Bach's Solfeggietto. Not sure who was the genius behind it, but always wanted to thank him. Anyway, to exercise skills in Timer operation with TA0 Out (tone) and TA1 ISR (Duration) and a little bit of math I've created the attached code. All comments are welcome!

/*
 * main_Player.c
 * simple tune player on MSP430G2553 (2 timers required)
 * piezo buzzer is connected to P1.1 TA0 Out.
 * Tune format:
 * Ox-Octave x (1-7) Can be omitted
 * C,D,E,F,G,A,B  major notes
 * + or - for sharp and flat
 * 16, 9 and 4 for duration.
 * Example O2E-16, C4, O5F+9, G16
 *  Created on: Apr 26, 2014
 *      Author: Arsen Norman
 */
#include <msp430g2553.h>
#include "math.h"
#include "CPEBach.h"

#define OUT0	BIT1
#define SW2		BIT3

int i;
int Octave;
int Note;
float NoteN;
int Key;
int Duration;
float Freq;

void main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    BCSCTL1 = CALBC1_1MHZ;				// Set DCO to 16MHz
    DCOCTL = CALDCO_1MHZ;				// Set DCO to 16MHz

	P1DIR |= OUT0;// + BIT4;
	P1SEL |= OUT0;// + BIT4;
	P1DIR &= ~SW2;						//*((char *)0x22) &= ~SW2;
	P1REN |= SW2;
	P1OUT |= SW2;
	P1IES &= ~SW2;
	P1IFG &= ~SW2;
	P1IE |= SW2;

	TA0CTL = TACLR;
	TA0CTL = TASSEL_2 + ID_0 ;
	TA0CCR0 = 62499;
	TA0CCTL0 |= OUTMOD_4;

	TA1CTL = TACLR;
	TA1CTL = TASSEL_2 + ID_3 ;
	TA1CCR0 = 0x4000;
	TA1CCTL0 |= CCIE;

	for (;;){
		_nop();
		_BIS_SR(CPUOFF + GIE);			// Enter LPM0 w/interrupt
		_nop();
		_nop();
//		anal = pi()/Nexp();
	}
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer1_A0(void){
//	TA1CTL &= ~MC_1;
	int byte;
	byte = FEBACH[i++];
	if (byte=='O') {
		Octave = FEBACH[i++]-0x30;
		Note = FEBACH[i++];
	} else if(byte=='.'){
		TA1CTL &= ~MC_1;
		TA0CTL &= ~MC_1;
	} else {
		Note = byte;
	}
	byte = FEBACH[i++];
	if (byte=='-') {
		Key=-1;
		byte = FEBACH[i++];
		if (byte=='1') {
			Duration = 0x4000;
			i++;
		}else if (byte=='9'){
			Duration = 0x8000;
		} else {
			Duration = 0xFFFE;
		}
	} else if (byte=='+'){
		Key=1;
		byte = FEBACH[i++];
		if (byte=='1') {
			Duration = 0x4000;
			i++;
		}else if (byte=='9'){
			Duration = 0x8000;
		} else {
			Duration = 0xFFFE;
		}
	} else if (byte=='1') {
		Key=0;
		Duration = 0x4000;
		i++;
	}else if (byte=='9'){
		Key=0;
		Duration = 0x8000;
	} else {
		Key=0;
		Duration = 0xFFFE;
	}
	NoteN= (12*(Octave+1)) + Score[Note-65] + Key;
	Freq = 440*powf(2,((NoteN-49)/12));
	TA0CCR0 = (int)(1000000/(2*Freq))-1;
	TA1CCR0 = Duration;
	_nop();
}

#pragma vector=PORT1_VECTOR
__interrupt void Port1_ISR(void){
	i=0;
	TA0CTL |= MC_1;
	TA1CTL |= MC_1;
	P1IFG &= ~SW2;
	_nop();
//	_BIC_SR_IRQ(CPUOFF);				// Exit LPM0
}

6840.CPEBach.h

**Attention** This is a public forum