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

📄 atmel mp3.c

📁 89c51snd1c的FLASH MP3 U盘的详细代码
💻 C
📖 第 1 页 / 共 2 页
字号:
void KeyBoardInit();


void MP3FsInit(unsigned char NDIV, unsigned int RDIV, unsigned char MPCD, unsigned char AUCD)
{
	PLLNDIV = 0;
	PLLRDIV = 0;
	MP3CLK = 0;
	AUDCLK = 0;
                                                     //PLL时钟的频率计算方法
	                                                 //PLLclk=(OSCclk*(RDIV+1))/(int)(NDIV+1);
	                                                 //set PLL CLK
	PLLNDIV	= 0x7f&NDIV;                             //set NDIV
	PLLCON	|= (0x3&RDIV) << 6;                      //set RDIV
	PLLRDIV	= (0x3ff&RDIV) >> 2;
                                                     //MP3时钟频率的计算方法
	                                                 //MP3CLK=PLLCLK/(int)(MPCD+1)负反馈
	MP3CLK |= MPCD;                                  //0000 0010 MPCD=2	
	                                                 //必须通过计算得到最小 MP3CLK 24M
                                                     //AUDCLK计算公式
	                                                 //AUDCLK=PLLCLK/(int)(AUCD+1)负反馈
	AUDCLK  |= AUCD;	                             //AUCD=4   必须通过计算得到 AUDCLK=12.288MHz              

}

void PllInit(void)
{
	if (FirstStart)
	{
		AUXR1 = 0xf2;	                             //这两个寄存器的值在用Start Application和直接上电时
		                                             //不一样,前一种情况下MP3解码器才工作,
		PLLCON = 0;	                                 //这里强制将其置为与用Start Application按钮时一致
		FirstStart = 0;
	}
	                                                 //锁相环时钟及MP3解码器时钟设置
	CKCON |= X2;		                             //0000 0001使能X2模式,增加处理速度,
	                                                 //每个机器周期变成6个振荡周期即3个时钟周期

	PLLCON &= (~PLLRES);                             //Enable PLL
	PLLCON |= PLLEN;
}

void MP3Init(void)
{
	                                                  //MP3音量及音效初始值
	MP3VOR = 0x0a;                                    //0000 1111下同
	MP3VOL = 0x0a;
	MP3BAS = 0x0f;
	MP3MED = 0x0f;
	MP3TRE = 0x0f;

	                                                  //MP3CON自动上电为0011 1111
	MP3CON &= (~MSKREQ);	                          //允许产生MP3中断Clear to allow the 
	                                                  //MPREQ flag to generate a MP3 interrupt.
	MP3CON |= MPEN;	                                  //使能MP3解码器Set to enable the MP3 decoder.
}

void AudioInit()
{	
    unsigned char i = 10;
	AUDCON0 = 0x77;                                    //0111 0110
	AUDCON1 &= (~0xB0);                                //SRC=0,MSREQ=0,MUDRN=0
	AUDCON1 |= 0x01;
	while (i)i--;
	AUDCON1 |= 0x40;
}

void MP3_Init(void)
{
	PllInit();
	MP3Init();
	AudioInit();
}

void PlayInit(unsigned char *SongName)
{
		int i = 0, j = 0, f = 0;
		int k = 0;
		unsigned int total_size;
/*		分析MP3信息,可能会比较长,但是没有别的办法	
		先要读出一部分文件内容,大小不能确定			*/
		m = ReadSector(SongName, Page_Buf);                               //先读出512字节
/*		when the first 3 bytes are 49 44 33 the next can be 03,this means ID3 V2.3  */
			if (Page_Buf[0] == 0x49)
				if ((Page_Buf[1] == 0x44) && (Page_Buf[2] == 0x33))
				{
/**********		 search the 7th-10th bytes,use the formular to calculate ***********/
					total_size = (Page_Buf[6] & 0x7F) * 0x200000 + (Page_Buf[7] & 0x7F) * 0x4000 + (Page_Buf[8] & 0x7F) * 0x80 + (Page_Buf[9] & 0x7F);

					while (total_size > 512)
					{
						ReadSector(SongName, Page_Buf);
						total_size -=512;
					}

					i = total_size;
				}
			                                                    //如果接下来是FFF则为MP3帧头,如果
																//不是则为扩展标签头,需要加10个字节的量
			if (Page_Buf[i] != 0xFF)
				i += 10;

			                                                                 
			if ((Page_Buf[i] == 0xFF) && (Page_Buf[i + 1] & 0xF0 == 0xF0))//get MP3 information from FF FX XX XX 4bytes,
			                                                              //and show that
			{
				MP3_Framehead[0] = Page_Buf[i];
				MP3_Framehead[1] = Page_Buf[i + 1];
				MP3_Framehead[2] = Page_Buf[i + 2];
				MP3_Framehead[3] = Page_Buf[i + 3];
			}

			if (MP3_Framehead[1] & 0x08) 
			{
//				MP3_Init();
				switch ((MP3_Framehead[2] & 0x0C) >> 2) 
				{
					case 0x00 : MP3FsInit(24, 126, 3, 5); printuf("Fs=44.1kHz", 0);break;          //Fs=44.1kHz
					case 0x01 : MP3FsInit(124, 575, 3, 4); break;         //Fs=48kHz
					case 0x02 : MP3FsInit(124, 511, 3, 9); AUDCON0 = 0x76; break;//Fs=32kHz
					default : break;
				}
			} 
			else 
			{
//				MP3_Init();
				switch ((MP3_Framehead[2] & 0x0C) >> 2)
				{
					case 0x00 : MP3FsInit(24, 126, 3, 11);printuf("Fs=22.05kHz", 0);break;         //Fs=22.05kHz
					case 0x01 : MP3FsInit(124, 575, 3, 9); break;         //Fs=24kHz
					case 0x02 : MP3FsInit(124, 511, 3, 19); AUDCON0 = 0x76; break;  //Fs=16kHz
					default : break;
				}
			}
							
			DataRead = 0;                                                 //这句一定要加上
}

void PlayMP3(unsigned char *SongName)
{
	int i =0;
	
		while (MP3STA1&MPFREQ)
		{   
		                                                                  //MP3解码器请求数据块
			m = ReadSector(SongName, Page_Buf);                           //从当前歌曲中读取512字节
			for (i=0; i<m; i++) 
			{
				while (!(MP3STA1 & MPBREQ)) 
				{                                                         //MP3解码器请求数据字节
					while (!PlayState);                                   //暂停播放
					if (ChangeSong) 
					{                                                     //发生选曲
						DataRead = 0;
						ChangeSong = 0;
						return;
					}
				} 
				MP3DAT = Page_Buf[i];                       //向MP3解码器数据寄存器送入一个数据字节
			}

			if (m < 512) 
			{                                               //如果从歌曲中读出的数据不足512个字节则结束本歌曲播放
				NowPlaying++;
				MP3InitFlag = 1;
				return;
			}
		}
	
}


void KeyBoardInit()
{
	P1 = 0x0f;	                                             //将端口1的低四位,即键盘对应的4位置1
	KBCON = 0x00;                                            //设置键盘有效模式为低电平有效,并使能
	                                                         //中断Low Level,Enable Interrupt
	IEN1 = IEN1 | EKB;	                                     //使能键盘中断Enable KeyBoard Interrupt

}

void Func()
{
		if (CurrentFun < 3)
		{
			CurrentFun++;                                     //在选曲/音量调节/音效调节三者间切换
		}
		else if (CurrentFun == 3)
		{
			CurrentFun = 1;
		}
}


void Next()                                                   //按下"下一首/音量减小"键时的处理
{

	switch (CurrentFun)
	{                                                         //如果当前处于音量调节功能
		case VOLUME	:
			{
				if (MP3VOR > 0x00)                            //当前音量没有达到最小时
				{
					MP3VOR -= 0x01;                           //右声道音量增大一档
					MP3VOL -= 0x01;                           //左声道音量增大一档
				}

				break;
			}
		case EFFECTION :                                      //如果处于音效调节功能
			{
				if (MP3BAS > 7)
				{                                              //降低重音效果
					MP3BAS -= 7;
					MP3MED = 0x0f;	
					MP3TRE += 7;
				}
				break;
			}
		case SELECTSONG	:                                      //如果处理MP3选取功能
			{
				if (NowPlaying == (NumofSong - 1))
				{ 
					NowPlaying = 0;                            //如果已经处于最后一首了,则指向第一首
					MP3InitFlag = 1;
				}
				else 
				{ 
					NowPlaying++;	                           //否则,指向下一首
					MP3InitFlag = 1;
				}
			ChangeSong = 1;		                               //置选曲标志位

				break;
			}
		default : break;
	}
		
}


void Previous()                                                //按下"上一首/音量增大"键时的处理
{
	switch (CurrentFun)
	{
		case VOLUME :                                          //如果当前处于音量调节功能
			{
				if (MP3VOR < 0x1f)                             //当前音量没有达到最大时
				{
					MP3VOR += 0x01;                            //右声道音量增大一档
					MP3VOL += 0x01;                            //左声道音量增大一档
				}

				break;
			}

		case EFFECTION :                                       //如果处于音效调节功能
			{
				if (MP3BAS < 0x1e)
				{                                              //增加重音效果
					MP3BAS += 5;
					MP3MED = 0x0f;	
					MP3TRE -= 5;
				}
				break;
			}

		case SELECTSONG	:                                      //如果处理MP3选取功能
			{
				if (NowPlaying > 0)
				{
					NowPlaying--;                              //如果当前播放歌曲不为第一首,则指向上一首
					MP3InitFlag = 1;
				}
				else 
				{
					NowPlaying = NumofSong - 1;                //如果当前已经到达第一首,则指向最后一首
					MP3InitFlag = 1;
				}
				ChangeSong = 1;				                   //置选曲标志位

				break;
			}
		default:break;
	}
	
}


void PlayPause()
{
	PlayState = !PlayState;	                                    //按一下播放键时,改变播放状态
	
}


⌨️ 快捷键说明

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