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

📄 mp3-at89c51.c

📁 基于AT89C51的MP3程序设计
💻 C
字号:

#include "AT89C51SND1_REG.H"
#include "MCU_KEYPAD.H"
#include "MP3_PLAYER.H"
#include "FILE_SYS.H"


void main()
{     
void main()
{     
	 //MP3 Player
	 /*初始化*/
	 MP3player_Init(); //解码器初始化
	 Mutestate(1);//初始化为声状态                                                 
	 P1 = 0x0f;
	 KBCON = 0x00;
	 IEN1 |=EKB;	  //按键初始化                                            
	 EA = 1;      //中断使能  
	/*获得曲目数量*/   
	Number_Song = GetMP3NUM(); 
	/*处理播放曲目程序*/ 
	Playingflag= 0;                
	while(1) //循环
	 {
	 if(Number_Song != 0)//如果存在MP3文件
	 {
	 PlayInit(&SONG[11 * Playingflag]);			
	 Mutestate(0);//有声模式
	 PlayMP3(&SONG[11 * Playingflag]);//播放指定MP3文件
	 Mutestate(1);
	 }
	if(Playingflag ==Number_Song)//循环播放 
	{	
	 Playingflag= 0;
	}
    } 
  }
}


}
//-----------------------------------------------------------------------
void MP3player_Init(void)
{
	MP3VOR = 0x0a;//右声道控制寄存器
	MP3VOL = 0x0a;//左声道音量控制寄存器
	MP3BAS = 0x10;//低音控制寄存器
	MP3MED = 0x10;//媒介控制寄存器
	MP3TRE = 0x10;

	MP3CON &= (~MSKREQ);	                          //Clear to allow the 
	                                                  //MPREQ flag to generate a MP3 interrupt.
	MP3CON |= MPEN;	                                  //使能MP3解码.
}
//------------------------------------------------------------------------
void Mutestate(unsigned char sw)
{ 
    static char volume;	
    
	if(sw)
	    { 
		  volume = MP3VOL;
		  MP3VOR = 0x00;
	      MP3VOL = 0x00;
		  AUDCON1 &= (~0x01);
		  MP3CON &= (~MPEN);
    	 }
    else
	    { 
		  MP3VOR = volume;
	      MP3VOL = volume;
		  AUDCON1 |= 0x01;
		  MP3CON |= MPEN;
		 }
}
//---------------------------------------------------------------------------
unsigned char GetMP3NUM(void)
{
	unsigned char i = 0, j = 0, l = 0;
	int k = 0;
	unsigned char MP3[3] = {'M', 'P', '3'};
    GetFATInfo();
	k = BootSector + RsdSector + 2 * SectorofFatSize;
	ReadPage(k / 32, k % 32, Page_Buf);
 	while (Page_Buf[0] != 0)
	{
	for (j=0; j<16; j++)
	{
	 if (!Page_Buf[j * 32]) break;
	 if (Page_Buf[j * 32] == 0xE5) continue;
	 if (!memcmp(MP3, &Page_Buf[j * 32 + 8], 3))					  
	   {
		for (i=0; i<11; i++) 
		{
		SONG[l * 11 + i] = Page_Buf[j * 32 + i];
		 }
			l++;
		   }
		 }
		 k++;
		 ReadPage(0 + k / 32, k % 32, Page_Buf);
	}
	return l;
}
//----------------------------------------------------------------------
void GetFATInfo(void)
{

	ReadPage(Begin_Cluster, 0, Page_Buf);

	if (!(Page_Buf[0] == 0xeb && Page_Buf[2] == 0x90))	
	{
		
		BootSector = Page_Buf[454] + Page_Buf[455] * 256 + Page_Buf[456] * (256 * 256) + Page_Buf[457] * (256 * 256 * 256);
	}
	else 
	{
		BootSector = 0;
	}


	ReadPage(Begin_Cluster, BootSector, Page_Buf);
	RsdSector = Page_Buf[14] + Page_Buf[15] * 256;
	SecPerClus = Page_Buf[13];

	BytesPerSec = Page_Buf[12] * 256 + Page_Buf[11];

	TotalSector = (Page_Buf[20] * 256 + Page_Buf[19]);
	TotalCapacity = TotalSector * BytesPerSec;
	TotalCluster = TotalSector / SecPerClus; 

	SectorofFatSize = ((Page_Buf[22] + Page_Buf[23] * 256));
	RootEntry = (Page_Buf[18] * 256 + Page_Buf[17]);
 
	FirstDataSec = BootSector + RsdSector + (SectorofFatSize * 2) + ((RootEntry * 32 + (BytesPerSec-1)) / BytesPerSec);

	if (TotalCluster > 65525)
	{               
		FAT_TYPE = FAT32;

		if (TotalSector == 0) 
		{
			TotalSector = (Page_Buf[32] + Page_Buf[33] * 256 + Page_Buf[34] * 256 * 256 + Page_Buf[35] * 256 * 256 * 256);
		}
		TotalCapacity = TotalSector * BytesPerSec;
		TotalCluster = TotalSector / SecPerClus;

		SectorofFatSize = (Page_Buf[36] + Page_Buf[37] * 256 + Page_Buf[38] * 256 * 256 + Page_Buf[39] * 256 * 256 * 256);
		if (SectorofFatSize > (TotalCluster * 16 / 512))
		{
			SectorofFatSize = ((Page_Buf[22] + Page_Buf[23] * 256));
		}
		RootEntry = (Page_Buf[44] * 256 + Page_Buf[43]);
		FirstDataSec = BootSector+RsdSector + (SectorofFatSize * 2) + ((RootEntry * 32 + (BytesPerSec-1)) / BytesPerSec);
		
	}
	else if ((TotalCluster > 0) && (TotalCluster < 4085)) 
	{
		FAT_TYPE = FAT12;
	}
	else
	{	
		FAT_TYPE = FAT16;
	}
}
//-------------------------------------------------------
char PlayInit(unsigned char *SongName)
{
		int i = 0, j = 0, f = 0;
		int k = 0;
		unsigned int total_size;
		RDCOUNT = Read_Sector(SongName, Page_Buf);      
		/*判断ID3V2*/
		if (Page_Buf[0] == 0x49)
		if ((Page_Buf[1] == 0x44) && (Page_Buf[2] == 0x33))
		{
		/*获得MP3标签长度*/
	  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)
		{
		Read_Sector(SongName, Page_Buf);
		total_size -=512;
		}
		i = total_size;
	  }
	  /*MP3帧头*/
	if (Page_Buf[i] != 0xFF)i += 10;				 
	  /*获得MP3文件的信息*/			                                                                 
	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];
	}
	    /*设置MP3解码器和AUDIO接口的时钟*/
	  if (MP3_Framehead[1] & 0x08) 
	  {
	  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;
	  }
	  } 
	else 
	  {
	  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;
	  }
	}						
	  DataRead = 0;
	  return 1; 
}
//-------------------------------------------------------------------------------
int ReadSector(unsigned char *Name, unsigned char *databuff)
{
	  int i, k, Page;
	  unsigned  long CurrentSector;
	  if (DataRead == 0) 
	  {
	   Page = BootSector + RsdSector + 2 * SectorofFatSize;//文件目录表地址
	   ReadPage(Page / 32, Page % 32, databuff);    //读取文件目录表内容
	   while (databuff[0] != 0)//文件目录表有内容
		{
		for (i=0; i<16; i++)
		{
		if (!memcmp(Name, &databuff[i * 32], 11))//比较文件名
		{
		//获得文件所在簇号
		Current_Cluster = databuff[32 * i + 27] * 256 + databuff[32 * i + 26];
		for (k=31; k>27; k--) 
		{
		DataRemain = (DataRemain << 8) | databuff[i * 32 + k];
		}
		//文件所在逻辑扇区号
		CurrentSector = (Current_Cluster - 2) * SecPerClus + FirstDataSec;
		//读取一个扇区的文件内容
		ReadPage(CurrentSector / 32, CurrentSector % 32, databuff);
		DataRead += 512;
		DataRemain -= 512;
		if (DataRemain < 0) 
		{
		DataRead = 0;
		return (DataRemain + 512);
		}
		else
		{
		return (512);
		}
		}
		}
		Page++;
		ReadPage(0 + Page / 32, Page % 32, databuff);
		}
		return (0);
		}
		else
		{
		Current_Cluster++;
		CurrentSector = (Current_Cluster - 2) * SecPerClus + FirstDataSec;
		ReadPage(CurrentSector / 32, CurrentSector % 32, databuff);
		DataRead += 512;
		DataRemain -= 512;
		if (DataRemain < 0) 
		{
		DataRead = 0;
		return (DataRemain + 512);
		}
		else return (512);
		}
}

//-----------------------------------------------------------------
void PlayMP3(unsigned char *SongName)
{
	int i =0,m =0;

	while (1)
		{   
 			RDCOUNT = ReadSector(SongName, Page_Buf); 
			for (i=0; i<RDCOUNT; i++) 
			{
				while (!(MP3STA1 & MPBREQ)) 
					while (!PlayState);
 
				MP3DAT = Page_Buf[i]; 
			}
			if (ChangeSong) 
			{ 
				DataRead = 0;
				ChangeSong = 0;
				m =1;
			}

			if (RDCOUNT < 512) 
			{
				NowPlaying++;
				MP3InitFlag = 1;
				m =1;
			}

			if(m)
 			 {  
			    while(MP3STA1 & MPFREQ)
			      MP3DAT = 0x00;
				return;
			  }
		}
	
}
//-------------------------------------------------
void key_interrupt() interrupt 11
{
  unsigned char i,j,k;
  /*屏蔽MP3中断*/
  EA = 0;	
  IEN1 &= (~EKB);	           
  k=KBSTA & 0x0f;
  for(j=0;j<10;j++)		   
  for(i=0;i<100;i++);
  if(k==(~P1 & 0x0f))
  /*中断任务处理*/
  switch (k)
  {		                                                     
  case 1 : Func(); break;	//		
  case 2 : Next(); break;
  case 4 : Previous(); break;
  case 8 : PlayPause(); break;//播放暂停
  default : break;
  }
  /*使能MP3中断*/
  IEN1 |= EKB;	          
  EA = 1;	
  k=KBSTA;	                                                  
  return;
}

void Func()
{
  if (function < 3)
	{
	function++;
	}
  else if (function == 3)
	{
	function = 1;
	}
}
void Next()
{
	switch (function)
	{		
	   case SELECT_MP3	:
	   if (Playing == (number_mp3 - 1))
		   Playing = 0; 
	   else 
		   Playing++;	
		   MP3InitFlag = 1;
		   ChangeSong = 1;	
		break;
		case VOLUME	:
		if (MP3VOR > 0x00) 
		{
		   MP3VOR -= 0x01;
		   MP3VOL -= 0x01; 
		}
		break;
		case EFFECT : 
		if (MP3BAS > 2)
		{
		MP3BAS -= 2;
		MP3TRE += 2;
		}
		break;
	  default: break;
	}
  }

void Previous()
{
	switch (function)
	{		
	   case SELECT_MP3	: 
	 	  if (Playing > 0)
		     Playing--; 
		  else 
		     Playing = number_mp3 - 1;
		      MP3InitFlag = 1;
			 ChangeSong = 1;	
	   break;
	   case VOLUME :
		  if (MP3VOR < 0x1f)
	         {
		      MP3VOR += 0x01; 
		      MP3VOL += 0x01; 
	         }
	         break;
		  case EFFECT: 
	         if (MP3BAS < 0x1e)
	           {
			   MP3BAS += 2;
			   MP3TRE -= 2;
	           }
	         break;
		  default:      break;
	}
}

void PlayPause()
{
	PlayState = !PlayState;
	player_state(!PlayState);	
}

⌨️ 快捷键说明

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