本帖最后由 FrRSVI 于 2025-2-13 23:13 编辑

一. 引言
感谢面包板社区和富芮坤电子给予本次评测机会。

二.前期准备
查看芯片手册以及参考手册,发现FR3068芯片性能还是很强大的,SPI,I2C、UART,QSPI,SPDIF,PWM,ADC,DAC,SDIO,LCD接口,CAN,USB OTG,蓝牙等等功能应有尽有。


三.上手测试
1. 初次打开keil会提示找不到芯片包,查询论坛发现是软件包版本的问题,在网上下载ARM CMSIS 5.8.0版本的包,可以选择ARMCM33_DSP_FP_TZ。




2.打开LVGL工程点击编译会报错,需要修改部分代码

(1)打开注释《#include "fr_device_rtc.h"》

(2)在main.c中添加一下《#include "driver_st7282_rgb_hw.h"》

3.debug需要修改代码,默认工程使用了LCD屏会占用SWD引脚

4.串口下载时,要注意在配置User选项卡下,需添加"..\..\..\..\components\tools\keil\post_process.bat" "@L" "#L" "$J" ,这样编译才会生成Project_burn.bin串口烧录bin文件


四.课题学习记录


我选择的是课题4-【富芮坤FR3068x-C】基于REPL Micro Python实现本地音乐播放,于是有了如下的学习内容:

1)Micro Python简介

Micro Python 约等于一个可以运行在 微控制器上的 Python解释器,它使得我们可以编写Python脚本来控制硬件。解释型语言大多也称作为脚本语言,例如Python这类不需要编译的编程语言,我们可以在交互式的Python解释器环境中输入一行指令,执行一行指令,获得输出;也可以把写好的脚本文件一次性交给Python解释器去解释执行。

对应的,非解释型语言典型的以 C 语言为例,这类语言编写的代码需要通过*编译器 *编译之后才能被执行。我们编写的代码,无论C语言也好,Python语言也好,都是希望计算机去执行。但是计算机是机器,只能识别01构成的二进制代码。因此,为了让机器搞懂我们现在编写的C语言代码,或Python语言代码,都需要经过一番转换,才能变成计算机设备能够理解的东西,进而才能被正确执行。

Micro Python虽然在很大程度上都能无缝的支持Python的语法,Python的理念,但是,由于Micro Python是设计运行在微处理器上的,所以他在某些方面实现了精简以此来保障性能。同时在某些地方,Micro Python和普通的Python解释器存在一些微小的差异,所以说约等于。


2)REPL简介

REPL是以下四个英语单词的首字母缩写:

- Read (读入)

- Evaluate(执行)

- Print (打印)

- Loop (循环)

这四个单词准确的概括了交互式解释器环境的特点,因此REPL通常也就代指交互式解释器环境。

一般的脚本语言都拥有自己的解释器, Python和Micro Python也不例外,我们可以把写好的脚本文件一次性扔给解释器,同样的也可以这样和解释器进行交互:

- 写一句代码 如

print('hello world')(读入)

- 按下回车 解释器执行一句 (执行)

- 打印输出

'hello world'(打印)

- 你可以继续循环以上步骤 (循环)


值得一提的是,在每次新的REPL循环开始的时候,总会有>>> 在一行的最开始,我们把>>>称作命令提示符

如果代码是输入到REPL的话,都会添加 >>> 标志例如:>>> print('hello world')以上代码块代表是在REPL里面输入了print('hello world'), 而 >>> 不需要输入。

使用REPL是在Micro Python中 测试代码 *和 *运行代码 **最简单的方法。


3)WAV简介

‌WAV格式‌是由微软公司开发的数字音频文件格式,符合RIFF(Resource Interchange File Format)文件规范,主要用于保存Windows平台的音频信息资源。WAV格式支持多种压缩算法,如MSADPCM、CCITT A律和CCITT μ律等,同时也支持多种音频位数、采样频率和声道配置。

image.png



image.png

image.png

WAV文件的PCM音频数据以小端形式来进行数据存储。

先简单的说明一下大端存储和小端存储的区别。

大端存储:数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;

小端存储:数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。


这里解释一下WAV文件数据存储的最小单元是采样点,也就是说,如果WAV头中配置采样点的大小是16bit,那么两个字节代表一个采样点(Int16),如果为32bit则是4个字节代表一个采样点(Int32)。然而,它们都是无符号整型,只是采样的精度不同而已。另外,要为每个声道都存储采样点。如果是单声道的话,采样点就是简单的顺序排列。如果是双声道,采样点就是左右声道交错排列。采样频率也需要与数据的保持一致,否则可能会造成音频播放速度上出现异常。


具体的格式可以参照下图进行理解:

image.png

4)mp3简介

Layer-3 音频文件,MPEG(Moving Picture Experts Group) 在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG音频文件是MPEG1 标准中的声音部分,也叫MPEG 音频层,它根据压缩质量和编码复杂程度划分为三层,即Layer-1、Layer2、Layer3,且分别对应MP1、MP2、MP3 这三种声音文件,并根据不同的用途,使用不同层次的编码。

MPEG 音频编码的层次越高,编码器越复杂,压缩率也越高,MP1 和MP2 的压缩率分别为4:1 和6:1-8:1,而MP3 的压缩率则高达10:1-12:1,也就是说,一分钟CD 音质的音乐,未经压缩需要10MB的存储空间,而经过MP3 压缩编码后只有1MB 左右。不过MP3 对音频信号采用的是有损压缩方式,为了降低声音失真度,MP3采取了“感官编码技术”,即编码时先对音频文件进行频谱分析,然后用过滤器滤掉噪音电平,接着通过量化的方式将剩下的每一位打散排列,最后形成具有较高压缩比的MP3 文件,并使压缩后的文件在回放时能够达到比较接近原音源的声音效果。

MP3 文件大体分为三部分:TAG_V2(ID3V2),音频数据,TAG_V1(ID3V1)

image.png

a). ID3V2 在文件开始的位置,包含了作者,作曲,专辑等信息,长度不固定,扩展了ID3V1 的信息量。

b). 一系列的音频数据的帧,在文件的中间位置,个数由文件大小和帧长决定;

每个帧的长度可能不固定,也可能固定,由位率bitrate决定

每个帧又分为帧头和数据实体两部分

帧头记录了mp3 的位率,采样率,版本等信息,每个帧之间相互独立 。

c). ID3V1在文件结尾的位置,包含了作者,作曲,专辑等信息,长度为128Byte。

ID3V2

包含了作者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。

Frame。

参考链接:

https://blog.csdn.net/fulinwsuafcie/article/details/8972346




.动手实验


1)在此感谢qinyunti大佬移植的micropython工程,链接:https://mbb.eet-china.com/forum/topic/147876_1_1.html

2) MP3解码参考的是野火电子提供的例程,感谢开源。

现在合适在小型嵌入式控制器移植运行的有两个版本的开源MP3解码库,分别为Libmad解码库和Helix解码库,Libmad是一个高精度MPEG音频解码库,支持MPEG-1、MPEG-2以及MPEG-2.5标准,它可以提供24bitPCM输出,完全是定点计算,更多信息可参考网站:http://www.underbit.com/。

Helix解码库支持浮点和定点计算实现,将该算法移植到STM32控制器运行使用定点计算实现,它支持MPEG-1、MPEG-2以及MPEG-2.5标准的Layer3解码。Helix解码库支持可变位速率、恒定位速率,以及立体声和单声道音频格式。更多信息可参考网站:https://datatype.helixcommunity.org/Mp3dec。

因为Helix解码库需要占用的资源比Libmad解码库更少,特别是RAM空间的使用,这对STM32控制器来说是比较重要的,所以在实验工程中我们选择Helix解码库实现MP3文件解码。这两个解码库都是一帧为解码单位的,一次解码一帧,这在应用解码库时是需要着重注意的。

Helix解码库是用来解码MP3数据帧,一次解码一帧。

--特别注意:它是不能用来检索ID3V1和ID3V2标签的,如果需要获取歌名、作者等信息需要自己编程实现。一开始出错,会打印UNKNOWN ERROR,就是没注意MP3文件的开头数据。


解码过程用到的Helix解码库函数有:

MP3InitDecoder:初始化解码器函数

MP3FreeDecoder:关闭解码器函数

MP3FindSyncWord:寻找帧同步函数

MP3Decode:解码MP3帧函数

MP3GetLastFrameInfo:获取帧信息函数


无标题2.png
移植所需Helix解码库文件

其实与解码wav这种原始文件相比,解码MP3文件只是多增加了还原压缩数据这一步,其余操作与wav一致。在解码MP3数据时需要开辟两个大数组,一个用来存储mp3数据,还有一个用来存储还原后的PCM数据。数组大小就按照MP3文件一帧的最大值设置就可以了。

最后,MP播放MP3的操作步骤如下:
1)在shell命令下输入micropython即可进入MP环境
2)输入1-import pyb
            2-audio=pyb.AUDIO(1)
            3-audio.play("2:/xxx.mp3")
即可听到存储在外部Flash中的mp3音乐了。
在播放过程中可以发送以下指令控制:
audio.mute(1) 静音

audio.mute(0) 不静音

audio.volume(x)可以听到声音大小变化

audio.stop可以提前结束播放

无标题.png
注:视频效果如下

六.总结

    评价:使用富芮坤FR3068E-C芯片可以使用内部DAC+运放替代I2S+外部DAC方案,满足播放音频的需求,确实是高性价比的解决方案。


    总之,富芮坤FR3068E-C芯片资源丰富,性能也强,尤其针对音频解决方案集成度很高,直接使用PWM-DAC输出播放音频效果也非常不错,从演示视频可以看到,播放效果非常好几乎无杂音,完全不需要外置音频芯片也可以满足大部分应用,是高性价比的解决方案。