<<< Zpět

typedef unsigned char u8;
typedef unsigned short u16;
#define	B4	0x10

/*=============================================================================

                 Tone generator (speaker connected to PB4)

=============================================================================*/
/* http://www.duzozua.yoyo.pl/raf/doku.php?id=avr:simple_sound_player */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

/* notes */
#define nC	0
#define nCx	1
#define nD	2
#define nDx	3
#define nE	4
#define nF	5
#define nFx	6
#define nG	7
#define nGx	8
#define nA	9
#define nAx	10
#define nB	11

/* efects */
#define PA	32	/* pause */
#define nX	1	/* stop until pause */
#define ED	255	/* end */
#define LP	254	/* loop */

/* frequencies interval */
u16 ntime[] = {
	F_CPU / (2 * 2093),
	F_CPU / (2 * 2217),
	F_CPU / (2 * 2349),
	F_CPU / (2 * 2489),
	F_CPU / (2 * 2637),
	F_CPU / (2 * 2794),
	F_CPU / (2 * 2960),
	F_CPU / (2 * 3136),
	F_CPU / (2 * 3322),
	F_CPU / (2 * 3520),
	F_CPU / (2 * 3729),
	F_CPU / (2 * 3951)
};

#define ROW_DELAY 75

/* sound track "reksio" */
int track[] = {
nC, 4,  PA,PA,  PA,PA,  PA,nX,  nC, 4,  nC, 4,  PA,nX,  nD, 4,  PA,nX,
nE, 4,  PA,nX,  nC, 4,  PA,nX,  nG, 3,  PA,PA,  PA,nX,  PA,PA,  nE, 4,
PA,PA,  PA,nX,  nE, 4,  nC, 4,  PA,nX,  nA, 4,  PA,nX,  nG, 4,  PA,PA,
PA,PA,  PA,PA,  PA,PA,  PA,PA,  PA,PA,

nG, 4,  PA,nX,  nF, 4,  PA,nX,
nD, 4,	PA,PA,  PA,PA,  PA,nX,  nF, 4,  PA,nX,  nE, 4,  PA,nX,  nC, 4,
PA,PA,  PA,PA,  PA,nX,  nD, 4,  PA,PA,  PA,PA,  nE, 4,  nD, 4,  PA,nX,
nC, 4,  PA,nX,  nB, 3,  PA,PA,  PA,PA,  PA,PA,  nG, 3,  PA,PA,  PA,PA,
PA,PA,  LP,LP,  ED,ED,
};

/* current sound frequency */
volatile u16 fr;


/* interrupt routine */
SIGNAL (SIG_OVERFLOW1)
{
	PORTB ^= B4;
	TCNT1 = 0xffff - fr;
}

/* play one tone */
void playtone(int note, int octave)
{
	fr = ntime[note]*(2<<(6-octave));
	TCNT1 = 0xffff - fr;
}

int main(void)
{
	u8 trackptr = 0;
	u8 trkcmd = 0;

	TIMSK = BIT(TOIE1);	/* interrupt with T/C1 */
	TCCR1A = 0;
	TCCR1B = BIT(CS10);

	/* set PB4 to output mode */
	DDRB |= B4;

	fr = 0xffff;
	sei();

	while (1)
	{
		while ((trkcmd = track[trackptr]) != ED)
		{
			switch (trkcmd)
			{
				case LP: // loop
					trackptr = 0;
					continue;

				case PA: // pause
					if (track[trackptr+1] == 1) // stop + pause
					{
						TCCR1B = 0;
						_delay_ms(ROW_DELAY);
					}
					else
						_delay_ms(ROW_DELAY);
					break;
			}

			if (trkcmd < 12)
			{
				TCCR1B = 1;
				playtone(trkcmd, track[trackptr+1] & 0x7f);
				_delay_ms(ROW_DELAY);
				if ((track[trackptr+1] & 0x80) == 1) TCCR1B = 0;
			}
			trackptr += 2;

		}
		trackptr = 0;
	}
}

<<< Zpět