Сделал по http://eldigi.ru/site/house/18.php(там исходник на ИАР), только вывел на ШИМ +добавил буфер 256 байт, чтобы не было паузы во время чтения с флеш (кварц 24.576 МГц (во время прошивания устанавливал 16 Мгц, иначе не шьеться)), звук
8 бит дискр 44100 Гц моно, вполне приемлемо для игрушек. флешка Микро СД 512 МБ,
питание от аккумулятора сотика + усилитель от китайского радио.
вот здесь поменял часть кода исходника
- Код: Выделить всё
/*
---------------------------------------------------------------------------------------------
Глобальные переменные
---------------------------------------------------------------------------------------------
*/
unsigned int count=0;// счетчик байт
unsigned char data[257]; //буфер от пауз
unsigned char song;
unsigned char play;
unsigned char gotoNextSong;
__flash char FileNames [10][11] =
{
"muson01.wav","muson02.wav","muson03.wav","muson04.wav","muson05.wav",
"muson06.wav","muson07.wav","muson08.wav","muson09.wav","muson10.wav"
};
/*
=============================================================================================
Проверка заголовка WAV файла на соответсвие параметрам воспроизведения.
Формат WAV файла должен быть: PCM 8 бит 16000 КГц Моно.
=============================================================================================
*/
unsigned char WaveComp (char const __flash name[])
{
//~~~~~~~~~~~~~
FILE *f;
TitleWave tw;
//~~~~~~~~~~~~~
f = fopenc(name,READ);
if ( f==0 ) return (1); // Не открыть файл
fread(&tw,sizeof(TitleWave),1,f);
fclose(f);
if ( strncmp_G(tw.id_riff,"RIFF",4) != 0 ) return (1); // Не совпал идентификатор RIFF
if ( strncmp_G(tw.id_chuck,"WAVE",4) != 0 ) return (1); // Не совпал идентификатор CHUCK
if ( strncmp_G(tw.fmt,"fmt ",4)!= 0 ) return (1); // Не совпал идентификатор FMT
if ( tw.type != 1 ) return (1); // Тип данных - не выборка
if ( tw.channels != 1 ) return (1); // Не моно
//if (( tw.freq != 16000 )) return (1); // Не 16000 КГц
//if (( tw.bytes != 16000 )) return (1);
if ( tw.bits != 8 ) return (1); // Не 8 бит
return (0);
}
/*
=============================================================================================
MAIN.
=============================================================================================
*/
void main ()
{
unsigned int i=0;
//~~~~~~~~~~
FILE *fp;
//~~~~~~~~~~
OCR2=0x80;
SPSR = 0x01; //setup SPI
//start
while (!initialize_media()){};
PORTD_Bit2 = 1;
PORTD_Bit3 = 1;
// Sleep enable
MCUCR |= (1 << SE);
// External Interrupts enable
GICR |= (1 << INT1)|(1 << INT0);
SEI();
while(1)
{
if (play)
{
GICR &= ~(1 << INT0);
// Timer/Counter 0 initialization
TCCR0 |= (1 << CS01);
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK |= (1 << TOIE0);
if (!WaveComp (FileNames[song]))
{
fp = fopenc(FileNames[song], READ);
OCR2 = 0x80;
DDRD = 0x80;
TCCR2 = 0x69;
while ( ((fp -> position) < (fp -> length)) && !gotoNextSong )
{
while (!count)
{
for (i=0;i<256;i++)
{
data[i]=fgetc(fp);
}
}
SLEEP();
}
DDRD = 0x00;
fclose(fp);
if (!gotoNextSong) play = 0;
gotoNextSong = 0;
}
else song = 0;
TCCR2 = 0x00;
// Stop Timer0
TCCR0 &= ~(1 << CS01);
TIMSK &= ~(1 << TOIE0);
GICR |= (1 << INT0);
}
else SLEEP();
};
}
/*
=============================================================================================
Timer0 interrupt.
=============================================================================================
*/
#pragma vector = TIMER0_OVF_vect
__interrupt void Timer0_Ovf (void)
{
TCNT0 = 0xBD;
OCR2=data[count];
if (count<255) count++;else count=0;
}
/*