admin管理员组

文章数量:1530281

理论篇

简介

I2S(Inter IC Sound)总线, 又称集成电路内置音频总线,是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准,该总线专责于音频设备之间的数据传输,广泛应用于各种多媒体系统。它采用了沿独立的导线传输时钟数据信号的设计,通过将数据和时钟信号
分离,避免了因时差诱发的失真,为用户节省了购买抵抗音频抖动的专业设备的费用。

iis引脚和作用有关

I2S总线接口有3个主要信号,但只能实现数据半双工传输,后来为实现全双工传输有些设备增加了扩展数据引脚。STM32f42x系列控制器支持扩展的I2S总线接口。
(1) SD(Serial Data):串行数据线,用于发送或接收两个时分复用的数据通道上的数据(仅半双工模式),如果是全双工模式,该信号仅用于发送数据。
(2) WS(Word Select):字段选择线,也称帧时钟(LRC)线,表明当前传输数据的声道,不同标准有不同的定义。WS线的频率等于采样频率(FS)。
(3) CK(Serial Clock):串行时钟线,也称位时钟(BCLK),数字音频的每一位数据都对应有一个CK脉冲,它的频率为:2采样频率量化位数,2代表左右两个通道数据。
(4) ext_SD(extend Serial Data):扩展串行数据线,用于全双工传输的数据接收。
(5) 有时为使系统间更好地同步,还要传输一个主时钟(MCK),主时钟常用语当stm32作为主设备时,为其他从设备提供主时钟

与时序频率有关:

MCK:主时钟输出,一般是采样率的 256 倍或 384 倍
LRC:采样频率Fs,低电平表示左声道,高电平表示右声道

BCLK:位时钟,音频数据的每一位数据都对应一个 SCK,立体声都是双声道的,因此 BLCK=2×采样率Fs×采样位数。比如采样率Fs为 44.1KHz、16 位的立体声音频,那么 BLCK=2×44100×16=1411200Hz=1.4112MHz。

SD:串行数据信号,收/发
ext_SD():扩展串行数据线,用于全双工传输的数据接收。

I2S Philips 标准

使用LRCLK信号来指示当前正在发送的数据所属的声道,为0时表示左声道数据。LRCLK信号从当前声道数据的第一个位(MSB)之前的一个时钟开始有效。LRCLK信号在BCLK的下降沿变化。发送方在时钟信号BCLK的下降沿改变数据,接收方在时钟信号BCLK的上升沿读取数据。正如上文所说,LRCLK频率等于采样频率Fs,一个LRCLK周期(1/Fs)包括发送左声道和右声道数据。

对于这种标准I2S格式的信号,无论有多少位有效数据,数据的最高位总是出现在LRCLK变化(也就是一帧开始)后的第2个BCLK脉冲处。这就使得接收端与发送端的有效位数可以不同。如果接收端能处理的有效位数少于发送端,可以放弃数据帧中多余的低位数据;如果接收端能处理的有效位数多于发送端,可以自行补足剩余的位。这种同步机制使得数字音频设备的互连更加方便,而且不会造成数据错位。
I2S Philips 标准时序图如下所示:

iis和dma传输有关

为满足iis传输数据时的高效性和主从设备的实时性,单片机使用iis收发数据时,常使用dma传输数据(寄存器到外设,外设到寄存器),dma不在这里过多赘述,以下时dma1和dma2与外设的映射关系:



dma控制器和AHB总线矩阵,外设的关系图:

DMA框图 STM32有2个DMA控制器,但是DMA2有点特殊,只能存储器到存储器

/---------------------------------------------下述无意义-----------------------------------------/
假设使用的外部晶振(HSE)频率为8MHz,系统时钟源被配置为主PLL(Phase-Locked Loop)。通过对主PLL的配置,可以生成所需的系统时钟频率。在STM32F407中,通过配置PLL的倍频和分频因子,可以生成较高频率的系统时钟。
在SystemClock_Config函数中,主PLL的配置如下:

RCC_PLLConfig(RCC_PLLSource_HSE, 8, 336, 2, 7);

这里的参数意义如下:

RCC_PLLSource_HSE:使用外部高速时钟(HSE)作为PLL的输入源。
8:PLLM,输入时钟分频因子。
336:PLLN,主PLL的倍频因子。
2:PLLP,主PLL的输出分频因子,用于生成系统时钟(SYSCLK)。
7:PLLQ,用于生成USB、SDIO、随机数发生器等外设的时钟。
/---------------------------------------------上述无意义-----------------------------------------/

iis时钟配置有关

也就是说,设置好了iis的时钟源I2SxCLK,采样频率I2S_AudioFreq , 就等于设置好了主时钟(MCLK),位时钟(BCLK),帧同步时钟(WS)
ChatGPT:是的,在STM32F407中,通过正确配置I2S的时钟源和采样频率(I2S_AudioFreq),你就等于间接设置好了I2S的主时钟(MCLK)、位时钟(BCLK)和帧同步时钟(WS)。
总结:
主时钟(MCLK):通常是采样频率的256倍或384倍,具体取决于音频编解码器的要求。
位时钟(BCLK):由I2S模块根据采样频率和数据格式自动生成,频率为采样频率乘以每个采样的位数和通道数。
帧同步时钟(WS):其频率等于采样频率,用于指示每个音频帧的开始。在iis初始化函数中由用户编写。
如何设置iis时钟源呢?
外部晶振或内部晶振在经过主PLL(Phase-Locked Loop)配置后,通过配置PLL的倍频和分频因子,将主PLL配置成功,可根据需要选择是否需要将配置成功的PLL设置为系统时钟,再配置 PLLI2S(Phase-Locked Loop for Inter-IC Sound),它是一个专门用于生成 I2S 外设时钟的 PLL,调整 PLLI2S 的倍频和分频因子,可以得到适合音频采样率的时钟源。
配置步骤:

时钟计算

其中:
f HSE 是外部高速时钟(晶振)频率。
PLLM 是主 PLL 配置中的输入分频因子。
PLLI2SN 是倍频因子。
PLLI2SR 是分频因子。
此时输出的时钟即I2SxCLK时钟
简化说:

I2SxCLK=(HSE/PLLM)*PLLI2SN/PLLI2SR

HSE 我们是 8Mhz,而 PLLM 在系统时钟初始化就确定了,是 8。

iis时钟发生器内部是什么结构呢,我们看这张图:

I2SxCLK是该图的输入时钟;
音频的采样频率可以是96kHz、48kHz、44.1kHz、32kHz、22.05kHz、16kHz、11.025kHz或者8kHz(或任何此范围内的数值)。
为了获得需要的输出频率,需按照以下公式设置线性分频器,要输出mck和lck还要经过下面的步骤:
1.设置I2SDIV分频因子。 I2SDIV在SPI2->I2SPR的第[7:0]位设置。
2.设置ODD(奇数分频)(0/1) ODD 由寄存器第8位设置。
3.使能MCKOE位,输出主时钟(MCLK) MCKOE 由寄存器第8位设置

I2SPR寄存器描述如下:

主时钟使能/禁止输出情况下,采样频率计算公式:

输出主时钟(SPI_I2SPR 寄存器中的 MCKOE 置 1)时:
FS = I2SxCLK / [(16*2)*((2*I2SDIV)+ODD)*8)](通道帧宽度为 16 位时)
FS = I2SxCLK / [(32*2)*((2*I2SDIV)+ODD)*4)](通道帧宽度为 32 位时)
关闭主时钟输出(MCKOE 位清零)时:
FS = I2SxCLK / [(16*2)*((2*I2SDIV)+ODD))](通道帧宽度为 16 位时)
FS = I2SxCLK / [(32*2)*((2*I2SDIV)+ODD))](通道帧宽度为 32 位时)

综上所述,在主时钟输出的情况下,可得下式:

fs= (1000PLLI2SN/PLLI2SR )/[256(2*I2SDIV+ODD)]
其中:
fs 单位是: Khz
PLL2SN 取值范围:192~432;
PLLI2SR 取值范围:2~7;
I2SDIV 取值范围:2~255;
ODD 取值范围:0/1

根据以上约束条件,我们便可以根据 fs 来设置各个系数的值了,不过很多时候,并不能取得和 fs 一模一样的频率,只能近似等于 fs,比如 44.1Khz采样率,我们设置 PLL2SN=271,PLL2SR=2,I2SDIV=6,ODD=0,得到 fs=44.108073Khz,误差为:0.0183%。晶振频率决定了有时无法通过分频得到我们所要的 fs,所以,某些 fs 如果要实现 0 误差,大家必须得选用外部时钟才可以。

常用iis采样率对应系数表:

假设我们希望生成 44.1 kHz 的音频采样率,以下是具体计算步骤

44.1k= (1000271/2 )/[256(2*I2SDIV+ODD)]

反解出

I2SDIV = 6
ODD    = 0

如果要通过程序去计算这些系数的值,是比较麻烦的,所以,我们事先计算好常用 fs 对应
的系数值,建立一个表,这样,用的时候,只需要查表取值就可以了,大大简化了代码,常用
fs 对应系数表如下:

/*--------------------------------    说明     ---------------------------------
采样率计算公式:Fs=I2SxCLK/[256*(2*I2SDIV+ODD)]
I2SxCLK=(HSE/pllm)*PLLI2SN/PLLI2SR
一般HSE=8Mhz 
pllm:在Sys_Clock_Set设置的时候确定,一般是8
PLLI2SN:一般是192~432 
PLLI2SR:2~7
I2SDIV:2~255
ODD:0/1
I2S分频系数表@pllm=8,HSE=8Mhz,即vco输入频率为1Mhz
表格式:采样率/10,PLLI2SN,PLLI2SR,I2SDIV,ODD
-------------------------------------------------------------------------------*/
const u16 I2S_PSC_TBL[][5]=
{
	{800 ,256,5,12,1},		//8Khz采样率
	{1102,429,4,19,0},		//11.025Khz采样率 
	{1600,213,2,13,0},		//16Khz采样率
	{2205,429,4, 9,1},		//22.05Khz采样率
	{3200,213,2, 6,1},		//32Khz采样率
	{4410,271,2, 6,0},		//44.1Khz采样率
	{4800,258,3, 3,1},		//48Khz采样率
	{8820,316,2, 3,1},		//88.2Khz采样率
	{9600,344,2, 3,1},  	//96Khz采样率
	{17640,361,2,2,0},  	//176.4Khz采样率 
	{19200,393,2,2,0},  	//192Khz采样率
};  

STM32寄存器篇

编程篇

本文标签: 学习指南总线I2SSOUNDic