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

📄 atmel mp3.c

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


#include <string.h>

#define Root_Cluster	 (0)
#define Begin_Cluster	 (0)				  //MBR所在的簇号
#define Data_Cluster	 (1)				  //数据真正开始的扇区

#define BPB_Sector	     (0)
#define Fat_Sector	     (BPB_Sector + 1)
#define Directory_Sector (Fat_Sector + 4)
#define End_Cluster		 (Disk_Size / 32)

#define UNUSED_MARK		 (0xFF)
#define BAD_MARK		 (0x00)
#define LAST_BLOCK		 (0xFFFF)
#define FILE_NO_FOUND	 (512)

#define PagePerClus	      32

#define FAT12            (12)
#define FAT16            (16)
#define FAT32            (32)

#define	K9F_FUN				P5
#define K9F5608				0x4000
#define	COMMAND				0x03	
#define	ADDRESS				0x05	
#define	D_DATA				0x01
#define	INACTIVE			0x09	
#define	RB					0x01

//数据结构与全局变量定义  
unsigned char Page_Buf[512];
extern unsigned char SONG[];
long int Current_Cluster, DataRead = 0, DataRemain = 0, Sector_Offset = 0x21d;
unsigned int TotalCluster, BootSector, RsdSector, SectorofFatSize, TotalCapacity, RootEntry, SecPerClus;
unsigned int TotalSector, BytesPerSec, FirstDataSec;
unsigned char FAT_TYPE; 


int ReadSector(unsigned char *Name, unsigned char *databuff);
unsigned char GetMP3List(void);
void Init_FAT_Info(void);

extern void ReadPage(unsigned int block, unsigned int page, unsigned char *pPage);


void Init_FAT_Info(void)
{
/*	得到引导扇区所在扇区号,如果介质是不带分区的,则0扇区就是BootSector了。 */
	ReadPage(Begin_Cluster, 0, Page_Buf);

	if (!(Page_Buf[0] == 0xeb && Page_Buf[2] == 0x90))					  //通过判断EB ?? 90来看是否已经是BPB了
	{																	  //带分区的介质
		
		BootSector = Page_Buf[454] + Page_Buf[455] * 256 + Page_Buf[456] * (256 * 256) + Page_Buf[457] * (256 * 256 * 256);
	}
	else 
	{
		BootSector = 0;
	}

/*	得到保留扇区数,总扇区数,总扇区数/每簇扇区数得到簇数,是FAT类型的依据	   */
	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;                              //FAT16的簇总数=扇区总数/每簇扇区数

	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)											  //FAT32的扇区总数和FAT表项长度
	{               
		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;
	}
}

unsigned char GetMP3List(void)
{
	unsigned char i = 0, j = 0, l = 0;
	int k = 0;
	unsigned char MP3[3] = {'M', 'P', '3'};
	Init_FAT_Info();

	k = BootSector + RsdSector + 2 * SectorofFatSize;

	ReadPage(0 + 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))					  //file find
			{	
					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);
}

int ReadSector(unsigned char *Name, unsigned char *databuff)
{
	int i, k, Page;
	unsigned  long CurrentSector;
	if (DataRead == 0)                                                    //第一次读取,先查找文件,然后进行读取
		{
			Page = BootSector + RsdSector + 2 * SectorofFatSize;
			ReadPage(0 + 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);
		}

}

//定义与MP3播放相关的寄存器
sfr PLLNDIV = 0xEE;
sfr PLLRDIV = 0xEF;
sfr IEN1    = 0xB1;
sfr KBCON   = 0xA3;
sfr MP3STA1 = 0xAF;
sfr AUDCON0 = 0x9A;
sfr AUDCON1 = 0x9B;
sfr MP3CON  = 0xAA;
sfr PLLCON  = 0xE9;
sfr CKCON   = 0x8F;
sfr AUDCLK  = 0xEC;
sfr AUXR1 = 0xA2;
sfr P1      = 0x90;

sfr MP3DAT  = 0xAC;
sfr MP3ANC  = 0xAD;
sfr MP3VOL  = 0x9E;
sfr MP3VOR  = 0x9F;
sfr MP3BAS  = 0xB4;
sfr MP3MED  = 0xB5;
sfr MP3TRE  = 0xB6;
sfr MP3CLK  = 0xEB;

int m = 0;
extern unsigned char data MP3InitFlag;
unsigned char data FirstStart = 1;
unsigned char data MP3_Framehead[4];                            //解析MP3帧头数组

//MP3有关的宏定义*********************
#define VOLUME		1
#define EFFECTION	2
#define SELECTSONG	3
#define PLAY		1
#define STOP		0

#define EKB		(0x10)
#define	MPBREQ 	(0x08)
#define X2		(0x1)
#define PLLRES	(0x08)
#define PLLEN	(0x02)
#define	MSKREQ	(0x08)
#define MPEN			(0x80)
#define	MPFREQ 		(0x10)


extern unsigned char data CurrentFun;
extern unsigned char data PlayState;
unsigned char data ChangeSong = 0; 

extern unsigned char data NowPlaying;
extern unsigned char data NumofSong;

/*
bits name              comments
--------------------------------------------------
12   sync              0xFFF
1    version           1=mpeg1.0, 0=mpeg2.0
2    lay               4-lay = layerI, II or III
1    error protection  0=yes, 1=no
4    bitrate_index     see table below
2    sampling_freq     see table below
1    padding								  
1    extension         see table below
2    mode              see table below
2    mode_ext          used with "joint stereo" mode
1    copyright         0=no 1=yes
1    original          0=no 1=yes
2    emphasis          see table below
--------------------------------------------------
at end of file - 128 bytes
							 
offset  type  len   name
--------------------------------------------
0       char  3                   "TAG"  
3       char  30    title
33      char  30    artist
63      char  30    album
93      char  4     year   
97      char  30    comments		 
127     byte  1     genre
--------------------------------------------
*/


static void PllInit(void);
static void MP3Init(void);
static void AudioInit();

void MP3_Init();
void PlayInit(unsigned char *SongName);

void Func();
void Next();
void Previous();
void PlayPause();
void PlayMP3(unsigned char *SongName);

⌨️ 快捷键说明

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