公告

大中华汽车电子生态圈社区并入开发者社区- 更多资讯点击此

Tip / 登入 to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Translation_Bot
Community Manager
Community Manager
Community Manager

你好,

由于需要传输大型音频文件并逐段读取数据,目前使用单缓冲进行数据传输会在每个片段之间产生噪声。 我能想到的是使用类似于 STM32 MCU DMA 的双缓冲机制。 PSOC DMA 有双缓冲功能吗? 或者还有其他方法可以解决这个噪音问题吗?

问候,

克里斯

0 点赞
1 解答
lock attach
Attachments are accessible only for community members.
Translation_Bot
Community Manager
Community Manager
Community Manager

我修改了音频播放项目,使其使用双缓冲 DMA 传输。 现在 DMA1 由两个传输描述符组成:TD0 和 TD1,它们将中间缓冲区的内容复制到中间位置 TMP。 TD0 从缓冲区的前半部分逐字节复制数据,然后将任务传递给 TD1,后者从缓冲区的后半部分复制数据,然后循环回到 TD0。 缓冲区的总大小为 64 字节,每半的大小为 32 字节。 实际大小应根据代码的延迟时间来设置,但是 128+128 通常是一个不错的大小。

一旦 TD0 或 TD1 完成,就会触发中断,表示这半缓冲区现在需要新的数据(而另一半正忙)。 这里的处理器需要从数据源(这里是闪存)中复制新数据,然后等待下一个数据请求,同时不间断地持续播放数据。

数据源可以是 RAM、FLASH、SD 卡或处理器生成的数据(正弦等)。

该项目被配置为在启动时在循环中播放 Sawtooth 波形。 或者,也可以将其配置为单次播放,或者在按下按钮时播放。

随附的项目包括所有必要的组件。 该项目正在运行,但尚未经过全面测试。

 

图 1。 项目描述显示了从闪存到缓冲区,再到 RAM 中的 TMP 位置,最后到 IDAC 的数据流。

AudioPCM_DMA2_01a_DMA.png

 

图 2。项目示意图。 DMA1 配置为两个 TD。

AudioPCM_DMA2_01a_A.png

 

图 3。启动时输出波形。 测试数据为 Sawtooth,每时段 256 分,连续循环播放。

AudioPCM_DMA2_01a_D1.png

 

图 4。配置为 SINGLE_SHOT 时的锯齿波形输出。 数据点数 256 个,玩过一次。 数据结束后,输出被设置为某个预定义值(这里是 127)。

AudioPCM_DMA2_01a_D2.png

 

 

在原帖中查看解决方案

0 点赞
6 回复数
Translation_Bot
Community Manager
Community Manager
Community Manager

@chwa_1570756

简短的回答:是的。

使用 DMA,您可以分配两个(或更多)TD(传输描述符)。 每个 TD 可以指向内存(缓冲区)的不同部分,并且可以链接起来,这样 TD 完成后它将自动启动下一个 TD。 此外,你可以在每个 TD 完成后请求中断,这样你就可以知道 TD 已经完成并可以开始用新数据重新填充内存。

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

嗨 Len,

谢谢你的好建议。

但是,仍然存在一些令人不安的问题:

1。这两个描述符是否相互连接以形成一个循环?

2。我需要为每次数据传输触发信号吗?

3。如何确定哪个描述符生成了中断信号?

问候,

克里斯

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

你能详细描述一下这个项目吗? 例如,如何通过代码或 DMA 从 SD 复制数据?

0 点赞
lock attach
Attachments are accessible only for community members.
Translation_Bot
Community Manager
Community Manager
Community Manager

我通过 Fatfs 代码从 SD 复制数据,一个音频文件数据大于 65536 字节。

实际上,我使用的是你提供的音频 DMA 示例,我刚刚将音频数据复制到 MCU 闪存中替换了原始数据。

附上我的项目。

 

0 点赞
lock attach
Attachments are accessible only for community members.
Translation_Bot
Community Manager
Community Manager
Community Manager

我修改了音频播放项目,使其使用双缓冲 DMA 传输。 现在 DMA1 由两个传输描述符组成:TD0 和 TD1,它们将中间缓冲区的内容复制到中间位置 TMP。 TD0 从缓冲区的前半部分逐字节复制数据,然后将任务传递给 TD1,后者从缓冲区的后半部分复制数据,然后循环回到 TD0。 缓冲区的总大小为 64 字节,每半的大小为 32 字节。 实际大小应根据代码的延迟时间来设置,但是 128+128 通常是一个不错的大小。

一旦 TD0 或 TD1 完成,就会触发中断,表示这半缓冲区现在需要新的数据(而另一半正忙)。 这里的处理器需要从数据源(这里是闪存)中复制新数据,然后等待下一个数据请求,同时不间断地持续播放数据。

数据源可以是 RAM、FLASH、SD 卡或处理器生成的数据(正弦等)。

该项目被配置为在启动时在循环中播放 Sawtooth 波形。 或者,也可以将其配置为单次播放,或者在按下按钮时播放。

随附的项目包括所有必要的组件。 该项目正在运行,但尚未经过全面测试。

 

图 1。 项目描述显示了从闪存到缓冲区,再到 RAM 中的 TMP 位置,最后到 IDAC 的数据流。

AudioPCM_DMA2_01a_DMA.png

 

图 2。项目示意图。 DMA1 配置为两个 TD。

AudioPCM_DMA2_01a_A.png

 

图 3。启动时输出波形。 测试数据为 Sawtooth,每时段 256 分,连续循环播放。

AudioPCM_DMA2_01a_D1.png

 

图 4。配置为 SINGLE_SHOT 时的锯齿波形输出。 数据点数 256 个,玩过一次。 数据结束后,输出被设置为某个预定义值(这里是 127)。

AudioPCM_DMA2_01a_D2.png

 

 

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

干得好,现在可以播放流畅的声音。

谢谢。

0 点赞