STM32
直播中

遇鱼余的小白

11年用户 520经验值
私信 关注
[问答]

怎样去设计一个基于VS1003语音解码芯片和CH375优盘模块的mp3播放器呢

怎样去设计一个基于VS1003语音解码芯片和CH375优盘模块的mp3播放器呢?

回帖(1)

张小林

2021-12-14 14:03:17
以前做毕业设计买了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("串口设置完毕rn");
        KEY_Init();                                        //初始化按键
        VS1003_GPIO_Init();
        znFAT_Device_Init(); //存储设备初始化
  printf("U盘初始化完毕rn");
        znFAT_Select_Device(0,&Init_Args); //选择设备
        res=znFAT_Init(); //文件系统初始化       
         printf("文件系统初始化完毕rn");
if(!res) //文件系统初始化成功,返回0
{
  printf("Suc. to init FSrn");
         
  printf("DBR(BPB)所在扇区号BPB_Sector_No: %drn",Init_Args.BPB_Sector_No);   
  printf("磁盘的总容量,单位KB,KBTotal_SizeKB: %drn",Init_Args.Total_SizeKB);         
  printf("每个扇区的字节数BytesPerSector: %drn",Init_Args.BytesPerSector);  
  printf("FAT表所占扇区数FATsectors: %drn",Init_Args.FATsectors);                      
  printf("每簇的扇区数SectorsPerClust: %drn",Init_Args.SectorsPerClust);
  printf("第一个FAT表所在扇区FirstFATSector: %drn",Init_Args.FirstFATSector);      
  printf("第一个目录所在扇区FirstDirSector: %drn",Init_Args.FirstDirSector);        
  printf("FSINFO扇区所在扇区FSsec: %drn",Init_Args.FSINFO_Sec);                          
  printf("空闲簇的个数Next_Free_Cluster: %drn",Init_Args.Next_Free_Cluster);
  printf("空闲簇的个数ýFreenCluster: %drn",Init_Args.Free_nCluster);        
}
else //文件系统初始化失败
{
        printf("Fail to init FS , Err Code: %drn",res);
}
//VS_Sine_Test();
VS_sin_test(0x24); //正弦测试,听到滴的一声

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

         for(i=0;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 Kbpsrn",bit);  //此处用串口显示信息,波特率太低播放会卡
                printf("歌曲时间为:%d srn",time);       
                printf("歌曲总时间为:%d srn",Total_time);
        }
         znFAT_Close_File(&fileinfo); //关闭文件
         VS_Flush_Buffer();//清空VS1003的数据缓冲区,此函数中最后将VS_XDCS置高,即关闭SDI       
        if(currentfile>=n_file)currentfile=0;
        znFAT_Flush_FS(); //刷新文件系统
}         
}   








  
















有些歌曲计算的时长和文件自身的时长一致,有些计算出来的要长一些。可能前面有空白扇区。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分