本节我们来使用stm32、TF卡以及VS1003芯片来制作一台简易的MP3播放器。

VS1003是一个集成的MP3解码芯片,它能自动完成MP3、WMA、WAV、MIDI等格式音频文件的解码。

我们利用stm32的SPI接口,通过必要的初始化配置后,从TF/SD卡中读取MP3文件,发送给VS1003,就能完成声音的输出。

1)硬件设计

VS1003芯片的外围需要搭配晶振、阻容等器件;供电需要2.85V和2.5V;通信接口使用SPI,其他必要的信号除了CS片选外,还需要XDCS(数据片选)、XRESET(复位)、DREQ(状态监测)。

实际上,为了减少硬件制作的工作量,我们可以购买VS1003的电路模块,已经搭配好外围器件,只要供电5V、连接通信接口相关的线即可使用,本文选用的是下图这种:

如果diy能力比较强,可以依据下图自己做板子:

STM32使用的具体型号是STM32F103C8T6。选用这款单片机,它没有SD卡接口,只能通过SPI接口去访问SD/TF卡,这样更具有学习意义。

VS1003模块挂载SPI2接口上,TF卡挂载在SPI1接口上(其实二者挂同一个SPI口上也是可以的,这里主要是因为我在实现时,用的是杜邦线连接,分到两个口上比较好插线)。

SD卡或者TF卡的SPI接口接线定义如下图所示,左边为SD卡,右边为TF卡,我们使用SPI接口,只用连接电源以及SPI的4根线即可:

STM32的引脚如下图分配,PA4用作TF卡的片选,PB3~PB6用作操作VS1003的IO口(各引脚的作用已在命名上区分),串口用于打印状态信息,具体见图:

2)cubemx中的设置

在cubemx中建立工程时,如下图所示:

在SPI1建立时,先将速率设为比较低(因为某些低速的存储卡需要初始化时速率在100k~400k,初始化完后,读取数据时,可以把速率设得比较高):

SPI2建立时,速率设为1~2M左右,以便于操作VS1003时速率足够快:

GPIO设置如下:

打开中间件FATFS,并开启长文件名支持,其他不用改:

将堆栈空间设置得大一些:

这样就设置好了,可以生成keil工程,并在keil中编写代码。

3)keil中的代码编写(TF卡和FATFS文件系统部分)

首先了解SPI接口的TF/SD卡初始化过程。

SPI模式下的初始化操作主要过程有:上电->进入SPI模式(CMD0)->检测当前MCU电压是否符合SD卡的要求(CMD8)->开始初始化(ACMD41)->读取卡类型(CMD58)。

当电压达到SD卡的最小工作电压的后,MCU必须使CS,DI为高电平,输出最少74个时钟脉冲后,才能开始发送第一个命令。

SD卡上电后处于SD Bus模式,使CS保持为0,并且发送CMD0命令,SD卡就会进入到SPI模式。在SPI模式下,命令的CRC校验功能默认是禁止的(CMD8命令除外),但是发送第一个CMD0命令时,SD卡是处于SD Bus模式,该模式下CRC校验功能是启动的,因此第一个CMD0命令必须要有正确的CRC校验。正确的CMD0命令应为:0x40, 0x00, 0x00, 0x00, 0x00, 0x95。

CMD8用于检测SD卡接口电压是否满足要求,该命令的参数包括当前MCU接口的电压范围VHS([11:8]),以及用于检测通信的Check Pattern([7:0])。如果SD卡能满足当前MCU的接口电压,它就会返回VHS和Check Pattern的值。需要注意的是,CMD8的CRC校验值必须正确,假如CRC校验不对,SD卡返回的R1值中的CRC错误位就会置1。正确的CMD8的命令应为:0x48,0x00,0x00,0x01,0xaa,0x87。

ACMD41命令用于开始初始化SD卡及检测其是否完成初始化。该命令的参数HCS([30])表示MCU是否支持SDHC和SDXC,若支持HCS置1,反之置0。如果ACDM41命令返回R1的值为0x01,说明SD卡正在初始化,MCU需要重复发送ACMD41,直到返回值R1为0。

初始化完成后,通过发送CMD58指令读取卡的类型(OCR寄存器的CCS位[30]), CCS为1表示当前卡的类型为SDXC或者SDHC,为0表示卡的类型为SDSC。

还有一些其他的指令,可以参见SD卡的操作说明。

初始化过程的代码较长,这里限于篇幅就不贴了,有兴趣可以在文某关注公众号,留言获取所有的源代码。源码中这部分有详细的注释,在SDdriver.c这个文件中:

接着,看文件系统的使用。

这部分我们使用了cubemx自带的中间件——FATFS,只要移植几个函数即可。

在keil工程中,打开user_diskio.c文件,

先改写初始化和获取状态的两个函数,直接修改为返回OK,如下:

用户读函数,主要是依据参数,将它引导到调用SD_ReadDisk()这个函数:

由于我们制作MP3只用到了读存储卡,所以可以不用实现用户写函数(实际上,FATFS中的很多功能,如果不使用也都可以裁剪掉,如USER_write、USER_ioctl函数都可以不用实现)。

SD_ReadDisk()这个函数,主要实现了按扇区读的操作:

读取单个扇区时,调用SD_sendcmd函数发出读取单个数据块命令CMD17,若存储卡返回响应无错误(返回0),则调用SD_ReceiveData函数等待数据块起始标识符0xFE,然后开始读取数据块和CRC校验。

读取多个扇区时,操作和读取单个数据块的相似,先发送命令CMD18,然后开始等待数据块的起始标识符。需要停止读取操作时,发送CMD12命令,返回响应为0表示存储卡处于忙碌状态,只有返回任何不为0的值后,MCU才能发送下一条命令。

SD_sendcmd和SD_ReceiveData函数主要的代码如下:

这里注意一下crc和校验虽然读取了,但并没有使用它。

以上就是读SD卡数据的实现,也就是与FATFS使用必须的函数都已经实现了。

3)keil中的代码编写(VS1003部分)

VS1003中的代码相对简单一些。

初始化时,只需要完成复位、寄存器配置等操作。

复位即是将复位线拉低一段时间,再恢复。

寄存器的配置,最主要的是进入播放模式、设置时钟、设置音量。VS1003要求SPI时钟在主时钟SCLK/6以下,所以,如果想要使用较高速率的SPI接口,就要设置时钟3倍频;音量这里,高8位和低8位分别表示左右声道的衰减dB数,要设置得合适一些,实测衰减设置得较小时,播放的声音会很不正常。

VS1003初始化的代码如下:

实际上,采样率这里不设置也是可以的,因为mp3文件里已经包含了采样率的数据,这里的设置如果不对,vs1003也能按正确的码率解码出声音。

至于播放MP3的过程,就是从存储卡中读取MP3文件内容,再将其发送给VS1003就可以了。不用关心mp3文件的码率、采样率等参数,因为这些在音频文件中都会记录,发送给VS1003后它能自动识别。

操作的主要过程如下:

包括挂载存储卡、读取磁盘目录、循环查找后缀为“mp3、mid、wma、wav”格式的文件,然后读取文件内容,发送给VS1003。

上图中最后if内部执行的是,找到有后缀符号的文件后,打开文件,每次读取512个字节放在buffer中。

当DREQ为高时(允许发送,表示vs1003至少能接收32个字节数据),发送32个字节给VS1003。

到文件末尾时,再发送2048个0给VS1003,停止发送,关闭文件,具体的代码如下:

执行完后,还需要卸载存储卡:

4)代码测试

把tf卡格式化为FAT32格式,存入MP3文件(最好文件名用英文和数字,文件名短一点),然后就可以上电测试了。

测试结果如下:

由打印信息可见,VS1003的寄存器成功写入,存储卡也初始化成功,并且打开mp3文件成功。

同时,接上耳机,可以听到音乐播放。

在实现过程中遇到的一些不理解的问题,也记录在这里:

a)左右声道设置为一样的衰减时,声音很不正常;而且两个声道的音量大小只受小衰减倍数的一边控制,比如设为0xf030,则两个声道的音量实际是衰减为0x30dB,高位的f0完全没起作用,不知道哪里有问题,有明白的大佬可以指点一下;

b)偶尔会发生音量突变成很大声音,现象和音量衰减为全0一样,而且此时播放速度变慢了,打印寄存器发现除了SPI_MODE正常,其他都被清零了,感觉是硬件哪里有问题。

好了,本节使用stm32的SPI接口,挂载TF卡、VS1003制作MP3的内容就讲到这了。

由于本节内容比较多,代码量比较大,本人的技术水平也有限,有些地方讲的很粗略,算抛砖引玉,有兴趣的可以就某些细节深入研究一下,欢迎留言讨论。

欢迎关注我的微信公众号“小白白学电子”,可留言“资料”获取所有电路、源码和参考资料:

使用STM32 和 TF卡、VS1003制作MP3相关推荐

  1. 使用vs1003制作MP3问题总结

    这是自己的第一篇博客,心中不免有些小激动,就算自己的经验总结和与别人一起分享吧! 做MP3需要控制器(stm32).存储器(SD卡).音频解码器(vs1003),今天专讲使vs1003发生的问题. 首 ...

  2. linux下制作ext3格式的tf卡

    tf卡与sd卡的区别:前者小卡,后者大卡:TF卡在linux系统中通常为/dev/mmcblk0,SD卡通常为/dev/sda1.以下是格式化TF卡并制作etx3格式的步骤: 1.fdisk /dev ...

  3. STM32挂载SD卡记录日志

    STM32挂载SD卡记录日志 程序主要是在前一篇的基础上进行.使用CUBE配置STM32挂载TF卡,请看https://ydgd118.blog.csdn.net/article/details/11 ...

  4. itop-4412学习笔记:TF卡烧写

    1. 制作可以烧写的TF卡(TF卡内存至少2G) 给TF卡分区.需要将TF卡先插入开发板,然后再启动开发板并进入Uboot模式,然后在超级终端中,依次输入下列烧写命令: fdisk -c 1 fatf ...

  5. STM32单片机语音识别MP3播放器音乐播放器TF卡播放器

    实践制作DIY- GC0086-音乐播放器 一.功能说明: 基于STM32单片机设计-音乐播放器 功能介绍: STM32F103C系列最小系统板+语音识别模块+TF卡MP3播放模块+喇叭+3个按键 1 ...

  6. 73、基于STM32单片机录音机录音笔语音存储回放播放器TF卡TFT屏系统设计

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.PCB图 六.程序源码 七.资料包括 摘要 随着生活水平的提高,人们对消费电子的需求也 ...

  7. Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  8. Jetson-nano:制作TF卡启动

    旧Nano可以直接导入镜像至TF卡,然后插入卡槽即可启动系统. 但目前旧的英伟达已经停止生产底板,现在市面上都是带emmc的核心板,底板是由其他厂商进行扩容自行生产的,因为官方自带的emmc只有16G ...

  9. stm32开发3D打印机(五)——TF卡spi协议与FATFS文件系统(已完成)

    借鉴于正点原子stm32 Mini板 下方的代码仅为对TF卡的初始化 FATFS移植方法请看正点原子Mini板教程,以及建议完成USMART的移植 因为TFATFS移植与USMATRT没有什么好写的, ...

最新文章

  1. 【转】教你在PHP中使用全局变量
  2. go 使用mongodb
  3. dart系列之:dart语言中的异常
  4. 数字后端——可制造性设计
  5. linux 浏览器 links,linux下的命令行浏览器links
  6. mysql5.7安装教程centos_MySQL5.7版CentOS系统简易安装教程
  7. 你不可不看的 Oracle RAC 日常基本维护命令
  8. c语言第五章137页题目及答案,(完整版)C语言程序设计教程第五章练习题题目
  9. socket 收不到16进制 数据_UDP编程-套接字(socket)
  10. 客户端请求时间和服务端处理时间不匹配问题
  11. S3C2440 进行微秒级、毫秒级延时函数
  12. 读Zepto源码之Callbacks模块
  13. 卡特兰数-两个经典做法
  14. windows内核驱动开发(WDK环境搭建)
  15. 服装商城电商-前端网页技术精美完整源码HTML+CSS+JS
  16. 必备知识:相机标定-旋转矩阵性质
  17. ckplayer html播放本地,vue中使用ckplayer播放器
  18. 软件设计中的心跳机制
  19. 第27天 LDT与库
  20. Spring Security | 轻松搞定认证授权~

热门文章

  1. medium hosts
  2. vue单应用在ios系统中实现微信分享功能
  3. 国际漫游通信服务应跟进
  4. 一招教你如何搜索国内各大网盘资源
  5. 2017年9月历史文章汇总
  6. mysql errorcode 1366_mysql插入emoji表情报 error code [1366]
  7. 树莓派玩黄油,编译运行ONScripter
  8. 【Linux】linux下删除/清空文件夹/文件命令
  9. @Value(“${}“) 和 @Value(“#{}“) 的区别
  10. 微处理机就是微型计算机,他们是《微型计算机》改版20年的历史见证者