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

发布者:PeacefulOasis最新更新时间:2019-10-16 来源: eefocus关键字: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("串口设置完毕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


最后来一张实物图


关键字:stm32f103  znfat  ch375  vs1003  单mp3播放器 引用地址:stm32f103+znfat+ch375+vs1003实现简单mp3播放器功能

上一篇:STM32F103RC驱动CH375B模块读写优盘扇区数据
下一篇:点击Debug按钮提示“uVision IDE 已停止工作”的一种解决办法

推荐阅读最新更新时间:2024-11-04 20:17

STM32F103串口1 printf函数的实现
  在单片机中使用最多的通信接口基本就是串口了,说起串口就不得不提串口中最常用的一个函数就是打印函数printf()函数,在上位机上中这个函数直接从库函数中调用就可以了,那么在单片机中这个函数要怎么使用呢?能不能将这个函数和串口1对应起来,当然是有方法的。   下面就通过代码来演示一下如何在串口1上使用printf()函数的功能。 void uart_init(u32 bound) { //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_Ini
[单片机]
<font color='red'>STM32F103</font>串口1 printf函数的实现
STM32F103C8T6引脚功能分布
引脚分布: 数据手册中的:
[单片机]
<font color='red'>STM32F103</font>C8T6引脚功能分布
STM32F103攻城笔记】外部晶振HSE倍频设置系统时钟
上一篇的内部晶振的系统时钟设置已经对系统时钟进行了配置,而外部晶振的倍频只需要改变上一篇的初始化函数就可以,其他均一样! 第一步:建立一个HSE倍频的初始化函数void SystemClock_Config(void) ; 所以我们由上一篇文章变为: int main (void) { RCC_ClocksTypeDef RCC_Clocks; //初始化 SystemClock_Config(); //调用刚才改过的函数 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Usart_Init(115200); //串口为了看数据而已 RCC_GetClocksF
[单片机]
关于内外时钟切换及时钟超频测试
前言 近日,有群友困于STM32的时钟系统。这里就详细介绍一下关于内外时钟切换及时钟超频测试,希望对大家能有所帮助 诚然,当使用固件库时,把外部晶振摘掉,系统确实会自动切换到内部时钟,但是只会以8M的默认值运行,显然这是十分不可行的,8M的速度直接让我们的STM32病入膏肓,今天的任务就是让STM32失去外挂(晶振)时,依旧可以激情澎湃。 时钟详解这里不过多介绍,自己也没有别人介绍的好,本文旨在解决现实问题。 此处插播广告:群友问过这种问题,外部接8M晶振和16M晶振有啥区别? 以我微薄的经验来看,这两个在用的时候差别不大,如果使用ST的固件库(以STM32F103为例),使用8M的晶振会更方便,不用改任
[单片机]
关于内外时钟切换及时钟超频测试
STM32F103RCT6+USART3+UART5初始化代码
USART和UART的区别就是:USART支持同步收发,UART只支持异步收发 同步模式:USART 需要同步始终信号USART_CK,通常情况同步信号很少使用,因此一般的单片机UART和USART使用方式是一样的,都使用异步模式。 1 USART3初始化 void USART3_init(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //使能USART3,GPIOB时钟 RCC
[单片机]
CH375_CH376 U盘读写模块在51单片机上的应用
电路原理图如下: ch375资料手册: 本程序的接线图: 单片机源程序如下(host.c文件): /* **************************************** ** Copyright (C) W.ch 1999-2004 ** **************************************** ** USB Host File Interface for CH375 ** ** TC2.0@PC, KC7.0@MCS51 ** **************************************** */ /* CH375 主机文件系统接口 */ /* 支
[单片机]
CH375_CH376 U盘读写模块在51单片机上的应用
STM32F103C8T6用官方bootloader实现IAP升级操作方法
在使用STM32F103C8T6单片机IAP功能时,可以自己写bootloader程序,也可以使用官方bootloader文件。下面说一下使用官方bootloader的使用方法。 首先下载官方bootloader文件 目前使用的是这个版本,打开文件夹,选择适合自己编译器的工程。 目前使用的是keil,所以打开MDK-ARM文件夹 打开IAP工程 打开后根据自己的单片机型号,对工程进行简单的修改。用的是STM32F103C8T6单片机,FLASH为64K,SRAM为20K。 设置IROM1的起始地址和大小。 设置引用的头文件,STM32F103C8T6为中等容量,所以设置文件为STM32F10X_MD,。
[单片机]
<font color='red'>STM32F103</font>C8T6用官方bootloader实现IAP升级操作方法
基于IAR环境下STM32F103单片机读取BME280程序
自己编写的基于IAR环境下STM32F103单片机读取BME280程序,没有太多的寄存器操作,简单易懂,可以直接调用,上电后只要对IO口初始化,调用函数Bme_ReadDigValue()读取校准寄存器参数并保存,再调用函数Bme_Init()初始化之后就可以用函数Bme_ReadStatus()读取传感器状态判断是否读取数据了,也可不判断传感器状态直接读取数据,读取数据直接调用函数ReadBme280()。 单片机源程序: void ReadBme280() { u32 value_ad; double var1; double var2; double var3; double
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved