妖怪罗小黑OL 发表于 2025-10-8 11:23:29

I2S开发困难重重



用的STC32G8K64,从这个规格书上可以看到,I2S的位时钟主要和 I2SPRL这个寄存器有关,I2SPRH 固定写 3
I2SPRL设置的是音频主时钟,也叫同步时钟,而I2S的比特率也称位时钟=16*2*FS。


在这个图里,我FOSC设置12M,I2SDIV=FOSC/(16*2*8*SampleRate)=12M/(16*2*8*4500)=10
同步时钟FS=I2S时钟/(16*2*(2*DIV+ODD)*8))=12M/(16*2*(2*10+1)*8)=2.2Khz.
位时钟=16*2*FS=70.4Khz
以下为代码实际运行的效果。为什么对不上的。







国芯人工智能 发表于 2025-10-8 11:30:00

您好,关于您在使用 STC32G8K64 进行 I2S 接口开发过程中遇到的问题,我们从以下几个方面进行分析与排查:

一、I2S时钟配置逻辑分析

根据您提供的信息,您使用的是 I2S主模式,FOSC为12MHz,I2SDIV设为10,I2SPRL=10,I2SPRH=3。根据规格书中的公式:

1. 同步帧时钟(FS)计算公式:
$$
FS = \frac{F{I2SCLK}}{162 \times (2 \times I2SPRL + I2SPRH) \times 8}
$$

其中:
$ F{I2SCLK} $:I2S主时钟源频率(由I2SDIV分频后得到)
I2SPRL:主时钟分频低位
I2SPRH:主时钟分频高位(固定为3)
162:固定系数,用于生成位时钟

2. I2S主时钟计算公式:
$$
F{I2SCLK} = \frac{F{OSC}}{16 \times (2 \times I2SDIV + ODD)}
$$

其中:
$ F{OSC} = 12MHz $
I2SDIV = 10
ODD = 1(根据您代码中的设置)

代入得:
$$
F{I2SCLK} = \frac{12M}{16 \times (2 \times 10 + 1)} = \frac{12M}{16 \times 21} = 35.714kHz
$$

再代入FS计算:
$$
FS = \frac{35.714kHz}{162 \times (2 \times 10 + 3) \times 8} = \frac{35.714}{162 \times 23 \times 8} = \frac{35714}{29808} \approx 1.198Hz
$$

这个结果显然与预期不符,说明配置逻辑存在偏差。

二、配置逻辑错误分析

1. I2SDIV的设置依据

您提供的公式为:
$$
I2SDIV = \frac{F{OSC}}{16 \times 2 \times SampleRate} = \frac{12M}{16 \times 2 \times 4500} = 83.33
$$

但实际您设置为10,这会导致I2S主时钟远低于预期,从而影响帧率和位时钟。

2. 位时钟(Bit Clock)计算错误

您提到位时钟应为 16 × 2 × FS = 162 FS,但实际上:
16 × 2 是指16位立体声(每声道16位,立体声即32位),而 I2S 标准下,每个帧包含两个声道,每个声道16位,即共32位。
所以正确的位时钟应为 32 × FS

因此:
$$
BitClock = 32 \times FS
$$

而您使用的162是错误的,可能是将系数混淆了。

三、建议的配置修正

1. 目标参数设定
FOSC = 12MHz
音频采样率 Fs = 4500Hz
位时钟 = 32 × Fs = 144,000Hz

2. I2SDIV的计算

$$
I2SDIV = \frac{F{OSC}}{16 \times BitClock} = \frac{12M}{16 \times 144000} = \frac{12000000}{2304000} ≈ 5.2
$$

取整数部分为5,ODD=0 或 1(可微调)

3. I2SPRL 和 I2SPRH 的设置

由于 I2SPRH 固定为3,所以:
$$
FS = \frac{F{I2SCLK}}{162 \times (2 \times I2SPRL + 3) \times 8}
$$

代入:
$$
F{I2SCLK} = \frac{12M}{16 \times (2 \times 5 + 0)} = \frac{12M}{16 \times 10} = 75kHz
$$

$$
FS = \frac{75000}{162 \times (2 \times I2SPRL + 3) \times 8}
$$

令 FS = 4500Hz:
$$
4500 = \frac{75000}{162 \times (2 \times I2SPRL + 3) \times 8}
\Rightarrow (2 \times I2SPRL + 3) = \frac{75000}{4500 \times 162 \times 8} ≈ 0.0128
$$

这显然不合理,说明系统时钟与I2S配置之间存在不匹配,可能需要提高FOSC或降低采样率。

四、建议解决方案

方案一:提高系统主频
将 FOSC 提高至 24MHz 或更高,以获得更高的 I2S 主时钟
重新计算 I2SDIV、I2SPRL 等寄存器值

方案二:使用外部时钟源
若芯片支持外部时钟输入,可接入高精度音频时钟(如12.288MHz),用于I2S模块
可极大提升音频同步精度

方案三:使用PLL倍频
若芯片支持 PLL 倍频功能,可将系统时钟倍频后再用于I2S
提高时钟精度与稳定性

五、调试建议

1. 使用示波器测量I2S各信号线(BCLK、WS、SD):
确认BCLK频率是否符合预期
WS是否与BCLK同步,且频率为4500Hz
数据线SD是否输出正确音频数据

2. 检查寄存器配置是否正确写入:
使用调试器或串口打印寄存器值,确认配置无误

3. 使用I2S标准音频设备验证输出:
接入DAC或音频解码芯片(如TI PCM5102、WM8731等)
观察是否能输出正常音频

六、总结

您当前的配置中存在以下问题:
I2SDIV设置过小,导致I2S主时钟偏低
位时钟计算错误,误将162作为固定系数
I2SPRL计算逻辑错误,导致帧率不匹配
未考虑主频与音频采样率之间的匹配关系

建议:
重新计算I2SDIV、I2SPRL等寄存器
提高主频或使用外部时钟
使用示波器辅助调试

如需进一步协助,欢迎提供完整代码或配置流程,我们可协助逐行分析。

祝开发顺利!

国芯人工智能团队
2025年4月5日

[本文内容由国芯人工智能辅助生成,仅供参考]

妖怪罗小黑OL 发表于 2025-10-8 11:42:37


可以确定是16位的位宽

妖怪罗小黑OL 发表于 2025-10-8 11:46:53

而且不管我如何修改SampleRate的数值或者FOSC的值,都不会导致这个波形发生变化。就很奇怪,时钟用的外部12M振荡器,已经确认晶振是工作的

神农鼎 发表于 2025-10-8 14:01:09



https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=19972&pid=186080

妖怪罗小黑OL 发表于 2025-10-8 15:27:11

神农鼎 发表于 2025-10-8 14:01
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=19972&pid=186080
但是我用的是位宽16,采样21Khz,那MCLK=128*0.021=2.688Mhz
选择晶振12MHZ,四分频,按理说也可以做到差不多的吧。

ercircle 发表于 2025-10-8 16:22:26

妖怪罗小黑OL 发表于 2025-10-8 11:46
而且不管我如何修改SampleRate的数值或者FOSC的值,都不会导致这个波形发生变化。就很奇怪,时钟用的外部12 ...启用了外部晶振,主时钟源没选对


ercircle 发表于 2025-10-8 16:31:15

貌似是个AiCube自动生成BUG,同时启用外部晶振和PLL:

1.多了个选择内部HIRC时钟源,和外部晶振冲突
CLK_MCLK_XTAL
CLK_MCLK_HIRC
2.旁路MCLK2和PLL配置冲突
CLK_MCLK2_BYPASS

CLK_PLL_Output144MHz();
CLK_PLL_PreDivider2();



推荐先在已调通的I2S程序上修改试试:
Ai8051U实现USB全双工声卡,同时 录音/ 放 音,微信通话/腾讯会议 可用, 重磅开源 - 51 发烧友,UAC,极致音频,大国工匠,艺术人生,乐林漫步 国芯人工智能技术交流网站 - AI32位8051交流社区
一个音视频播放例程【USART-SPI==>DMA-P2P==>SPI, +I2S】@AI8051U - TFT彩屏,触摸屏,DMA-i8080/M6800并口自动刷屏,DMA-SPI刷屏,外设直接到外设 国芯人工智能技术交流网站 - AI32位8051交流社区
页: [1]
查看完整版本: I2S开发困难重重