📄 atmel mp3.c
字号:
#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 + -