硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5884|回复: 6
收起左侧

[有问必答] I2S & uart 同步(已解决)

[复制链接]

14

主题

109

回帖

151

积分

初级会员

积分
151
发表于 2016-1-25 16:29:30 | 显示全部楼层 |阅读模式
想请教下,我有一串音频数据从 uart 接收
经过 I2S 送到 WM8978。
有没有一个比较好的方式来确认两者能够同步?

uart 是 921600
I2S 是 8K

我一开始是慢慢试..
但随着程序变更的次数越来越多
时常会影响到原本调配好的速度
发出怪声 0001.rar (175 KB, 下载次数: 123) ,
想跟大家讨个思路
回复

使用道具 举报

14

主题

109

回帖

151

积分

初级会员

积分
151
 楼主| 发表于 2016-1-25 18:00:16 | 显示全部楼层
不想费神了,
顺便写下我的作法,
基本上先确认I2S频率,
及自己的uart打包的速率.
抓好自己打包的间隔.


程序的架构大概是,
收进来数据,先别开I2S
收几个包顺便处理一下,(我的速度差几个包的时间不碍事,顺便当缓冲时间..)
用timer去抓包丢进I2S存数据的buffer(g_tRec.pAudio[g_tRec.uiCursor++])
像这样..跟得上就行..
  1. void I2S_CODEC_DataTransfer(void)
  2. {
  3.     static uint16_t usData;
  4.     /*只录左声道(安富莱STM32开发板MIC安装在左声道), 放音时左右声道相同*/
  5.     if (g_tRec.ucStatus == STA_RECORDING) /*录音状态*/
  6.     {
  7.         if (I2S2ext->SR & SPI_I2S_FLAG_RXNE)
  8.         {
  9.             usData = I2S2ext->DR;
  10.             if (SPI2->SR & I2S_FLAG_CHSIDE != SET)
  11.             {
  12.                 g_tRec.pAudio[g_tRec.uiCursor++] = usData;
  13.             }
  14.         }
  15.         if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE) == SET)
  16.         {
  17.             SPI2->SR = 0;
  18.         }
  19.     }
  20.     else if (g_tRec.ucStatus == STA_PLAYING) /*放音状态,右声道的值等于左声道*/
  21.     {
  22.         if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE) == SET)
  23.         {
  24.             if (SPI2->SR & I2S_FLAG_CHSIDE != SET) /*判断是不是左声道*/
  25.             {
  26.                 usData = g_tRec.pAudio[g_tRec.uiCursor++];
  27.             }
  28.             I2S2ext->DR = usData;
  29.         }
  30.     }
  31.     else  /*临时状态 STA_STOP_I2S,用于停止中断*/
  32.     {
  33.         /*禁止I2S2 RXNE中断(接收不空),需要时再打开*/
  34.         SPI_I2S_ITConfig(I2S2ext, SPI_I2S_IT_RXNE, DISABLE);
  35.         /*禁止I2S2 TXE中断(发送缓冲区空),需要时再打开*/
  36.         SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
  37.     }
  38. }
复制代码


当然,这样做是会有问题的
时间长了, 一定有个会被咬上
只是以我目前的需求是暂时够用了..
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2016-1-25 18:19:18 | 显示全部楼层
这个做同步的确得需要花些心思了,I2S不能等,只能在USART部分下工夫了,做个FIFO,缓冲下。

另外如果可以做自定义音频个格式也是可以的,设置音频的播放率跟串口速度一样。不过串口的速度的确是有些高,I2S也得设置的高些。
回复

使用道具 举报

14

主题

109

回帖

151

积分

初级会员

积分
151
 楼主| 发表于 2016-1-26 14:55:26 | 显示全部楼层
谢谢硬汉兄回覆
在此附上硬汉兄所说的音频速率设置图(详见RM0090)
123.png


因为 uart 收到的音频数据采样率是固定的(8K无法变更)

因此 I2S 只能使用 8K, 而 32bit 实在是不太方便(要压缩)

因为需求的关系,所以需要足够高的 uart 支持
基本上至少也是 460800 跑不掉
所以,就如同硬汉兄所说的
目前我只能做到的就是尽可能的确保足够的缓冲

而从 I2S 到 UART 就容易多了,
总之有多少就丢多少
回复

使用道具 举报

116

主题

800

回帖

1148

积分

至尊会员

积分
1148
QQ
发表于 2016-1-26 16:16:42 | 显示全部楼层
把DMA用起来,可以节省CPU时间的
回复

使用道具 举报

14

主题

109

回帖

151

积分

初级会员

积分
151
 楼主| 发表于 2016-1-26 17:36:11 | 显示全部楼层
谢谢 jcx0324 兄弟的回覆

目前I2S已经用上了DMA
确实能在一定程度上拉近彼此速率
谢谢 jcx0324 兄弟的建议

假设我的程序没问题的话
但 DMA 在原理上还是受限於基层的 GPIO 设置
我想两边抓包跟丢包的速率差实在是太大
真是让我很头疼
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2016-12-1 21:46:34 | 显示全部楼层
i2s+dma 代码能否share一下?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-16 15:08 , Processed in 0.045510 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表