Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.05.2012, 13:56   #1
antowka1987
Новичок
Джуниор
 
Регистрация: 17.05.2012
Сообщений: 2
По умолчанию C++ плюс МК

Товарищи, решил собрать небольшую штучку, просто для эксперемента и новых познаний. Это простой проигрыватель wav файлов на микроконтроллере. Нашёл готовые исходники, но по функционалы, там не так как мне хотелось бы, вот код main.c:

Код:
#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[256];		/* Wave output FIFO */

FATFS fs;			/* File system object */
DIR dir;			/* Directory object */
FILINFO fno;		/* File information */

WORD rb;			/* Return value. Put this here to avoid bugs of avr-gcc */


/*---------------------------------------------------------*/

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


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

	i = 12;
	while (i < 200) {
		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 < 256) 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(;;) ;
}
Плеерок спаял, отлично заработал, проигрывает песни по порядку, одну за одной, подряд. А я хочу добиться, чтобы крутилась одна песня бесконечно, а если нажать кнопку back то переходил на вторую песню, и её крутил по кругу до тех пор пока не нажать кнопку back. Кстати в плеере всего одна кнопка, back и других нет, за ненадобностью. Т.е. при подаче питания он автоматом начинает играть песенки по порядку.
antowka1987 вне форума Ответить с цитированием
Старый 17.05.2012, 13:56   #2
antowka1987
Новичок
Джуниор
 
Регистрация: 17.05.2012
Сообщений: 2
По умолчанию

На сколько хватило мне познаний в С++, я понял что всё это обрабатывается вот в этом кусочке

Код:
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;
		}
Я попробовал, функцию play зациклить так:
Код:
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;

for(;;){
			res = play(fno.fname);
			if(sw=1) break;  // добавил выход из цикла, при условии нажатия кнопки sw(она же back)
}

if (res) break;
		}
но это не сраслось, тип проигрывания не изменился.

есть задумка ещё:

Код:
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) continue;  //убрать отсюда break, чтобы не мог выйти из цикла
		}
Но этот вариант не опробывал, так как, нет дебагера, а постоянно выпаивать впаивать МК, геморно очень. Вот хотелось бы услышать мнения спецов )))
antowka1987 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужна программа Делфи плюс БД nightly Фриланс 5 12.05.2012 13:53
Посоветуйте литературку по C плюс плюс gefest58 Свободное общение 16 29.01.2011 01:03
делфи плюс приложения вконтакте DeDoK Свободное общение 5 19.03.2010 12:30
Edit ругается на плюс. harrison Помощь студентам 2 03.02.2010 18:29
Программа типа Консультант плюс Жемчужинка БД в Delphi 0 24.04.2008 14:42