找回密码
 立即注册
查看: 238|回复: 7

AICUBE中音频采样率的计算是否有误,是手册公式错误?

[复制链接]

9

主题

28

回帖

183

积分

注册会员

积分
183
发表于 2026-9-8 11:14:34 | 显示全部楼层 |阅读模式
使用AICUBE设置I2S如下图
I2S设置.png

时钟设置如下图
时钟设置.png
此时I2S主时钟为8Mhz,按照手册计算
音频采样率FS=I2S时钟/[(16*2)*(2*DIV+ODD)*8]=40000000/[32*80*8]=40000000/20480=1953.125HZ=1.95KHZ
计算出来的采样率与AICUBE的不一致。
如果按照当 I2S 主时钟输出被禁用时
音频采样率FS=I2S时钟/[(16*2)*(2*DIV+ODD)]=40000000/[32*80]=40000000/2560=15625HZ=15.625Khz


不管怎样都得不出AICUBE计算出来的数值,是我哪里计算错了吗?
回复

使用道具 举报 送花

28

主题

1327

回帖

5046

积分

超级版主

积分
5046
发表于 2026-9-8 11:42:28 | 显示全部楼层
I2S时钟分频是(2*DIV+ODD)的值,不是DIV的值
DIV和ODD组合成一个9bit的分频器,ODD为bit0,DIV是bit8~bit1

音频采样率FS=I2S时钟/[(16*2)*(2*DIV+ODD)*8]=40000000/[32*40*8]=40000000/10240=3906.25HZ=3.91KHZ
回复

使用道具 举报 送花

9

主题

28

回帖

183

积分

注册会员

积分
183
 楼主| 发表于 2026-9-8 12:41:20 | 显示全部楼层
我的代码中,需要设置采样率为3.91K才可以正常
I2S配置2.png

这是我的代码,我找不出问题所在了
TLVAIC23B.rar (89.98 KB, 下载次数: 100)
到底问题出在哪里?
回复

使用道具 举报 送花

9

主题

28

回帖

183

积分

注册会员

积分
183
 楼主| 发表于 2026-9-8 12:41:44 | 显示全部楼层
zh*** 发表于 2026-9-8 11:42
I2S时钟分频是(2*DIV+ODD)的值,不是DIV的值
DIV和ODD组合成一个9bit的分频器,ODD为bit0,DIV是bit8~bit1
...

非常感谢,麻烦您再看看我的代码问题出在哪里,我的TLV320是设置的32K采样率,单片机要送3.9K才可以
回复

使用道具 举报 送花

9

主题

28

回帖

183

积分

注册会员

积分
183
 楼主| 发表于 2026-9-8 14:20:12 | 显示全部楼层
这是我问stcai的回答,我更搞不懂了
核心问题回答
是的,您的理解是正确的。 单片机并不需要按31250Hz送数据,而是按 I2S接口自身的采样率(3906.25Hz) 送数据,但 AIC23芯片实际采样的速率是由它接收到的MCLK(主时钟)频率决定的。

让我深入解释这个原理:

一、I2S主机模式下的信号链路
AI8051U作为 I2S主机,对外输出三路关键信号:
截图202609081425543371.jpg

二、单片机的LRCK(帧同步)频率由什么决定?
根据手册中 I2S分频寄存器 的定义,在 MCKOE=1(主时钟输出使能)、16bit、信道帧宽度16位时:
截图202609081422301497.jpg
代入您的配置(I2S时钟=40MHz,DIV=20,ODD=0,实际分频值=40):
截图202609081423085447.jpg
这就是 单片机I2S模块产生LRCK帧同步信号的频率,即单片机每次发送一帧(左声道+右声道数据)的速率是 3906.25Hz。

三、为什么单片机和AIC23采样率不同也能工作?
这就是关键所在。I2S协议中,从机DAC芯片的采样率并不是由LRCK单独决定的,而是由芯片内部的时钟配置决定的。

在AIC23芯片中:

MCLK输入 → 8MHz
AIC23配置为 Normal mode,BOSR=0(256fs) → 芯片内部采样率 = MCLK/256 = 31250Hz
但 AIC23需要从LRCK(帧同步)信号获取具体的采样时机。

四、实际会发生什么?
这里存在一个 匹配问题:

单片机 按 3906.25Hz 的频率更新LRCK,每次帧同步时发送一组左/右声道数据
AIC23 内部按 31250Hz 的采样率工作,但它需要等待LRCK信号来触发每个声道的数据锁存
两者不匹配时会怎样?

实际上,您的代码中正弦波的输出频率计算是基于 AIC23的实际采样率(31250Hz) 来计算的,而不是单片机的LRCK频率(3906.25Hz)。

让我回顾一下之前的分析:
截图202609081428086467.jpg

这个计算假设了采样率是31250Hz。但实际上,如果单片机LRCK只有3906.25Hz,那么:

单片机每3906.25Hz发送一帧数据(左声道+右声道各16bit)
AIC23在每次LRCK到来时锁存数据
正弦波的更新速率实际上是 3906.25Hz,而不是31250Hz
那么输出频率应该是:
截图202609081428392500.jpg
这显然不是1kHz!

五、重新审视问题
这说明,前面的分析中有一个关键矛盾:

如果单片机LRCK确实为3906.25Hz,那么输出正弦波频率应该是122Hz,而不是1kHz
但因为用户实际测量/听到了接近1kHz的正弦波,说明 实际采样率并非3906.25Hz
可能的原因有两种:

可能性1:AIC23的实际采样率由MCLK决定,但与LRCK无关?
在这种情况下,AIC23以31250Hz的速率自行采样(不依赖LRCK),单片机以3906.25Hz速率送数据。但这样会导致数据送入速率跟不上AIC23的采样速率,会产生数据丢失或重复采样,输出波形会变得不规则。

可能性2:实际LRCK频率可能是31250Hz,而非3906.25Hz
让我重新检查一下 I2S_SetClockDivider(40) 的实际作用。

根据手册,I2S_SetClockDivider(n) 宏定义为:

#define I2S_SetClockDivider(n)  MODIFY_REG(I2SPRH, I2SPRH_ODD_MSK, ((n) << 0)); \
                                I2SPRL = ((n) >> 1)
📋
当 n=40:
ODD = 40 & 0x01 = 0
DIV = 40 >> 1 = 20
实际分频值 = 2×DIV + ODD = 40
MCKOE=1,16bit时采样率:
截图202609081429143789.jpg

但等一下——手册中还有一个重要的公式条件。让我仔细再看手册中的说明:
手册提到"上述I2S时钟为系统时钟或PLL时钟"。而您的代码中 I2S工作时钟 = 40MHz。这个没问题。
然而,I2S主时钟MCLK输出(8MHz)不只是给AIC23提供时钟,它在I2S内部也是 LRCK同步信号的来源。
让我重新审视。在MCKOE=1时,采样率的公式中包含了 ×8 这个因子。这个 ×8 表示的是 主时钟MCLK与LRCK之间的关系,即 MCLK = 8 × 16bit × 2ch × FS = 256×FS(这是I2S标准的256fs关系)。
也就是说,当MCKOE=1时,I2S模块内部用 MCLK(8MHz) 来生成LRCK,LRCK频率 = MCLK/256 = 31250Hz。
但手册的公式给出的是3906.25Hz,这中间存在矛盾!
六、结论
根据手册的公式,I2S_SetClockDivider(40) 在MCKOE=1时得到的LRCK(采样率)= 3906.25Hz。但 AIC23的MCLK=8MHz时,芯片内部采样率 = 31250Hz。
两者之间确实存在不匹配。
但用户实际听到/测量到约1kHz的正弦波,这个事实说明:
AIC23实际采样率由MCLK决定(31250Hz),AIC23以自己内部设定的采样率工作,不依赖LRCK频率来采样
单片机按LRCK(3906.25Hz)送数据,AIC23在其内部采样时刻捕获单片机送来的数据
由于 LRCK(3906.25Hz) 远低于 AIC23采样率(31250Hz),AIC23会在两次LRCK之间以31250Hz持续采样,但在LRCK到来时才锁存新数据
这种情况下,用户听到的正弦波频率实际取决于 单片机的LRCK(数据更新速率) 而不是AIC23的内部采样率。
截图202609081430163580.jpg
这与"接近1kHz"不符!
七、最终结论
我的回答是: 手册中明确给出的公式是可信的。在我的分析中关于AIC23的部分可能存在推断错误。
让我澄清:手册明确说明采样率FS是由I2S分频寄存器决定的:
截图202609081431037216.jpg
在这个采样率下,使用步进2048的DDS方法,输出频率是:
截图202609081431217605.jpg

如果用户实际测量到接近1kHz,那说明用户的配置或代码中还有其他因素在起作用。 需要进一步确认用户的完整配置。
截图202609081421038168.jpg
回复

使用道具 举报 送花

9

主题

28

回帖

183

积分

注册会员

积分
183
 楼主| 发表于 2026-9-9 09:12:20 | 显示全部楼层
采样率的计算确实存在问题,如果按照下图设置,I2S音频采样率应该为4K,实际硬件测试为32K。

截图202609090908139835.jpg
用示波器测试,左右声道时钟为32Khz,表明采样率为32K而不是4K。


AI8051试验箱第81号例程,采样率为32K,代码如下:




#define FOSC                        40960000UL                //定义主时钟
#define SampleRate                32000                        //定义采样率


#define I2S_MCLKDIV        (FOSC/(8*16*2*SampleRate))        //MCLK分频系数, 对于双声道16bit.
#define I2S_BCLKDIV                (FOSC/(16*2*SampleRate))                //BCLK分频系数, 对于双声道16bit.

void        I2S_config(void)
{
        I2SMD = 0xff;                                        //内部保留字节,需设置为FFH
        I2SSR = 0x00;                                        //状态寄存器清0
        I2SCR = 0x80+0x00;                                //使能发送缓冲区空中断(0x80), +0x00:Motorola格式, +0x10:TI格式
        HSCLKDIV    = 1;                                //高速时钟分频器 1~255 (默认2)
        I2S_CLKDIV = 1;                                        //I2S主时钟分频
        I2SMCKDIV  = I2S_MCLKDIV;                                        //I2S时钟分频,I2SMCLK = 主频/2/I2S_CLKDIV/HSCLKDIV/I2SMCKDIV,  或I2SMCLK = PLLCLK/2/I2S_CLKDIV/HSCLKDIV/I2SMCKDIV
       
        I2SPRH = (MCKOE << 1) + (I2S_BCLKDIV & 1);        //设置I2S_BMCLK分频系数的bit0, 并允许或禁止输出MCLK。
        I2SPRL = I2S_BCLKDIV/2;                                                //设置I2S_BMCLK分频系数的bit8~bit1
       
       
        I2SCFGH = I2S_MODE;                                //设置I2S模式为主机发送模式
        I2SCFGL = (PCMSYNC << 7) + (STD_MODE << 4) + (CKPOL << 3) + (DATLEN << 1) + CHLEN;
        P_SW3 = (P_SW3 & 0x3f) | (1<<6);        //I2S端口切换, 0: P3.2(BCLK) P3.3(MCLK) P3.4(SD) P3.5(WS),        2024-7-21
                                                                                //             1: P1.7(BCLK) P1.6(MCLK) P1.5(SD) P1.4(WS),
                                                                                //             2: P2.3(BCLK) P2.2(MCLK) P2.1(SD) P2.0(WS),
                                                                                //             3: P4.3(BCLK) P1.6(MCLK) P4.1(SD) P4.0(WS),
        I2SCFGH |= I2SEN;                //使能I2S模块
}


经过计算 I2S_BCLKDIV= 40960000/(16*2*32000)=40
如果按照手册
截图202609091000133959.jpg
采样率=40960000/[16*2*40*8]=4Khz
试验箱81号例程实际是正确的,倒推手册中的公式就是错误的!

点评

AI8051U的I2S的MCLK与BCLK是独立设置的,相互无关,但是I2S接口这两信号是相关的。 我常用16位数据,则跟时钟设置相关的指令为: #define MCKOE 1 /  详情 回复 发表于 2026-9-9 23:00
回复

使用道具 举报 送花

83

主题

8317

回帖

1万

积分

超级版主

积分
17932
发表于 2026-9-9 23:00:52 | 显示全部楼层
指*** 发表于 2026-9-9 09:12
采样率的计算确实存在问题,如果按照下图设置,I2S音频采样率应该为4K,实际硬件测试为32K。
AI8051U的I2S的MCLK与BCLK是独立设置的,相互无关,但是I2S接口这两信号是相关的。是否允许输出MCLK和输出频率不影响BCLK。
我常用16位数据,则跟时钟设置相关的指令为:

#define    MCKOE                      1                                     //I2S主时钟输出控制, 0:禁止I2S主时钟输出, 1:允许I2S主时钟输出
#define    I2S_MCLKDIV      (FOSC/(8*16*2*SampleRate))   //MCLK分频系数, 对于双声道16bit.
#define    I2S_BCLKDIV      (FOSC/(16*2*SampleRate))       //BCLK分频系数, 对于双声道16bit. BCLK是独立设置的,是否允许输出MCLK和输出频率不影响BCLK。



HSCLKDIV   = 1;              //HSCLKDIV主时钟分频
I2S_CLKDIV = 1;             //I2S主时钟分频
I2SMCKDIV  = I2S_MCLKDIV;                 //I2S_MCLK时钟分频,I2SMCLK = 主频/I2S_CLKDIV/HSCLKDIV/I2SMCKDIV,  或I2SMCLK = PLLCLK/I2S_CLKDIV/HSCLKDIV/I2SMCKDIV
I2SPRH = (MCKOE << 1) + (I2S_BCLKDIV & 1);  //设置I2S_BCLK分频系数的bit0, 并允许或禁止输出MCLK。
I2SPRL = I2S_BCLKDIV/2;            //设置I2S_BCLK分频系数的bit8~bit1



我的初始化:

截图202609092254083178.jpg
回复

使用道具 举报 送花

9

主题

28

回帖

183

积分

注册会员

积分
183
 楼主| 发表于 2026-9-10 08:28:18 | 显示全部楼层
梁*** 发表于 2026-9-9 23:00
AI8051U的I2S的MCLK与BCLK是独立设置的,相互无关,但是I2S接口这两信号是相关的。是否允许输出MCLK和输出 ...

您的代码实际测试效果很好,谢谢
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-11-7 12:23 , Processed in 0.078357 second(s), 82 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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