stm32f103+znfat+ch375+vs1003实现简单mp3播放器功能

以前做毕业设计买了VS1003语音解码芯片和CH375优盘模块,现在有时间想做一个mp3播放器出来。参照的znFAT例程&SD卡驱动(STM32F103)第9个例程、振南电子SD卡MP3播放器程序和正点原子的mp3播放器程序。可实现播放优盘或TF卡根目录的所有mp3文件,增加4个独立按键,实现下一曲、上一曲切换,音量+、音量-的功能。显示mp3信息没用显示屏,用的串口直接输出到串口调试助手上。能够显示mp3文件名称,总大小,歌曲码率,歌曲总时长,播放时间等信息。

打开mp3文件后,获取文件总大小,vs1003的缓冲区每次至少要发送32字节,用for循环每次取每簇4096字节送给vs1003解码。按键处理程序要在这个for循环里面,不然没作用。

#include "delay.h"
#include "sys.h"
#include "usart.h"	 
#include "znfat.h"
#include  "led.h"
#include "spi1.h"

#include "key.h"
#include "vs1003.h"


struct znFAT_Init_Args Init_Args; //初始化参数集合
struct FileInfo fileinfo; //文件信息集合
///

struct DateTime dt; //日期与时间
u8 pause=0;//暂停标志

u32 n_file=0;//mp3文件总数
u32 currentfile=0;	
u8 databuff[4096]; //vs1003文件缓冲区


int main(void)	
{	 
	u8 vol=220;  //音量
	u16 bit,time,Total_time; //码率,播放时间,总时长
	u16 i,j;
	u32 res=0;//初始化标志位,成功为0,失败返回错误码
	u32 len=0;
	
	delay_init();
	LED_Init();
	uart_init(115200); //
	printf("串口设置完毕\r\n");
	KEY_Init();					//初始化按键
	VS1003_GPIO_Init();
	znFAT_Device_Init(); //存储设备初始化
  printf("U盘初始化完毕\r\n");
	znFAT_Select_Device(0,&Init_Args); //选择设备
	res=znFAT_Init(); //文件系统初始化	
	 printf("文件系统初始化完毕\r\n");
 if(!res) //文件系统初始化成功,返回0
 {
  printf("Suc. to init FS\r\n");
	 
  printf("DBR(BPB)所在扇区号BPB_Sector_No: %d\r\n",Init_Args.BPB_Sector_No);   
  printf("磁盘的总容量,单位KB,KBTotal_SizeKB: %d\r\n",Init_Args.Total_SizeKB);          
  printf("每个扇区的字节数BytesPerSector: %d\r\n",Init_Args.BytesPerSector);  
  printf("FAT表所占扇区数FATsectors: %d\r\n",Init_Args.FATsectors);  		    
  printf("每簇的扇区数SectorsPerClust: %d\r\n",Init_Args.SectorsPerClust); 
  printf("第一个FAT表所在扇区FirstFATSector: %d\r\n",Init_Args.FirstFATSector);      
  printf("第一个目录所在扇区FirstDirSector: %d\r\n",Init_Args.FirstDirSector);        
  printf("FSINFO扇区所在扇区FSsec: %d\r\n",Init_Args.FSINFO_Sec);			   
  printf("空闲簇的个数Next_Free_Cluster: %d\r\n",Init_Args.Next_Free_Cluster); 
  printf("空闲簇的个数ýFreenCluster: %d\r\n",Init_Args.Free_nCluster);        
 }
 else //文件系统初始化失败
 {
	printf("Fail to init FS , Err Code: %d\r\n",res);
 }
 //VS_Sine_Test(); 
 VS_sin_test(0x24); //正弦测试,听到滴的一声

 while(!znFAT_Open_File(&fileinfo,"/*.mp3",n_file,1))
 {
  printf("Suc. to open file.\r\n");
  printf("================================\r\n");
  printf("文件名称(Short 8.3):%s\r\n",fileinfo.File_Name);
  printf("文件大小:%d 字节\r\n",fileinfo.File_Size);
  znFAT_Close_File(&fileinfo); //关闭文件
	n_file++;
	printf("mp3文件数量\r\n",n_file);
 znFAT_Flush_FS(); //刷新文件系统
 }
 while(1)
 {	
	VS_Reset_DecodeTime();					//复位解码时间
	res=znFAT_Open_File(&fileinfo,"/*.mp3",currentfile++,1);
	printf("res=%d\r\n",res);	 
  printf("文件名称(Short 8.3):%s\r\n",fileinfo.File_Name);
  printf("文件大小:%d 字节\r\n",fileinfo.File_Size);
	printf("currentfile:%d\r\n",currentfile);

	 for(i=0;i<fileinfo.File_Size/4096;i++)
	 {
	 len=znFAT_ReadData(&fileinfo,i*4096,4096,databuff);
		 j=0;

			do
			{
			if(VS_Send_MusicData((u8*)databuff+j)==0){
			j+=32;
			}				
			}while(j<4096);
	
		if(KEY_PRE==0)  //下一曲 低电平有效
		{
			 delay_ms(10);
			if(KEY0==0){
				while((KEY0==0));//松手检测
				break;
			}
		}
		if(KEY_NEX==0)  //上一曲
		{
			 delay_ms(10);
			if(KEY1==0){
				while((KEY1==0));//松手检测
				if(currentfile>1)
						currentfile-=2;
				else currentfile=0;				
				break;
			}
		}
		if(KEY_VUP==0)  //音量加
		{
			 delay_ms(10);
			if(KEY2==0){
				if(vol<250)
					{
						vol+=5;
						VS_Set_Vol(vol);	
					}else vol=250;
			}
		}
		if(KEY_VDN==0)   //音量减
		{
			 delay_ms(10);
			if(KEY3==0){
				LED1=!LED1;			
				if(vol>100)
				{
					vol-=5;
					VS_Set_Vol(vol);	
				}else vol=100;
			}
		}

			bit=VS_Get_HeadInfo();    //获取mp3文件码率
		time= VS_Get_DecodeTime();  //获取mp3文件播放时间,1s变化一次
		Total_time=(fileinfo.File_Size/bit)/125;  //计算mp3文件总时长,单位s
		printf("歌曲码率为:%d Kbps\r\n",bit);  //此处用串口显示信息,波特率太低播放会卡
		printf("歌曲时间为:%d s\r\n",time);	
		printf("歌曲总时间为:%d s\r\n",Total_time);
	}
	 znFAT_Close_File(&fileinfo); //关闭文件
	 VS_Flush_Buffer();//清空VS1003的数据缓冲区,此函数中最后将VS_XDCS置高,即关闭SDI	
	if(currentfile>=n_file)currentfile=0;
	znFAT_Flush_FS(); //刷新文件系统
 }	 
}   

  

有些歌曲计算的时长和文件自身的时长一致,有些计算出来的要长一些。可能前面有空白扇区。详细代码见https://download.csdn.net/download/u013072995/11419668

最后来一张实物图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值