⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Mp3 Player using ATmega128, VS1003B, Character LCD. Test OK.Good Sound.
💻 C
字号:
#include <avr/io.h>	// 器飘, 器飘巧 殿捞 急攫登绢 乐澜, 
#include <avr/pgmspace.h>
#include <stdio.h>
#include "global.h"	// U8, u16 殿捞 急攫登绢 乐澜, 庆歹 颇老阑 流立 父电 版快 奴 蝶咳钎("")肺 弓绢淋
#include "delay.h"
#include "usart.h"	// 流纺烹脚 (MCU <-> PC)
#include "spi.h"	// SPI 烹脚 (MCU <-> SD Card, MCU <-> vs1003)
#include "timer.h"

// SD Card
#include "sd/sd.h"

// FAT
#include "fat/fat.h"
#include "fat/filelist.h"

// VS1003
#include "vs1003b/vs1003.h"

// 弊贰侨 LCD
#include "glcd/glcd.h"
#include "glcd/ks0108.h"
#include "glcd/icondef.h"

// 荤侩磊 Key
#include "key/key.h"




// Play Mode Status
#define	PM_STOP			0
#define PM_PLAY			1
#define PM_PAUSE		2

void printLogo(void);
void IoInit(void);
void printSlider(U8 pos);
void MP3Play(struct tagFileInfo fileInfo);

// global variables
extern U8 SecPerClus;					// 茄 Cluster寸 sector 荐(Sector per Cluster)
extern U32 FirstDataSector;			// 霉锅掳 单捞磐 冀磐(焊烹 风飘叼泛配府 浚飘府狼 困摹烙)
extern U32 StartFATSector;				// FAT 矫累 冀磐
extern U32 RootCluster;				// Root Directory狼 努矾胶磐 锅龋(老馆利栏肺 2)

extern struct tagFATBuffer FATBuffer;	// FAT Buffer(1冀磐甫 佬绢坷扁 困茄 滚欺)
extern struct tagDirEntryBuffer DirEntryBuffer;	// 叼泛磐府 浚飘府 Buffer


extern U8 bTimerUpdateName;
extern U8 bTimerKeyLock;
extern U8 bTimerClearVol;


// Mp3 Setting
U8		Mp3Volume=200;

int main(void)
{

	U8 i=0;
	struct tagFileInfo FileInfo;

	// 鸥捞赣客 矫府倔 烹脚阑 鞍捞 劝己拳 矫虐搁 AVR捞 府悸 登绰 泅惑捞 惯积凳
	// 弊犯霸 锭巩俊 叼滚弊矫父 劝己拳 窍辨 官恩
	// 叼滚弊矫父 : 矫府倔 烹脚 劝己拳, 鸥捞赣 厚劝己拳
//	Init_USART(); 	// 流纺烹脚 檬扁拳		

	SD_Init();		// SD墨靛 檬扁拳

	glcdInit();		// 弊贰侨 LCD 檬扁拳

	fatInit();		// FAT 檬扁拳

	VS1003_Init();	// VS1003 檬扁拳

	Timer_Init();

	IoInit();

//	printLogo();


	fatGetDirEntry(RootCluster);

	while(1)
	{
		if (i < DirEntryBuffer.index)
		{
		FileInfo=fatGetFileInfo(DirEntryBuffer.cluster[i], DirEntryBuffer.entry[i]);
		glcdClearScreen();
	//		glcdSetAddress(0, 3);
	//	glcdPutString(FileInfo.fileName, NORMAL);		
		MP3Play(FileInfo);
		i++;
		}

		else
			i=0;
	}


//	fileListBrowse();

//	loadConfig();

//	fileListBrowse();


	return 0;

} // end main


void IoInit(void)
{
    // I/O Port Direction Setting
	Key_DDR = 0x00;	// Input Key

	cbi(VS1003_DDR, VS1003_DREQ);	// Input Vs1003 DREQ Pin

	sbi(LED_DDR, LED_RUN);	// LED Output
	sbi(LED_PORT, LED_RUN);	// LED OFF
}

void printLogo(void)
{
	U8 i;

	glcdClearScreen();
	glcdSetAddress(0, 0);
	glcdPutString(" Ggongchi MP3P  ", NORMAL);
	glcdGotoChar(LINE4, 2);	
	glcdPutStr("  Firmware v0.1   ");
	glcdGotoChar(LINE6, 2);	
	glcdPutStr("Made by Ggongchi");
	glcdRectangle(0, 60, 128, 63);

	for(i=0; i < 128; i++)
	{
		glcdLine(i, 60, i, 63);
		delay_ms(25);
	}
}

void printSlider(U8 pos)	// pos: 0~100
{
	U8 i;
	U8 offset = pos * 0.6;

	if(pos <= 100)
	{
		glcdSetAddress(61, LINE8);
		
		glcdDataWrite(0x38);		// 阜措 哭率
		for(i=0; i<offset; i++)
			glcdDataWrite(0x38);	// 阜措 吝埃(盲框)

		glcdDataWrite(0xFE);		// 器牢磐 哭率
		glcdDataWrite(0x82);		// 器牢磐 吝埃
		glcdDataWrite(0xFE);		// 器牢磐 吝埃
		glcdDataWrite(0x82);		// 器牢磐 吝埃
		glcdDataWrite(0xFE);		// 器牢磐 坷弗率

		for(i=60-offset; i>0; i--)
			glcdDataWrite(0x28);	// 阜措 吝埃(厚框)
		glcdDataWrite(0x38);		// 阜措 坷弗率
	}
}


void MP3Play(struct tagFileInfo fileInfo)
{
	struct VS1003_Mp3Info mp3_info;

	U8 test[30]={0,};

	U8 pos;
	U8 buffer[SECTOR_SIZE];
	U32 index;
	U32 sector;
	U8 nextSector;
	U8 playMode;
	U8 icon_flag = 1;	// sample rate客 bit rate甫 贸澜 茄锅父 免仿登霸 ...
	U32 curCluster, nextCluster;
	U32 byteCount;

	U16 decode_time=0;	// VS1003栏肺何磐 犁积矫埃 钎矫(檬)

	struct tagTime time;
	float volume;

	U8 icon, icon1;
	
	U8 name[MAX_NAME_LEN];
	U8* fileName_ptr = fileInfo.fileName;
	U8 offset;

	// init variables
	playMode = PM_PLAY;
	index = 512;
	byteCount = 0;	// 颇老阑 佬篮 官捞飘 荐
	nextSector = SecPerClus;	// 8 (1GB SD墨靛绰 努矾胶磐寸 8冀磐)
	curCluster = fileInfo.startCluster;	// MP3颇老狼 矫累 努矾胶磐
	sector = fatClusToSec(curCluster);	// 矫累 努矾胶飘肺 颇老狼 矫累 冀磐甫 备窃
	bTimerUpdateName = 1;			// 矫累锭 颇老疙捞 焊咯瘤档废
	bTimerKeyLock = 0;				// 虐 泪陛阑 秦力
	bTimerClearVol = 0;				// 杭俘 钎矫甫 瘤快瘤 臼澜


	VS1003_Write_SCI_Data(VS1003_DCTIME, 0x0000);	// Initialize Decode Time

	// init FAT buffer
	fatBufferInit(curCluster);

	// PLAY 酒捞能 钎矫
	glcdSetAddress(0, 0);
	glcdWriteIcon16(ICON_PLAY);

/*
	if(Config.fadeIn)
		volume = MUTE_VOLUME;
	else
		volume = Config.mp3Volume;
*/
/*
	sta013SetVolume(volume, Config.mp3Balance);
	sta013SetTone(Config.bassEnh, Config.bassFreq, Config.trebleEnh, Config.trebleFreq);
	sta013ResumeDecoder();


	timerReset(TIMER_SEC);	// 鸥捞赣 reset
	timerReset(TIMER_MS);
	timerEnable(TIMER_SEC);	// 鸥捞赣 enable
	timerEnable(TIMER_MS);
*/
	while(playMode)
	{

//		Blink_LED();

		while(VS1003_DREQ_PIN)
		{
			if(index == 512)	// 茄冀磐甫 促 佬菌栏搁 促澜 冀磐甫 佬澜
			{
				SD_Read_Sector(sector++, buffer);	// SD墨靛甫 佬瘤 给窍搁
				index = 0;
				nextSector--;
			}
			
			if(nextSector == 0 && index == 256)	// 付瘤阜 256官捞飘啊 巢栏搁, 促澜 努矾胶磐甫 霖厚窃
			{
				if((nextCluster = fatGetNextCluster(curCluster)) == 0xFFFFFFFF)	// 颇老狼 场捞搁
				{
					playMode = PM_STOP;	// 犁积 辆丰
					break;
				}

				curCluster = nextCluster;
				sector = fatClusToSec(curCluster);	// 努矾胶磐 林家甫 角力 冀磐 林家肺 函券
				nextSector = SecPerClus;
			}

			VS1003_XDCS_LOW();	// xDCS = low, vs1003 劝己拳
				SPI_Transfer_Byte(buffer[index++]);	// vs1003 抹栏肺 MP3 单捞磐 傈价 (1官捞飘)
			VS1003_XDCS_HIGH();	// xDCS = high, vs1003 厚劝己拳
			byteCount++;
		}



/*
		// 鸥捞赣甫 捞侩窍档废 荐沥且 巴
		// Fade-In effect (杭俘阑 辑辑洒 棵覆)
		if(Config.fadeIn && volume <= Config.mp3Volume)
		{
			volume += 0.4;
			sta013SetVolume(volume, Config.mp3Balance);
		}



		// 杭俘钎矫甫 瘤框 (杭俘虐甫 喘范阑 锭 鸥捞赣俊 狼秦 2檬饶 杭俘钎矫甫 瘤框)
		if(bTimerClearVol)
		{
			glcdSetAddress(80, LINE7);
			glcdPutStr("      ");
			bTimerClearVol = 0;
		}


		// 犁积矫埃钎矫
		time = timerGetTime();
		glcdGotoXY(2, 0);
		glcdPutU32Dec16(time.min, 2, NORMAL);
		glcdPutEngChar(':', NORMAL);
		glcdPutU32Dec16(time.sec, 2, NORMAL);
*/


		// 颇老疙 钎矫 (鸥捞赣俊 狼秦 4檬埃拜栏肺 颇老疙 诀单捞飘)
		if(bTimerUpdateName)
		{
			offset = strNcopy(name, fileName_ptr, 16);	// 茄临俊 康巩 16磊鳖瘤 钎矫啊瓷
			
			if(offset > 0)
			{
				glcdSetAddress(0, 2);
				glcdPutString(name, NORMAL);
				fileName_ptr += offset;
				bTimerUpdateName = 0;
			}
			else
				fileName_ptr = fileInfo.fileName;
		}


		// 犁积 困摹 钎矫
		pos = byteCount / (fileInfo.size / 100);
		printSlider(pos);



		VS1003_Get_Mp3info(&mp3_info);
/*
		sprintf(test, "\nID : %d", mp3_info.mp3_ID);
		string(test);

		sprintf(test, "\nSample Rate : %d", mp3_info.sample_rate);
		string(test);

		sprintf(test, "\nBit Rate : %d", mp3_info.bit_rate);
		string(test);
*/

		icon = ICON_STEREO;
		glcdSetAddress(0, LINE7);
		glcdWriteIcon16(icon);

		if (icon_flag == 1)
		{

		if (mp3_info.mp3_ID == 0 || mp3_info.mp3_ID == 1)
		{

			switch(mp3_info.sample_rate)
			{
				default:
				case  0: icon = ICON_11KHZ;	break;
				case  1: icon = ICON_12KHZ;	break;
				case  2: icon = ICON_08KHZ;	break;
			}
		}

		else if (mp3_info.mp3_ID == 2)
		{
			switch(mp3_info.sample_rate)
			{
				default:
				case  0: icon = ICON_22KHZ;	break;
				case  1: icon = ICON_24KHZ;	break;
				case  2: icon = ICON_16KHZ;	break;
			}
		}

		else if (mp3_info.mp3_ID == 3)
		{
			switch(mp3_info.sample_rate)
			{
				default:
				case  0: icon = ICON_44KHZ;	break;
				case  1: icon = ICON_48KHZ;	break;
				case  2: icon = ICON_32KHZ;	break;
			}

			switch(mp3_info.bit_rate)
			{
				default:
				case   2:  icon1 = ICON_040KBPS;	break;
				case   3:  icon1 = ICON_048KBPS;	break;
				case   4:  icon1 = ICON_056KBPS;	break;
				case   5:  icon1 = ICON_064KBPS;	break;
				case   6:  icon1 = ICON_080KBPS;	break;
				case   7:  icon1 = ICON_096KBPS;	break;
				case   8:  icon1 = ICON_112KBPS;	break;
				case   9:  icon1 = ICON_128KBPS;	break;
				case  10:  icon1 = ICON_160KBPS;	break;
				case  11:  icon1 = ICON_192KBPS;	break;
				case  12:  icon1 = ICON_224KBPS;	break;
				case  13:  icon1 = ICON_256KBPS;	break;
				case  14:  icon1 = ICON_320KBPS;	break;
			}
		}

		else if (mp3_info.mp3_ID == 0 || mp3_info.mp3_ID == 1 || mp3_info.mp3_ID == 2)
		{
			switch(mp3_info.bit_rate)
			{
				default:
				case   1:  icon1 = ICON_008KBPS;	break;
				case   2:  icon1 = ICON_016KBPS;	break;
				case   3:  icon1 = ICON_024KBPS;	break;
				case   5:  icon1 = ICON_040KBPS;	break;
				case   6:  icon1 = ICON_048KBPS;	break;
				case   7:  icon1 = ICON_056KBPS;	break;
				case   8:  icon1 = ICON_064KBPS;	break;
				case   9:  icon1 = ICON_080KBPS;	break;
				case  10:  icon1 = ICON_096KBPS;	break;
				case  11:  icon1 = ICON_112KBPS;	break;
				case  12:  icon1 = ICON_128KBPS;	break;
				case  13:  icon1 = ICON_144KBPS;	break;
				case  14:  icon1 = ICON_160KBPS;	break;
			}
		}

		icon_flag = 0;
		glcdSetAddress(18, LINE7);	// sample rate
		glcdWriteIcon16(icon);


		glcdSetAddress(36, LINE7);	// bit rate
		glcdWriteIcon24(icon1);


		}



		decode_time=VS1003_Get_DecodeTime();

		
		glcdSetAddress(70, LINE6);
		sprintf(test, "%d : %d ", (decode_time)/60, decode_time%60);
		glcdPutString(test, NORMAL);
		//glcdPutU32Dec((U32) decode_time, 4);


/*
		// 虐 涝仿 贸府
		switch(KEY_INPUT())
		{
		case KEY_PLAY:
			if(!bTimerKeyLock)	// 虐啊 泪扁瘤 臼疽栏搁
			{
				if(playMode == PM_PLAY)			// 犁积 -> 老矫沥瘤
				{
					sta013PauseDecoder();
					playMode = PM_PAUSE;
					glcdGotoXY(0, 0);
					glcdWriteIcon16(ICON_PAUSE);
					timerDisable(TIMER_SEC);	// 鸥捞赣 老矫沥瘤
				}
				else if(playMode == PM_PAUSE)	// 老矫沥瘤 -> 犁积
				{
					sta013ResumeDecoder();
					playMode = PM_PLAY;
					glcdGotoXY(0, 0);
					glcdWriteIcon16(ICON_PLAY);
					timerEnable(TIMER_SEC);		// 鸥捞赣 犁俺
				}
				timerReset(TIMER_MS);
				bTimerKeyLock = 1;	// debounce 规瘤甫 困秦 虐甫 泪陛
			}
			break;

		case KEY_FF:
			if(!bTimerKeyLock)	// 虐啊 泪扁瘤 臼疽栏搁
			{
				// 沤祸 风凭 眠啊且 巴
				timerReset(TIMER_MS);
				bTimerKeyLock = 1;	// debounce 规瘤甫 困秦 虐甫 泪陛
			}
			break;

		case KEY_REW:
			if(!bTimerKeyLock)	// 虐啊 泪扁瘤 臼疽栏搁
			{
				// 沤祸 风凭 眠啊且 巴
				timerReset(TIMER_MS);
				bTimerKeyLock = 1;	// debounce 规瘤甫 困秦 虐甫 泪陛
			}
			break;

		case KEY_VOL_UP:
			if(!bTimerKeyLock)	// 虐啊 泪扁瘤 臼疽栏搁
			{
				if(Config.mp3Volume < MAX_VOLUME_ATTENUATION)
				{
					Config.mp3Volume += 2;
					sta013SetVolume(Config.mp3Volume, Config.mp3Balance);
				}
				// 杭俘 沥焊 钎矫
				glcdSetAddress(80, LINE7);
				glcdPutStr("VOL");
				glcdSetAddress(100, LINE7);
				glcdPutU32Dec(Config.mp3Volume, 2);

				timerReset(TIMER_MS);
				bTimerKeyLock = 1;	// debounce 规瘤甫 困秦 虐甫 泪陛
			}
			break;

		case KEY_VOL_DN:
			if(!bTimerKeyLock)	// 虐啊 泪扁瘤 臼疽栏搁
			{
				if(Config.mp3Volume > MIN_VOLUME_ATTENUATION)
				{
					Config.mp3Volume -= 2;
					sta013SetVolume(Config.mp3Volume, Config.mp3Balance);
				}
				// 杭俘 沥焊 钎矫
				glcdSetAddress(80, LINE7);
				glcdPutStr("VOL");
				glcdSetAddress(100, LINE7);
				glcdPutU32Dec(Config.mp3Volume, 2);

				timerReset(TIMER_MS);
				bTimerKeyLock = 1;	// debounce 规瘤甫 困秦 虐甫 泪陛
			}
			break;

		case KEY_ENTER:
			sta013SetVolume(MUTE_VOLUME, Config.mp3Balance);
			// pause饶俊 stop窍搁 咯傈洒 棱澜 乐澜, 秦搬且 巴
			index = 5 * 1024;	// 割锅 角氰栏肺 措面 嘛绢辰 蔼烙
			while(index--)		// 滚欺甫 厚快扁 困秦 dummy 单捞磐甫 焊晨
				MP3sendByte(0xFF);
			playMode = PM_STOP;
			break;

		case KEY_FUNC:
			break;

		default:
			break;
		}
		*/
	}
	
	// Pause 饶俊 辆丰窍搁, 棱澜 积扁绰 巩力 秦搬且 巴
	// 犁积捞 辆丰 灯栏搁
/*
	sta013PauseDecoder();
	printf("End play\n\n");
*/

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -