关于stm32的传输24bit音频数据时I2S与DMA配置的一个问题

2019-12-20 21:40发布

在reference manual里有一段描述stm32所支持的音频协议,如下:
-------
支持的音频协议:
三线总线支持2 个声道上音频数据的时分复用:左声道和右声道,但是只有一个16位寄存器用作
发送或接收。因此,软件必须在对数据寄存器写入数据时,根据当前传输中的声道写入相应的
数据;同样,在读取寄存器数据时,通过检查寄存器SPI_SR的CHSIDE 位来判明接收到的数据
属于哪个声道。左声道总是先于右声道发送数据(CHSIDE位在PCM协议下无意义)。
有四种可用的数据和包帧组合。可以通过以下四种数据格式发送数据:  
● 16位数据打包进16位帧
● 16位数据打包进32位帧
● 24位数据打包进32位帧
● 32位数据打包进32位帧
在使用16位数据扩展到32位帧时,前16位(MSB) 是有意义的数据,后16位(LSB) 被强制为0 ,该
操作不需要软件干预,也不需要有DMA请求(仅需要一次读/ 写操作)。
24位和32位数据帧需要CPU对寄存器SPI_DR进行2 次读或写操作,在使用DMA时,需要2 次
DMA传输
对于24位数据,扩展到32位后,最低8位由硬件置0。
------
首先我想问个问题,对于24bit的双声道格式的声音文件, 其存储格式是否是如下所示:
format.JPG (5.3 KB, 下载次数: 0) 下载附件 2012-8-27 15:56 上传
如果是的话, 那么在I2S的传输采用DMA方式时,I2S只有16位的宽度, 而24位的数据被打包成32位的数据(低8位由硬件置0)来传,
那么此时该如何进行I2S与DMA的设置呢?
1: I2S_DataFormat = ? bit;
2: DMA_PeripheralDataSize = ? bit;
3: DMA_MemoryDataSize = ? bit;

我从WAV文件中读出的数据是存储在unsigned char的数组中, 每个声道的数据由3个字节组成.
我测试时设置:
1: I2S_DataFormat = 24bit;
2: DMA_PeripheralDataSize = 16bit;
3: DMA_MemoryDataSize = 16bit;
按照如上设置, 播放出来时噪声很大, 虽然也能听到歌声,但一定不是正确的做法.
并且启动DMA传输时, 我只是简单地设置了数据缓冲区的起始地址与长度(这个数据是32bit的数据,其中我做了处理:每三个字节后第四个字节用0填充)
/* Configure the buffer address and size */
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Addr;
  DMA_InitStructure.DMA_BufferSize = (uint32_t)(Size);

另外, 不知道两次DMA传输体现在哪里?  直接16比特16比特地传不行么?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
13条回答
rabbitgg
1楼-- · 2019-12-20 22:16
24bit需要手动补齐成32bit。原来24bit,看成3位char类型高到低位分别是 0x33 0x22 0x11,转换成32bit,看成4个char,高到低位应该是 0x33 0x22 0x11 0x00。
我试过,如果是f1xx系列,24bit大概只能上到48khz左右,再高就断流了,16bit不需要转换,可以上到96khz。
yuzhangyuan
2楼-- · 2019-12-21 02:02
我已经进行过补齐的,现在的现象是只有单声道有声音,而且还夹有噪声。 我用的是stm32F207的片子。
carryonli
3楼-- · 2019-12-21 06:52
望楼主把这部分代码发上来分析。
yuzhangyuan
4楼-- · 2019-12-21 11:29
 精彩回答 2  元偷偷看……
carryonli
5楼-- · 2019-12-21 16:12
FIFO禁止一下试试,
yuzhangyuan
6楼-- · 2019-12-21 22:10
carryonli 发表于 2012-8-30 03:28
FIFO禁止一下试试,

哪个FIFO呢,,  如何操作?

一周热门 更多>