📄 32musb.c
字号:
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 + -