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

📄 main.c

📁 采用Mega16+VS1011B+SD卡制作的Mp3
💻 C
📖 第 1 页 / 共 2 页
字号:
			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 + -