| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> 使用STM32 和 TF卡、VS1003制作MP3 -> 正文阅读 |
|
[嵌入式]使用STM32 和 TF卡、VS1003制作MP3 |
本节我们来使用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的内容就讲到这了。 由于本节内容比较多,代码量比较大,本人的技术水平也有限,有些地方讲的很粗略,算抛砖引玉,有兴趣的可以就某些细节深入研究一下,欢迎留言讨论。 欢迎关注我的公众号,可留言“资料”获取所有电路、源码和参考资料: |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 10:47:04- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |