📄 main.c
字号:
while(KeySt01==0) Delay(200);
UsrSel=255;
break; //退出
}
else if(KeySt02==0) //向上一项
{
Delay(200); //去抖
while(KeySt02==0) Delay(200);
if(UsrSel==0) UsrSel=5;
else if(UsrSel>0) UsrSel--;
//显示选择当前项
PrintOneASCII(0,0,' ');
PrintOneASCII(1,0,' ');
PrintOneASCII(2,0,' ');
PrintOneASCII(3,0,' ');
PrintOneASCII(4,0,' ');
PrintOneASCII(5,0,' ');
PrintOneASCII(UsrSel,0,'>');
}
else if(KeySt03==0) //向下一项
{
Delay(200); //去抖
while(KeySt03==0) Delay(200);
if(UsrSel==5) UsrSel=0;
else if(UsrSel<5) UsrSel++;
//显示选择当前项
PrintOneASCII(0,0,' ');
PrintOneASCII(1,0,' ');
PrintOneASCII(2,0,' ');
PrintOneASCII(3,0,' ');
PrintOneASCII(4,0,' ');
PrintOneASCII(5,0,' ');
PrintOneASCII(UsrSel,0,'>');
}
else if(KeySt04==0) //选中当前项
{
Delay(200); //去抖
while(KeySt04==0) Delay(200);
break;
}
}
ClearLCD();
if(UsrSel==0) //LCD背光开关
{
Lcdak=!Lcdak;
LCD_AK_Control(Lcdak); //开关背光
if(Lcdak) PrintConstAscStr(1,0,ScreenStr12[22],16); else PrintConstAscStr(1,0,ScreenStr12[23],16);
Delay(800);
}else if(UsrSel==1) //开关播放时间显示
{
SWPlayTime=!SWPlayTime;
if(SWPlayTime) PrintConstAscStr(1,0,ScreenStr12[24],16); else PrintConstAscStr(1,0,ScreenStr12[25],16);
Delay(800);
}
else if(UsrSel==2) //音量控制
{
ChangeVS1011Vol(&CurVol);
}
else if(UsrSel==3) //低音调整
{
ChangeVS1011Bass(&CurBass);
}
else if(UsrSel==4) //外接喇叭
{
SWSpeaker=!SWSpeaker;
if(SWSpeaker) PrintConstAscStr(1,0,ScreenStr12[26],16); else PrintConstAscStr(1,0,ScreenStr12[27],16);
Delay(800);
}
else if(UsrSel==5) //快速歌曲定位
{
ChangePlayPosition(pdata);
}
if(CurStatus==1) //播放器当前正在播放
{
ClearLCD();
DisplayNumInt(1,0,*pdata,3);PrintOneASCII(1,24,'/');
DisplayNumInt(1,32,DEF_MAX_SONGS,3);
PrintConstAscStr(0,0,ScreenStr12[7],16); //显示"正在播放Mp3文件:"
PrintHZ16(Mp3FileName,buff,2,16,8);
}
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
Display_BattVol(BattVolPic,retry);
while(retry==0 && KeySt01!=0) //电量空,提醒用户充电
{
PrintConstAscStr(7,16,Menustr6[6],13);
Delay(500);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
}
SEI();//开中断
}
void main()
{
unsigned char Dir_Attrib = 0,retry=0;
unsigned long Size = 0;
unsigned long a;
unsigned int b;
unsigned int tmp,old_tmp;
unsigned char flgover;
unsigned char Lcdak=1;
unsigned long Clustervar; //找到字库文件的起始簇号
MCUMode(10); //MCU不进入休眠模式
IniData_From_EEPROM(); //先读取一下E2Prom信息
LCD_AK_Control(Lcdak); //打开背光
LCD_Ini();
KeyIni();KeyInput(); //LCD,键盘初始化
Delay(30);
ClearLCD();
send_cmd(LCD_DISPLAY_NORMAL);
Display_Picture(MainUIPic); //显示开机画面
Delay(1500);
ClearLCD();
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
Display_BattVol(BattVolPic,retry);//显示ADC电量
while(retry==0 && KeySt01!=0) //电量空,提醒用户充电
{
CLI();
PrintConstAscStr(7,16,Menustr6[6],13);
Delay(500);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
SEI();
}
//初始化VS1011B,准备播放
SPI_CS_Deassert(); //PB2=1,释放MMC/SD卡
VS1011B_XRESET_H();//使能芯片 //chip select
{
unsigned char funret;
funret=VS1011B_Init();
Delay(10);
if(funret>0) //初始化VS1011B,失败
{
ClearLCD();
PrintConstAscStr(3,0,ScreenStr12[8],16);
DisplayNumChar(1,2,funret,3);
while(1) ;
}
}
//显示正在读取MMC卡
PrintConstAscStr(3,0,ScreenStr12[1],16);
//打开LM4906_Speaker:
DDRA&=~BIT(4);//端口A的第4位设置为输出
PORTA|=BIT(4);//端口A的第4位输出高电平
//关闭Vs1011b,返回到MMC_SD_SPI模式
VS1011B_DDR |= BIT(VS1011B_XCS)|BIT(VS1011B_XRESET); //XCS,XDCS=1
VS1011B_DISABLE();
MMC_SD_Init();//初始化MMC_SD_spi口
Delay(1500);
while(MMC_SD_Reset())//复位SD卡,失败会retry++;
{
retry++;
if(retry>20) //超时,显示失败
{
ClearLCD();
PrintConstAscStr(3,0,ScreenStr12[0],16);
Delay(500);
while(MMC_SD_Reset()==1) ; //直到插入SD卡为止.
}
}
Clustervar=fat_root_dir_addr(buff); //获取FDT.
//获取字库文件的第一个簇,第二个0参数,表明要寻找字库文件
FONT_ClusterVar = fat_read_dir_ent(0,0,&Size,&Dir_Attrib,buff);
if (FONT_ClusterVar == 0xFFFFFFFF) //出错,退出返回
{
//测试用代码:
ClearLCD();
Display_BattVol(BattVolPic,retry);//显示ADC电量
PrintConstAscStr(3,0,ScreenStr12[2],16);
Delay(1000);
return ;
}else if(FONT_ClusterVar == 0xFFFFFFFE) //根目录下的文件已经搜索完,返回
{
//测试用代码:
ClearLCD();
Display_BattVol(BattVolPic,retry);//显示ADC电量
PrintConstAscStr(3,0,ScreenStr12[3],16);
Delay(1000);
return ;
}
//以后就可以使用该汉字字库了,下面是一个测试
//ClearLCD();
//PrintConstHZ16(ScreenStr12[10],buff,3,0,16);
//Delay(1500);
//显示主菜单,并选择
//MainMenu();
////////////////////////////////////////
//开始进行Mp3文件的搜索与读取:
fat_root_dir_addr(buff); //获取FDT.
//////第一次将根目录下的所有Mp3文件都扫描一遍,获取歌曲的数目:
while(1)
{
for (tmp = 1;tmp < 999;tmp++)
{
Clustervar = fat_read_dir_ent(0,tmp,&Size,&Dir_Attrib,buff);
////测试使用:
//DisplayLong(Clustervar,1);
//
if (Clustervar == 0xFFFFFFFF) //出错,退出返回
{
DEF_MAX_SONGS=0;
ClearLCD();
Display_BattVol(BattVolPic,retry);//显示ADC电量
SWPlayTime=0;
PrintConstAscStr(1,0,ScreenStr12[4],16);
Delay(1000);
while(1) ;
}else if(Clustervar == 0xFFFFFFFE) //根目录下的文件已经搜索完,返回
{
//更新DEF_MAX_SONGS:
DEF_MAX_SONGS=tmp-1;
ClearLCD();
Display_BattVol(BattVolPic,retry);//显示ADC电量
//DisplayNumInt(4,32,DEF_MAX_SONGS);
Delay(500);
goto Mp3_Play_Begin;
}
}
}
Mp3_Play_Begin:
//////////////////////////////////////////////////////////
timer0_init(); //打开定时器T0
TotalSongTim[0]=TotalSongTim[1]=TotalSongTim[2]=TotalSongTim[3]=0; //歌曲总播放时间初始0
while(1)
{Begin:
for (tmp = 1;tmp < DEF_MAX_SONGS;tmp++)
{
//顺序读取根目录下的第tmp个指定文件(在FAT.C中定义),然后播放.
read_Mp3_file:
//关闭Vs1011b,返回到MMC_SD_SPI模式
VS1011B_DDR |= BIT(VS1011B_XCS)|BIT(VS1011B_XRESET); //XCS,XDCS=1
VS1011B_DISABLE();
SPI_CS_Assert();
CurSongTim[0]=CurSongTim[1]=CurSongTim[2]=0; //当前歌曲播放时间初始0
Clustervar = fat_read_dir_ent(0,tmp,&Size,&Dir_Attrib,buff);
////测试使用:
//DisplayLong(Clustervar,1);
//
if (Clustervar == 0xFFFFFFFF) //出错,退出返回
{
//测试用代码:
ClearLCD();
Display_BattVol(BattVolPic,retry);//显示ADC电量
SWPlayTime=0;
PrintConstAscStr(1,0,ScreenStr12[4],16);
Delay(1000);
break;
}else if(Clustervar == 0xFFFFFFFE) //根目录下的文件已经搜索完,返回
{
ClearLCD();
Display_BattVol(BattVolPic,retry);//显示ADC电量
PrintConstAscStr(1,0,ScreenStr12[5],16);
Delay(1000);
break;
}
strcpy((char *)Mp3FileName,(char *)pointer_FDT);
//显示并读取该文件:
ClearLCD();
//显示播放歌曲序号
DisplayNumInt(1,0,tmp,3);PrintOneASCII(1,24,'/');
DisplayNumInt(1,32,DEF_MAX_SONGS,3);
Display_BattVol(BattVolPic,retry);//显示ADC电量
PrintConstAscStr(0,0,ScreenStr12[7],16); //显示"正在播放Mp3文件:"
PrintHZ16(Mp3FileName,buff,2,16,8);
CurStatus=1; //播放器当前正在播放
for(a=0;;a++)
{
//读取该文件
flgover = fat_read_file(Clustervar,buff,a,&Dir_Attrib);
if(flgover==1) //读取文件簇链完毕,继续下一个文件
{
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
Display_BattVol(BattVolPic,retry);
while(retry==0 && KeySt01!=0) //电量空,提醒用户充电
{
CLI();
PrintConstAscStr(7,16,Menustr6[6],13);
Delay(500);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
SEI();
}
break;
}else
{
for(b = 0; b < 512; b+=32)
{
//播放文件
if((a*512+b)<Size) //读取文件还没有超出其大小
{
//切换到VS1011B:
SPI_CS_Deassert(); //SD_CS=1,释放MMC/SD卡
VS1011B_XRESET_H();//使能芯片VS1011
while(!(PINA & BIT(VS1011B_DREQ))) ; //等待VS1011B需要读取数据
{
unsigned char i;
for(i=0;i<32;i++)
VS1011B_WriteDAT(*(buff+b+i));
}
//返回到MMC_SD_SPI模式
VS1011B_DDR |= BIT(VS1011B_XCS)|BIT(VS1011B_XRESET); //XCS,XDCS =1;
SPI_CS_Assert(); //打开MMC/SD
if(KeySt01==0) //打开/关闭背光
{
//等待该键释放
Delay(200);
while(KeySt01==0) Delay(200);
Lcdak=!Lcdak;
LCD_AK_Control(Lcdak); //开关背光
}
else if(KeySt02==0) //Previous
{
//等待该键释放
Delay(200);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
Display_BattVol(BattVolPic,retry);
while(retry==0 && KeySt01!=0) //电量空,提醒用户充电
{
CLI();
PrintConstAscStr(7,16,Menustr6[6],13);
Delay(500);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
SEI();
}
while(KeySt02==0) Delay(200);
SPI_CS_Deassert(); //PB2=1,释放MMC/SD卡
VS1011B_XRESET_H();//使能Vs1011芯片
VS1011B_SoftReset();
tmp--;
if(tmp<1) tmp=DEF_MAX_SONGS; //循环播放
goto read_Mp3_file;
}
else if(KeySt03==0) //Next
{
//等待该键释放
Delay(200);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
Display_BattVol(BattVolPic,retry);
while(retry==0 && KeySt01!=0) //电量空,提醒用户充电
{
CLI();
PrintConstAscStr(7,16,Menustr6[6],13);
Delay(500);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
SEI();
}
while(KeySt03==0) Delay(200);
SPI_CS_Deassert(); //PB2=1,释放MMC/SD卡
VS1011B_XRESET_H();//使能Vs1011芯片
VS1011B_SoftReset();
tmp++;
if(tmp>DEF_MAX_SONGS) tmp=1; //循环播放
goto read_Mp3_file;
}
else if(KeySt04==0) //显示设置主菜单
{
//等待该键释放
Delay(200);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
Display_BattVol(BattVolPic,retry);
while(retry==0 && KeySt01!=0) //电量空,提醒用户充电
{
CLI();
PrintConstAscStr(7,16,Menustr6[6],13);
Delay(500);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
SEI();
}
while(KeySt04==0) Delay(200);
//显示主菜单,并选择
old_tmp=tmp; //保存原来的tmp值
MainMenu(&tmp);
if(old_tmp!=tmp) //如果改变了播放曲目的话,就跳转
goto read_Mp3_file;
//goto Begin;
}
}
else if((a*512+b)>(Size+512)) //超过文件实际大小,强制读完
{
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
Display_BattVol(BattVolPic,retry);
while(retry==0 && KeySt01!=0) //电量空,提醒用户充电
{
CLI();
PrintConstAscStr(7,16,Menustr6[6],13);
Delay(500);
ADC_Init(); //进行一次AD转换,测量电池电量,并且显示出来
retry=ADC_Convert();
SEI();
}
//强制下一首
SPI_CS_Deassert(); //PB2=1,释放MMC/SD卡
VS1011B_XRESET_H();//使能芯片 //chip select
VS1011B_SoftReset();
tmp++;
if(tmp>DEF_MAX_SONGS) tmp=1;
goto read_Mp3_file;
}
else //向vs1011b发送0数据
{
//切换到VS1011B:
SPI_CS_Deassert(); //PB2=1,释放MMC/SD卡
VS1011B_XRESET_H();//使能芯片 //chip select
while(!(PINA & BIT(VS1011B_DREQ))) ; //等待VS1011B需要读取数据
{
unsigned char i;
for(i=0;i<32;i++)
VS1011B_WriteDAT(0);
b+=32;
}
//返回到MMC_SD_SPI模式
VS1011B_DDR |= BIT(VS1011B_XCS)|BIT(VS1011B_XRESET); //XCS,XDCS =1;
SPI_CS_Assert(); //打开MMC/SD
}
}
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -