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

📄 32musb.c

📁 实现 32M的MP3+U盘的循环播放功能的原程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	else if (BulkPoint == Page_Buf + 512)
	{
		Trans_Data2PC();//为普通数据时转向数据接收处理程序
	}
//	P3_5 = 1;//USB通信指示灯关闭

}

void Reserved()
{
	printuf("Undefined Interrupt Occured : %x\n", UEPINT);
}
//END OF USB DISK
//---------Edit by kent-------------------------------------------------------------
void MP3FsInit(unsigned char NDIV, unsigned int RDIV, unsigned char MPCD, unsigned char AUCD)
{	//!!!!!!!!!!!!!!!先清零!!!!!!!!!这个问题在调试的时候碰到了很多麻烦!!!!!!!!!!!!!!!!!!
	//例如先置5后置11时发现变成了0f,因为0101|1011=1111=F,因此总是不能改歌
	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              1a

}

void MP3Disable(void)
{	PLLCON |= PLLRES;
	PLLCON &= (~PLLEN);
	MP3CON |= MSKREQ;
	MP3CON &= (~MPEN);
	AUDCON1 |= 0x20;
	AUDCON1 &= (~0x40);
	AUDCON1 &= (~0x01);
	AUDCON0 = 0x08;
	AUDCON1 = 0xB2;
	AUDDAT = 0xFF;
}
//<<<------------------------by frank----------------------------------------------------


/***Edit by kent***********************************************************/
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 = 0x0f;//0000 1111下同
	MP3VOL = 0x0f;
	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 = 0x41;//0100 0111
	AUDCON1 &= (~0xB0);//SRC=0,MSREQ=0,MUDRN=0
	AUDCON1 |= 0x01;
	while (i)i--;
	AUDCON1 |= 0x40;
}

void Init(void)
{
	PllInit();
	MP3Init();
	AudioInit();
}
/*****Write by kent***************************************************************************************/
/*PlayInit()函数用来预检MP3歌曲的帧头并作相应的配置*/
void PlayInit(unsigned char *SongName)
{
		int i = 0, j = 0, f = 0;
		int k = 0;
		unsigned int total_size;
		//MP3Init();
		//分析MP3信息,可能会比较长,但是没有别的办法
		//先要读出一部分文件内容,大小不能确定
		//while(){
		m = ReadSector(SongName, Page_Buf);//先读出512字节
		////for(k=0;k<64;k++)printuf("%x  ",Page_Buf[k]);
		//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
					/*计算公式
					int total_size;
		 			total_size = (Size[0]&0x7F)*0x200000 +(Size[1]&0x7F)*0x4000 +(Size[2]&0x7F)*0x80 +(Size[3]&0x7F)
					*/	
					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;
					printuf("%x", total_size >> 8);
					printuf("%x\n", total_size & 0xFF);
					}
			//else continue;
			
			//search whether the next 1.5bytes are 0xFFF,
			//如果接下来是FFF则为MP3帧头,如果不是则为扩展标签头,需要加10个字节的量
			if (Page_Buf[i] != 0xFF)
				i += 10;
			//for(k=i;k<i+4;k++)printuf("%x  ",Page_Buf[k]);
			//get MP3 information from FF FX XX XX 4bytes,and show that
			if ((Page_Buf[i] == 0xFF) && (Page_Buf[i + 1] & 0xF0 == 0xF0))
			{
				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];
			}
					//printu("The MP3 Framehead Bytes:");
			printuf("%x", MP3_Framehead[0]);
			printuf("%x", MP3_Framehead[1]);
			printuf("%x", MP3_Framehead[2]);
			printuf("%x\n", MP3_Framehead[3]);
			//MP3初始化;

			if (MP3_Framehead[1] & 0x08) 
			{//MP3Disable();//MPEG I
				Init();
				switch ((MP3_Framehead[2] & 0x0C) >> 2) 
				{
					case 0x00 : MP3FsInit(24, 126, 3, 5); 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;
				}
										//PLLRegister=PLLCON;
										//MP3Register=MP3CLK;
										//AudioRegister=AUDCLK;										
			} 
			else 
			{//MP3Disable();                   //MPEG II
				Init();
				switch ((MP3_Framehead[2] & 0x0C) >> 2)
				{
					case 0x00 : MP3FsInit(24, 126, 3, 11); 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;
				}
										
										//PLLRegister=PLLCON;
										//MP3Register=MP3CLK;
										//AudioRegister=AUDCLK;
			}
			//printu("The baud rate of now playing song is:");
			printuf("%x \n", BaudRate[1-MP3_Framehead[1] & 0x07][3-MP3_Framehead[1] & 0x06][(MP3_Framehead[2] & 0xF0) >> 4-1]);
			//printu("kbps\n");
							
			DataRead = 0;//这句一定要加上
}
//播放MP3歌曲*******write by jingxiao*************************************************************************
void PlayMP3(unsigned char *SongName)
{
	int i =0;
//	while ( 1 ) {
		
		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()//<<<<<------------------------change by kent-------------------------------------
{
	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;		//置选曲标志位
			/*if(MP3InitFlag){
								PlayInit(&SONG[11*NowPlaying]);
								MP3InitFlag=0;
								}*/
				break;
			}
		default : break;
	}
	
}

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

				break;
			}

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

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

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

}

void key_interrupt() interrupt 11
{
		unsigned char i = 100;
		EA = 0;			//关中断
		IEN1 &= (~EKB);	//Enable KeyBoard Interrupt

		while (i)
		{
			i--;
		}

		i = KBSTA;		//取键盘中断位
		switch (i)
		{		//依次处理四个键中的某个键被按下时的情况
			case 1 : Func(); break;
			case 2 : Next(); break;
			case 4 : Previous(); break;
			case 8 : PlayPause(); break;
			default : break;
		}
		IEN1 |= EKB;	//Enable KeyBoard Interrupt
		
		EA = 1;		//开中断
		return;
}
void main()
{
	printu(">>>> UP-TECH MP3 USB Disk V2.00 <<<<\n");

	if(P3_4)
	{
		printu("Entering USB Mode...\n");//输出进入U盘功能的信息

		AtmelUSBInit(4, 11, 0);//PLL时钟配置,
		EpEnable();//端点初始化
		UEPNUM = 0;//指向端点0
		BulkPoint = Page_Buf;

		while(1)
		{
			//轮询,检查相应端点是否有中断产生
			if(UEPINT & EP1INT) main_txdone();//Bulk-Out端点处理
			if(UEPINT & EP2INT) main_rxdone();//Bulk-In端点处理
			if(UEPINT & EP0INT) Ep0Int();//端点0处理

			UEPINT = 0;//清中断状态寄存器
		}
	}
	else 
	{
		printu("Entering MP3 Mode...\n");

		Flash_Reset();//Flash复位
		Init();//MP3初始化
		KeyBoardInit();//键盘初始化

		MP3InitFlag = 1;
		EA = 1;//开中断,键盘可以开始工作

		NumofSong = GetMP3List();//得到U盘中的MP3歌曲列表
		printuf("Song:%x\n", NumofSong);//输出歌曲总数信息

		if(NumofSong == 0) 
		{
			printu("There is no MP3 file in USB Disk!\n");
		}

		P3_5 = 0;//打开USB灯亮
		
		while(1) 
		{
			if(NumofSong != 0)
			{
				if(MP3InitFlag)
				{
					PlayInit(&SONG[11 * NowPlaying]);
					MP3InitFlag = 0;
				}
				PlayMP3(&SONG[11 * NowPlaying]);//如果处于播放状态,则播放当前歌曲
			}
			if(NowPlaying == NumofSong) 
			{
				//PlayState = STOP;			//全部歌曲播放完了,播放器停止
				NowPlaying = 0;//循环播放
			}
		}

	}
}	

⌨️ 快捷键说明

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