历史上的今天
返回首页

历史上的今天

今天是:2024年10月16日(星期三)

正在发生

2019年10月16日 | stm32f103+znfat+ch375+vs1003实现简单mp3播放器功能

2019-10-16 来源:eefocus

以前做毕业设计买了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(); //刷新文件系统

 }  

}   

   

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


最后来一张实物图


推荐阅读

史海拾趣

申风(everanalog)公司的发展小趣事

作为一家有社会责任感的企业,申风(everanalog)公司始终关注社会发展和环境保护问题。公司积极参与公益事业和环保活动,致力于为社会做出积极贡献。同时,公司也注重可持续发展战略的制定和实施,在生产经营过程中注重节能减排和资源循环利用等方面的工作。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。

请注意,以上故事框架仅为示例,并未包含具体的细节和数据。如需了解更多关于申风(everanalog)公司的具体信息和发展历程,请查阅相关新闻报道或官方资料。

Foxconn_Optical_Interconnect_Technologies__Inc.公司的发展小趣事

随着技术实力的不断提升和产品线的日益丰富,申风(everanalog)公司开始积极拓展市场。公司凭借优质的产品和服务,逐渐在国内市场上树立了良好的品牌形象。同时,公司也积极开展国际合作,与国际知名企业建立了战略合作关系,共同推动集成电路产业的发展。这些合作不仅为公司带来了更多的商业机会,也提升了公司在国际市场上的竞争力。

Dynastream公司的发展小趣事

展望未来,Dynastream将继续秉承“持续创新、追求卓越”的发展理念,致力于成为电子行业的领军企业。公司将继续加大研发投入,提高产品的技术含量和附加值;同时,也将注重人才培养和团队建设,为公司未来的发展提供有力保障。相信在不久的将来,Dynastream将在电子行业中创造更加辉煌的业绩。

请注意,以上故事均为基于Dynastream公司发展历程的假设性叙述,旨在展示其发展历程中的一些重要节点和成就。

Ceramics公司的发展小趣事

“绿色陶瓷”公司以其环保理念为核心,致力于研发和生产环保型陶瓷电子材料。该公司采用可再生资源和低能耗生产工艺,成功降低了产品对环境的影响。同时,绿色陶瓷还积极推广循环经济模式,通过回收再利用废旧陶瓷材料,实现了资源的最大化利用。这一环保理念不仅赢得了消费者的青睐,也为公司在电子行业的可持续发展奠定了坚实基础。

Ericsson Power Modules公司的发展小趣事

在创立初期,Ericsson Power Modules就展现出了强大的技术创新能力。公司团队通过深入研究电源技术、电路板应用和系统知识,成功开发出了一系列高性能、高效率的电源模块产品。其中,DC-DC转换器、中级和先进总线转换器、POL稳压器等产品因其卓越的性能和稳定性,在市场上赢得了广泛好评。这些技术突破和产品创新为Ericsson Power Modules的后续发展奠定了坚实的基础。

Everspin公司的发展小趣事

随着技术的不断进步,Everspin不断推出新的MRAM产品,并逐渐将市场扩展到工业自动化、游戏、能源管理、通讯、运输和航空电子等多个领域。特别是其MRAM和STT-MRAM产品在数据中心、云存储、能源、工业、汽车和运输市场中的广泛应用,为全球MRAM用户奠定了最强大、增长最快的基础。

问答坊 | AI 解惑

用两个M8+红外控制+LCD菜单 制作的频率发生器。

项目名称:频率发生器 v2.0   项目简介:通过LCD上的菜单,实时设置Mega8的三个定时器的各个寄存器,这样,      就可以通过示波器来监视Mega8的定时器的各个寄存器相互作用.   比如:Mega8的T1定时器,是最难 ...…

查看全部问答>

想问问各位做ARM嵌入式的工资高不高?

来自EEWORLD合作群:arm linux fpga 嵌入0(49900581) 群主:wangkj …

查看全部问答>

求助:ce6.0下加第三方驱动不能成功?

想在6.0下使用penmount触摸屏控制器,驱动已经编译到NK中,可CE运行后就是没有加载pmser.dll文件? 注册表都设置没有问题,如下所示: [HKEY_LOCAL_MACHINE\\Drivers\\BuiltIn\\PMSer]    \"Dll\"=\"pmser.dll\"    &nbs ...…

查看全部问答>

问一个关于注册表的低级问题

在platform.reg里面,有好多如: ; @CESYSGEN IF !CE_MODULES_FW6 \"EnablePacketFiltering\"=dword:1 ; @CESYSGEN ENDIF 这样的语法。请问: 分号+@是表示注释还是别的什么意思?…

查看全部问答>

请教:wince 4.2添加.cec后失败

    原来俺一直搞pc软件,现在开始接触wince 4.2了。碰到点问题,想请教下子大家,请多多帮忙呀。     俺想试验试验拷贝文件到wince文件系统里面(作为feature自动打包进去,而不是通过远程 文件传输或其他安装后的方式), ...…

查看全部问答>

问一下我这个外部中断定时50ms测频率怎么没显示啊?呜呜。。

#include #include sbit RS=P2^0;    //寄存器选择位,将RS位定义为P2.0引脚 sbit RW=P2^1;    //读写选择位,将RW位定义为P2.1引脚 sbit E=P2^2;     //使能信号位,将E位定义为P2.2引脚 sbit BF= ...…

查看全部问答>

F2803x入门之三:实例应用

F2803x入门之三:实例应用      本例是在《F2803x入门之二:工程建立》的基础上进行修改的。通过修改代码、添加中断、GPIO初始化、部分模块初始化等使初学者可以建立自己的工程,并使之正常“跑”起来! 一、一、代码修改: ...…

查看全部问答>

新人紧急求助…………如何用STC系列产生频率可调的方波?????????

单片机型号是 STC 12C5A60S2 ,请问如何编程输出 4KHz——5KHz 幅度1V 频率可变的方波? 4X4按键要求按下某一按键之后频率+1或-1,+10或-10,通过1602液晶实时显示当前频率。 本人是全新手,还望各路大侠倾情解救……希望有完整源码与注释。感激 ...…

查看全部问答>

发现一个bug

从bbs主页:https://home.eeworld.com.cn/forum.html上点击“新帖综览”右侧的“更多”企图查看最新帖列表,但页面提示“您所在的用户组(版主)无法进行此操作”,只能再次点击“全部新帖”才能进入新帖列表。 …

查看全部问答>

招募电子学翻译

要求有较好的专业基础和英语基础,有责任心,认真负责。 有相关图书翻译经验的老师优先 欢迎联系 待遇:翻译署名权+按千字计算稿酬 可详谈 简历请投 774824480@qq.com 或加Q 774824480交流…

查看全部问答>