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

Схемы и устройства на микроконтроллерах. Обсуждение.
slavabsm
Сообщения: 14
Зарегистрирован: 15 апр 2010, 10:19

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

Сообщение slavabsm » 26 апр 2010, 16:38

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

Griff
Сообщения: 9
Зарегистрирован: 25 апр 2010, 02:17

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

Сообщение Griff » 26 апр 2010, 17:46

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

vik_mix
Сообщения: 8
Зарегистрирован: 27 апр 2010, 06:09

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

Сообщение vik_mix » 27 апр 2010, 06:17

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

slavabsm
Сообщения: 14
Зарегистрирован: 15 апр 2010, 10:19

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

Сообщение slavabsm » 27 апр 2010, 13:24

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

Griff
Сообщения: 9
Зарегистрирован: 25 апр 2010, 02:17

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

Сообщение Griff » 27 апр 2010, 13:58

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

Griff
Сообщения: 9
Зарегистрирован: 25 апр 2010, 02:17

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

Сообщение Griff » 27 апр 2010, 23:59

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

Griff
Сообщения: 9
Зарегистрирован: 25 апр 2010, 02:17

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

Сообщение Griff » 29 апр 2010, 00:23

вот 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[i]); /* 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
Сообщения: 8
Зарегистрирован: 27 апр 2010, 06:09

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

Сообщение vik_mix » 29 апр 2010, 05:12

Griff писал(а):вот 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[i]); /* 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
Сообщения: 9
Зарегистрирован: 25 апр 2010, 02:17

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

Сообщение Griff » 29 апр 2010, 16:52

Не уверен что проект будет работать... надо править 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
Сообщения: 8
Зарегистрирован: 27 апр 2010, 06:09

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

Сообщение vik_mix » 30 апр 2010, 07:42

Griff писал(а):
подскажите как зациклить трек, а наследующий чтобы перескакивал только по нажатию кнопки?
Зациклить функцию 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
Сообщения: 9
Зарегистрирован: 25 апр 2010, 02:17

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

Сообщение Griff » 01 май 2010, 01:30

Зациклить функцию 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
Сообщения: 5
Зарегистрирован: 31 мар 2010, 21:44

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

Сообщение ILUHA_89 » 01 май 2010, 01:52

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

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей