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

📄 main.c

📁 MP3_PLAYER.rar
💻 C
字号:
/*******************************************************************************
* File Name          : main.c
* Author             : Wuhan R&D Center, Embest
* Date First Issued  : 08/08/2008
* Description        : Main program body
********************************************************************************/

/*******************************************************************************
MP3播放器,支持FAT16文件系统,支持长文件名和汉字。
命令说明:
dir:      	列出当前目录的所有项包括文件和子目录
cd:      	后跟子目录名,或“..”到上一级目录。
read:     	后跟文件名。读出并输出文件的ASCII码。
			可以正确显示文本文件如以txt,c,h,s为后缀的文件
free:     	查看SD卡空闲空间
play:     	后跟要播放的MP3文件。用来播放MP3文件。
vstest:		测试VS1003,用于测试硬件是否完好、是否连接好。
usb:		读卡器功能,此时PC可直接对开发板上的SD卡进行操作。
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "hw_config.h"
#include "config.h"
#include "fat16.h"
#include "msd.h"
#include "vs1003.h"

/* Global define -------------------------------------------------------------*/
u8  Stream_Buff[buffsize];
u8 	readNextBytes;
u32 mp3data_pointer;

/* Extern declare -------------------------------------------------------------*/
extern void SetupUART1(void);
extern void SetupClock(void);
extern void Speaker_Timer_Config(void);
extern void Get_Medium_Characteristics(void);
extern void VS1003_Config(void);
extern void Mp3Reset(void);
extern void SPI_Config(u16 BaudRatePrescaler);
extern void Delay(int);

extern u32 Mass_Block_Count;
extern u32 Mass_Block_Size;
extern u32 Mass_Memory_Size;

/*******************************************************************************
* Function Name  : USART_Scanf_Name
* Description    : Gets Char values from the hyperterminal.
* Input          : None
* Output         : None
* Return         : Length
*******************************************************************************/
u8 USART_Scanf_Name(u8 * str)
{	
  u8 index = 0;
  while(1) 
  {
    /* Loop until RXNE = 1 */
    while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
    {
    }
    str[index++] = (USART_ReceiveData(USART1));
	printf("%c",str[index - 1]);
	if(str[index - 1] == 13)
	{  
	    index--;
	    return index;
    }
  }													
}

/*******************************************************************************
* Function Name  : USART_Scanf_Cmd
* Description    : Gets Char values from the hyperterminal.
* Input          : None
* Output         : None
* Return         : Length
*******************************************************************************/
u8 USART_Scanf_Cmd(u8 * str)
{	
  u8 index = 0;
  while(1) 
  {
    /* Loop until RXNE = 1 */
    while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
    {
    }
    str[index++] = (USART_ReceiveData(USART1));
	printf("%c",str[index - 1]);
	if(str[index - 1] == 13 || str[index - 1] == 32)
	{  
	    index--;
	    return index;
    }
  }
}

/*******************************************************************************
* Function Name  : Equal
* Description    : Compare the string A and B
* Input          : A-- one string,B-- anohter string,SizeB-- the size of string
* Output         : None
* Return         : 1-- Equal 0-- Not Equal
*******************************************************************************/
u8 Equal(void* A, void* B, u8 SizeA, u8 SizeB)
{
	u8 i, *a = A, *b = B;
	if(SizeA != SizeB)
        return 0;
	for(i = 0; i < SizeA; i++)
		if(a[i] != b[i])
			return 0;
	return 1;
}

/*******************************************************************************
* Function Name  : PrintPass
* Description    : Print the pass
* Input          : pass-- the pass string
* Output         : None
* Return         : None
*******************************************************************************/
void PrintPass(u8 * pass)
{
   	printf("\r\nX:");
	while(* pass != '\0')
	   printf("%c",*(pass++));
	printf(">");
}

/*******************************************************************************
* Function Name  : Sleep
* Description    : delay.
* Input          : delay time.
* Output         : None
* Return         : None
*******************************************************************************/
void Sleep(u32 cpt_loop)
{
  cpt_loop = cpt_loop * 10000;
  while (cpt_loop -- != 0);
}  
 
/*******************************************************************************
* Function Name  : main.
* Description    : Main routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
int main(void)
{	
	u8 ret = 1;

	static u32 currSec;  									// currSec记录当前目录所在的首扇区 ,fileSec记录打开文件首扇区
    u32 temp ,fileoffset;
	u8 pass[512];											// 记录路径
	u8 foldername[128];										// 文件或目录名
    u8 command[6];											// 记录命令
	u8 len1,len2;
	u32 tmp;
	s16 index;
	u32 i;

	SetupClock ();
  	SetupUART1 ();
	VS1003_Config();
    ret = MSD_Init();
    printf("\r\nMSD_Init result: %d",ret);
	Get_Medium_Characteristics();
	printf("\r\nMsdBlockCount: %d",Mass_Block_Count);
	printf("\r\nMsdBlockSize: %d Byte",Mass_Block_Size);
	printf("\r\nMsdMemorySize: %d MB\r\n",Mass_Memory_Size/1024/1024);
 	
  	FAT_Init();
	currSec = DirStartSec();								// 找到根目录的开始扇区号
	pass[0] = '\\';
	pass[1] = '\0';
    index = 0;	
	while(1)
	{
		PrintPass(pass);
		len1 = USART_Scanf_Cmd(command);
		if(Equal(command, "dir",len1,3))					// 列出目录中所有项	
		{
			printf("\r\n\r\n");
			SPI_Config(SPI_BaudRatePrescaler_2);
			List_AllDir_Long(currSec);
		}
       else if(Equal(command, "cd",len1,2))					// 更改路径	
   	   {    
           len2 = USART_Scanf_Name(foldername);
		   temp = SearchFoler(currSec, foldername, len2, 1);
		   if(temp)
		   {
	 		  currSec = temp;	 
			  if(Equal(foldername, "..",len2,2))   			// 上级目录,修改路径
			  {
			      if(index > 0)
				  {
	    		      while(pass[--index] != '\\') ;
        			  pass[index + 1] = '\0';
				  }
			  }
			  else if(Equal(foldername, ".",len2,1)) ;  	// 当前目录,路径保持不变
			  else 											// 子目录,修改路径
			  {
	    		  for(tmp = 0; tmp < len2; tmp++) 			// 记录路径
	    		      pass[++index] = foldername[tmp];
				  pass[++index] = '\\';
    			  pass[index + 1] = '\0';
			  }			 
		   }
    	}
       else if(	Equal(command, "read",len1,4))				// 以文本文件的方式打开文件	
	   {
           len2 = USART_Scanf_Name(foldername);
		   temp = SearchFoler(currSec, foldername, len2, 0);// 查找文件,并返回长度
		   if(temp)											// 找到文件
		   {	 
			   printf("\r\n");

			   // 输出文件内容
			   for( fileoffset = 0 ; fileoffset < temp / buffsize ; fileoffset++)
			   {
    			   FAT_FileRead(fileoffset * buffsize, buffsize, Stream_Buff);
    			   for(tmp = 0; tmp < buffsize; tmp++)
				      printf("%c", Stream_Buff[tmp]);
			   }

			   FAT_FileRead(fileoffset * buffsize , temp % buffsize, Stream_Buff);
			   for( tmp = 0; tmp < temp % buffsize; tmp ++)
                  printf("%c",Stream_Buff[tmp]);

           }
	   }
	   else if(	Equal(command, "free",len1,4))					// 计算剩余空间	
	   {
		   printf("\r\n\r\nfree space: %dMB\r\n",CalcuFreeSpace() / 1024 / 1024);
	   }
	   else if(	Equal(command, "usb",len1,3))		 			// 读卡器
	   {
	   		SPI_Config(SPI_BaudRatePrescaler_2);
			Set_USBClock();
			USB_Interrupts_Config();
			Led_Config();
			Get_Medium_Characteristics();
			USB_Init();
			while(1);
	   }
	   else if(Equal(command, "vstest",len1,6))					// 测试VS1003	
	   {
	   		VS1003_Config();
			Mp3SoftReset();
			VsSineTest();
	   }
	   else if(Equal(command, "play",len1,4))					// 播放MP3文件	
	   {
			SPI_Config(SPI_BaudRatePrescaler_2);
			Mp3Reset();
			len2 = USART_Scanf_Name(foldername);
			temp = SearchFoler(currSec, foldername, len2, 0); 	// 查找文件,并返回长度
			if(temp)											// 找到文件
			{
				mp3data_pointer = 0;
				readNextBytes = 0;
				FAT_FileRead(0, buffsize, Stream_Buff); 		// 读取头一个文件流
				fileoffset = 1;
				printf("\r\nplaying...");
				VS1003_Config();	 		      			   
				while(1)
				{
					Mp3DeselectControl();
			   		Mp3SelectData();       						// xDCS = 0,选择vs1003的数据接口

			    	for(i=0;i<buffsize;i++)
					{
						// 等待DREQ为高
					    while((GPIO_ReadInputData(GPIOA) & MP3_DREQ) == 0);    
						SPIPutChar(Stream_Buff[mp3data_pointer++]);
					}
				 	Mp3DeselectData();	
					mp3data_pointer = 0;

					// 读取一个缓冲
    				if(fileoffset < temp / buffsize)
            		   	 FAT_FileRead(fileoffset++ * buffsize, buffsize, Stream_Buff);
    				else
					{
			    		 FAT_FileRead(fileoffset++ * buffsize, temp % buffsize, Stream_Buff);					 
                         break; 								// 返回
				    }
			   }
			   
           }		
		}	   
	}
}

#ifdef  DEBUG
/*******************************************************************************
* Function Name  : assert_failed
* Description    : Reports the name of the source file and the source line number
*                  where the assert error has occurred.
* Input          : - file: pointer to the source file name
*                  - line: assert error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while(1)
  {
  }
}
#endif
/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/

⌨️ 快捷键说明

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