Уведомления
Очистить все

WAV-плеер по схеме Elm Chan`а

211 Посты
69 Пользователи
0 Likes
192.7 Тыс. Просмотры
slavabsm
(@slavabsm)
Active Member
Присоединился: 14 лет назад
Сообщения: 14
 

Нужно ,чтобы очередная мелодия проигрывалась только по нажатию кнопки, т.е. подал питание, нажал кнопку - проигралась одна мелодия, , а следущая только по нажатию на кнопку и т.д.- хотелось бы сделать дверной звонок.


ОтветитьЦитата
Griff
(@griff)
Active Member
Присоединился: 14 лет назад
Сообщения: 9
 

понял, тоесть нужна ещё одна кнопка для выбора мелодии а первая для запуска мелодии? или оставить так, а включать мелодию по ресету будешь?


ОтветитьЦитата
vik_mix
(@vik_mix)
Active Member
Присоединился: 14 лет назад
Сообщения: 8
 

не получается запихать в tiny45
отключил всё что можно - _USE_DIR =0
_USE_LSEEK = 0
_FS_FAT32 = 0
соответственно в главном цикле остался только play("sound.wav");
в итоге не хватает озу
97% program
141% data !


ОтветитьЦитата
slavabsm
(@slavabsm)
Active Member
Присоединился: 14 лет назад
Сообщения: 14
 

понял, тоесть нужна ещё одна кнопка для выбора мелодии а первая для запуска мелодии? или оставить так, а включать мелодию по ресету будешь?
А зачем вторая кнопка? В оригинале при включении питания мелодии начинают воспроизводиться сразу после подачи питания, а кнопкой просто перескакивается на следущую, что для квартирного звонка и не нужно. Поэтому можно обойтись одной кнопкой, которая при нажатии будет запускать очередной ОДИН трек!


ОтветитьЦитата
Griff
(@griff)
Active Member
Присоединился: 14 лет назад
Сообщения: 9
 

А зачем вторая кнопка? В оригинале при включении питания мелодии начинают воспроизводиться сразу после подачи питания, а кнопкой просто перескакивается на следущую, что для квартирного звонка и не нужно. Поэтому можно обойтись одной кнопкой, которая при нажатии будет запускать очередной ОДИН трек!
так в таком случае прийдётся кнопку звонка удерживать чтобы трек до конца проиграл... вообщем с фузами разобрался, сегодня накидаю


ОтветитьЦитата
Griff
(@griff)
Active Member
Присоединился: 14 лет назад
Сообщения: 9
 

оппа... очередная засада. подскажите какой версией WinAVR компилировали проэкт?


ОтветитьЦитата
Griff
(@griff)
Active Member
Присоединился: 14 лет назад
Сообщения: 9
 

вот main.c для тех у кого нет attiny 85, это под 45.

////////////////////////////////////////////////////////////////////////////////////////////////////
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include "diskio.h"
#include "pff.h"

#define FCC(c1,c2,c3,c4) (((DWORD)c4<<24)+((DWORD)c3<<16)+((WORD)c2<<8)+(BYTE)c1) /* FourCC */

/*---------------------------------------------------------*/
/* Work Area */
/*---------------------------------------------------------*/

volatile BYTE FifoRi, FifoWi, FifoCt; /* FIFO controls */

BYTE Buff[180]; /* Wave output FIFO */

static
DWORD load_head (void)
{
DWORD fcc, sz;
UINT i;
FRESULT res;

res = pf_read(Buff, 180, &rb); /* Load file header (180 bytes) */
if (res || rb != 180) return res;
if (LD_DWORD(Buff+8) != FCC('W','A','V','E')) return 12;

i = 12;
while (i < 124) {
fcc = LD_DWORD(&Buff); /* FCC */
sz = LD_DWORD(&Buff[i+4]); /* Chunk size */
i += 8;
switch (fcc) {

case FCC('f','m','t',' ') : /* 'fmt ' chunk */
if (sz > 100 || sz < 16) /* Check chunk size */
return 10;
if (Buff[i+0] != 1) /* Check coding type (1) */
return 11;
if (Buff[i+2] != 1 && Buff[i+2] != 2) /* Check channels (1/2) */
return 11;
GPIOR0 = Buff[i+2]; /* Channel flag */
if (Buff[i+14] != 8 && Buff[i+14] != 16)/* Check resolution (8/16) */
return 11;
GPIOR0 |= Buff[i+14]; /* Resolution flag */
OCR0A = (BYTE)(F_CPU / 8 / LD_WORD(&Buff[i+4])) - 1;/* Sampling freq */
break;

case FCC('f','a','c','t') : /* 'fact' chunk (skip) */
break;

case FCC('d','a','t','a') : /* 'data' chunk (start to play) */
fs.fptr = i;
return sz;

default : /* Unknown chunk (error) */
return 14;
}
i += sz;
}

return 15;
}

static
FRESULT play (
const char *fn
)
{
DWORD sz;
FRESULT res;
BYTE sw;
WORD btr;

wdt_reset();
if ((res = pf_open(fn)) == FR_OK) {

sz = load_head(); /* Load file header */
if (sz < 180) return 99;

fs.flag |= FA_STREAM; /* Set stream mode */

FifoCt = 0; FifoRi = 0; FifoWi = 0; /* Reset FIFO */
res = pf_read(0, 512 - fs.fptr, &rb);/* Snip sector unaligned part */
sz -= rb;

sw = 1; /* Button status flag */
do {
/* Forward audio data */
btr = (sz > 1024) ? 1024 : (WORD)sz;
res = pf_read(0, btr, &rb);
if (res != FR_OK || btr != rb) break;
sz -= rb;
/* Check button down and break on button down */
sw <<= 1;
if (bit_is_clear(PINB, 0) && ++sw == 1) break;
wdt_reset();
} while (rb == 1024); /* Repeat until all data read */
}

while (FifoCt) ; /* Wait for FIFO empty */
OCR1A = 128; OCR1B = 128;

return res;
}

/*-----------------------------------------------------------------------*/
/* Main */

int __attribute__((naked)) main (void)
{
BYTE res;

MCUSR = 0; /* Enable WDT */
wdt_enable(WDTO_1S);

// OSCCAL += 2; /* Adjust internal osc */

PORTB = 0b111011; /* Initialize port: - - H H H L H P */
DDRB = 0b111110;

PLLCSR = 0b00000110; /* Select PLL clock for TC1.ck */
GTCCR = 0b01100000; /* Enable TC1.OCB as PWM out (L-ch) */
OCR1B = 128;
#if STEREO
TCCR1 = 0b01100001; /* Start TC1 with TC1.OCA is enabled as PWM out (R-ch) */
OCR1A = 128;
#else
TCCR1 = 0b00000001; /* Start TC1 */
#endif

TCCR0A = 0b00000010; /* Enable TC0.ck = 2MHz as interval timer */
TCCR0B = 0b00000010;
OCR0A = 255;
TIMSK = _BV(OCIE0A);
GPIOR0 = 1;

sei();

for (;;) {
res = pf_mount(&fs); /* Initialize FS */
if (res) continue;

Buff[0] = 0; /* Open sound file directory (root dir) */
res = pf_opendir(&dir, (char*)Buff);
if (res) continue;

for (;;) { /* Play all files in the dir */
res = pf_readdir(&dir, &fno);
if (res || !fno.fname[0]) break;
if (fno.fattrib & (AM_DIR|AM_HID)) continue;
res = play(fno.fname);
if (res) break;
}
}

for(;;) ;
}


ОтветитьЦитата
vik_mix
(@vik_mix)
Active Member
Присоединился: 14 лет назад
Сообщения: 8
 

вот main.c для тех у кого нет attiny 85, это под 45.

////////////////////////////////////////////////////////////////////////////////////////////////////
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include "diskio.h"
#include "pff.h"

#define FCC(c1,c2,c3,c4) (((DWORD)c4<<24)+((DWORD)c3<<16)+((WORD)c2<<8)+(BYTE)c1) /* FourCC */

/*---------------------------------------------------------*/
/* Work Area */
/*---------------------------------------------------------*/

volatile BYTE FifoRi, FifoWi, FifoCt; /* FIFO controls */

BYTE Buff[180]; /* Wave output FIFO */

static
DWORD load_head (void)
{
DWORD fcc, sz;
UINT i;
FRESULT res;

res = pf_read(Buff, 180, &rb); /* Load file header (180 bytes) */
if (res || rb != 180) return res;
if (LD_DWORD(Buff+8) != FCC('W','A','V','E')) return 12;

i = 12;
while (i < 124) {
fcc = LD_DWORD(&Buff); /* FCC */
sz = LD_DWORD(&Buff[i+4]); /* Chunk size */
i += 8;
switch (fcc) {

case FCC('f','m','t',' ') : /* 'fmt ' chunk */
if (sz > 100 || sz < 16) /* Check chunk size */
return 10;
if (Buff[i+0] != 1) /* Check coding type (1) */
return 11;
if (Buff[i+2] != 1 && Buff[i+2] != 2) /* Check channels (1/2) */
return 11;
GPIOR0 = Buff[i+2]; /* Channel flag */
if (Buff[i+14] != 8 && Buff[i+14] != 16)/* Check resolution (8/16) */
return 11;
GPIOR0 |= Buff[i+14]; /* Resolution flag */
OCR0A = (BYTE)(F_CPU / 8 / LD_WORD(&Buff[i+4])) - 1;/* Sampling freq */
break;

case FCC('f','a','c','t') : /* 'fact' chunk (skip) */
break;

case FCC('d','a','t','a') : /* 'data' chunk (start to play) */
fs.fptr = i;
return sz;

default : /* Unknown chunk (error) */
return 14;
}
i += sz;
}

return 15;
}

static
FRESULT play (
const char *fn
)
{
DWORD sz;
FRESULT res;
BYTE sw;
WORD btr;

wdt_reset();
if ((res = pf_open(fn)) == FR_OK) {

sz = load_head(); /* Load file header */
if (sz < 180) return 99;

fs.flag |= FA_STREAM; /* Set stream mode */

FifoCt = 0; FifoRi = 0; FifoWi = 0; /* Reset FIFO */
res = pf_read(0, 512 - fs.fptr, &rb);/* Snip sector unaligned part */
sz -= rb;

sw = 1; /* Button status flag */
do {
/* Forward audio data */
btr = (sz > 1024) ? 1024 : (WORD)sz;
res = pf_read(0, btr, &rb);
if (res != FR_OK || btr != rb) break;
sz -= rb;
/* Check button down and break on button down */
sw <<= 1;
if (bit_is_clear(PINB, 0) && ++sw == 1) break;
wdt_reset();
} while (rb == 1024); /* Repeat until all data read */
}

while (FifoCt) ; /* Wait for FIFO empty */
OCR1A = 128; OCR1B = 128;

return res;
}

/*-----------------------------------------------------------------------*/
/* Main */

int __attribute__((naked)) main (void)
{
BYTE res;

MCUSR = 0; /* Enable WDT */
wdt_enable(WDTO_1S);

// OSCCAL += 2; /* Adjust internal osc */

PORTB = 0b111011; /* Initialize port: - - H H H L H P */
DDRB = 0b111110;

PLLCSR = 0b00000110; /* Select PLL clock for TC1.ck */
GTCCR = 0b01100000; /* Enable TC1.OCB as PWM out (L-ch) */
OCR1B = 128;
#if STEREO
TCCR1 = 0b01100001; /* Start TC1 with TC1.OCA is enabled as PWM out (R-ch) */
OCR1A = 128;
#else
TCCR1 = 0b00000001; /* Start TC1 */
#endif

TCCR0A = 0b00000010; /* Enable TC0.ck = 2MHz as interval timer */
TCCR0B = 0b00000010;
OCR0A = 255;
TIMSK = _BV(OCIE0A);
GPIOR0 = 1;

sei();

for (;;) {
res = pf_mount(&fs); /* Initialize FS */
if (res) continue;

Buff[0] = 0; /* Open sound file directory (root dir) */
res = pf_opendir(&dir, (char*)Buff);
if (res) continue;

for (;;) { /* Play all files in the dir */
res = pf_readdir(&dir, &fno);
if (res || !fno.fname[0]) break;
if (fno.fattrib & (AM_DIR|AM_HID)) continue;
res = play(fno.fname);
if (res) break;
}
}

for(;;) ;
}

Не уверен что проект будет работать... надо править asmfunc.S там есть строчка
4: lds r24, FifoCt ;wait while FIFO full
cpi r24, 252 ;
возможно ещё гдето..
Обратите внимание - в свежих исходниках на ф-юю LoadHead:
.....
if (pf_read(Buff, 12, &rb)) return 1; /* Load file header (12 bytes) */
....


ОтветитьЦитата
Griff
(@griff)
Active Member
Присоединился: 14 лет назад
Сообщения: 9
 

Не уверен что проект будет работать... надо править asmfunc.S там есть строчка
4: lds r24, FifoCt ;wait while FIFO full
cpi r24, 252 ;
возможно ещё гдето..
Обратите внимание - в свежих исходниках на ф-юю LoadHead:
.....
if (pf_read(Buff, 12, &rb)) return 1; /* Load file header (12 bytes) */
....
да, там тоже править нужно....
подскажите как зациклить трек, а наследующий чтобы перескакивал только по нажатию кнопки?


ОтветитьЦитата
vik_mix
(@vik_mix)
Active Member
Присоединился: 14 лет назад
Сообщения: 8
 

подскажите как зациклить трек, а наследующий чтобы перескакивал только по нажатию кнопки?

Зациклить функцию play както так:
....
flag = 1;
While(flag)res = play(fno.fname);
....
В функции play() найти обработку кнопки и добавить к ней сброс флага:
....
if (bit_is_clear(PINB, 0) && ++sw == 1) { flag =0; break; }
....
и незабыть объявить глобальную переменную flag
volatile BYTE FifoRi, FifoWi, FifoCt; /* FIFO controls */
unsigned char flag;


ОтветитьЦитата
Griff
(@griff)
Active Member
Присоединился: 14 лет назад
Сообщения: 9
 

Зациклить функцию play както так:
....
flag = 1;
While(flag)res = play(fno.fname);
....
В функции play() найти обработку кнопки и добавить к ней сброс флага:
....
if (bit_is_clear(PINB, 0) && ++sw == 1) { flag =0; break; }
....
и незабыть объявить глобальную переменную flag
volatile BYTE FifoRi, FifoWi, FifoCt; /* FIFO controls */
unsigned char flag;
блин... конфликт с прерываниями получаеться.....While(flag)res = play(fno.fname);... res...а автор конечно красавчек.... для меня высший пилотаж запихнуть всё это в восьминожку


ОтветитьЦитата
ILUHA_89
(@iluha_89)
Active Member
Присоединился: 14 лет назад
Сообщения: 5
 

У меня тоже не получается с attiny45!
Если у кого то получилось отпишитесь...


ОтветитьЦитата
vik_mix
(@vik_mix)
Active Member
Присоединился: 14 лет назад
Сообщения: 8
 

Зациклить функцию play както так:
....
flag = 1;
While(flag)res = play(fno.fname);
....
В функции play() найти обработку кнопки и добавить к ней сброс флага:
....
if (bit_is_clear(PINB, 0) && ++sw == 1) { flag =0; break; }
....
и незабыть объявить глобальную переменную flag
volatile BYTE FifoRi, FifoWi, FifoCt; /* FIFO controls */
unsigned char flag;
блин... конфликт с прерываниями получаеться.....While(flag)res = play(fno.fname);... res...а автор конечно красавчек.... для меня высший пилотаж запихнуть всё это в восьминожку

While с маленькой буквы попробуй ) while...


ОтветитьЦитата
ILUHA_89
(@iluha_89)
Active Member
Присоединился: 14 лет назад
Сообщения: 5
 

Может кто нибудь проект под attiny45 выложить?


ОтветитьЦитата
Griff
(@griff)
Active Member
Присоединился: 14 лет назад
Сообщения: 9
 

to vik_mix!!!!
да СПАСИБО!!! получилось, компилятор res не понимал..
Может кто нибудь проект под attiny45 выложить?
я ж выкладывал main под 45 тини, только инклуды нужно немного подправить


ОтветитьЦитата
Страница 5 / 15