STM32F10x_SPI与I2S(2)

2019-03-03 12:58

I2S_Mode_SlaveTx I2S_Mode_SlaveRx I2S_Mode_MasterTx I2S_Mode_MasterRx 从模式发送 从模式接收 主模式发送 主模式接收 0x0000 0x0100 0x0200 0x0300 [2]、I2S_Standard:I2S标准选择 Table.03-2 I2S 标准选择值如下表

I2S_Standard I2S_Standard_MSB I2S_Standard_LSB I2S_Standard_PCMLong 意义/I2SCFGR 左<高位>对齐标准 右<低位>对齐标准 PCM模式下的长帧同步 #define 0x0000 0x0010 0x0020 0x0030 0x00B0 单位或组合意义 bit5-4 = I2SSTD =0b00 bit5-4 = I2SSTD =0b01 bit5-4 = I2SSTD =0b10 I2SSTD=11(bit5-4/PCM标准)下,PMCSYNC(bit7)才有意义:0-短帧同步,1-短帧同步 I2S_Standard_Phillips I2S飞利浦标准 I2S_Standard_PCMShort PCM模式下的短帧同步 [3]、I2S_DataFormat:设定通道数据长度值 Table.03-3通道数据长度

I2S_DataFormat I2S_DataFormat_16b 意义/I2SCFGR 待传输数据长度16位 #define 0x0000 单位或组合意义 bit0(CHLEN)=0:通道数据长度固定为16位。 bit2-1(DATLEN)为任何值都是16位数据。 bit0=1(32位位宽): bit2-1=00—16位扩展数据 bit2-1=01—24位数据 bit2-1=10—32位数据 bit2-1=11—保留 I2S_DataFormat_16bextended 待传输数据长度扩展16位 0x0001 I2S_DataFormat_24b 待传输数据长度24位 0x0003 I2S_DataFormat_32b 待传输数据长度32位 0x0005 上述“扩展16位”、“24位”、“32位”表示数据以32位包的形式传输。由CHLEN = 1(32位包)决定。对于“扩展16位”,数据16位放在32位包的MSB处,后16位LSB强制位0填充;对于“24位”、“32位”,放在MSB除,LSB也强制填充为0,发送时分2次发送。 [4]、I2S_MCLKOutput:主设备时钟输出使能 Table.03-4主设备时钟输出使能

I2S_MCLKOutput I2S_MCLKOutput_Enable 意义/I2SPR.bit9 使能主设备时钟输出 #define 0x0200 I2S_MCLKOutput_Disable 关闭主设备时钟输出 0x0000 [5]、I2S_AudioFreq:从定义的音频通道采样频率计算出I2SDIV[7:0]的值。 Table.03-5音频通道采样频率

I2S_AudioFreq I2S_AudioFreq_48k I2S_AudioFreq_44k I2S_AudioFreq_22k I2S_AudioFreq_16k I2S_AudioFreq_8k 意义:实际目标值[Fs] 通道数据频率48KHz 通道数据频率44.1KHz 通道数据频率16KHz 通道数据频率8KHz 目标频率值 (u16)48000 (u16)44100 (u16)16000 (u16)8000 (u16)2 获取I2SDIV值的方法 I2S的音频采样频率[Fs]: 通过RCC_GetClocksFreq()获取系统时间,然后根据I2SPR的ODD位及I2SDIV位,计算出填入I2SDIV[7:0]内的线性分频值。而不是直接把“目标频率值”直接填入I2SDIV[7:0]内。 同时I2SDIV的最终值,要受MCKOE控制。 通道数据频率22.05KHz (u16)22050 I2S_AudioFreq_Default 通道数据频率2Hz 下图是I2S时钟发生器的结构图

线性分频器需要按照以下的公式来设置,以获得需要的频率:

1、当需要生成主时钟时(寄存器SPI->I2SPR的MCKOE =‘1’) :

A、声道的帧长为16位时,Fs = I2SxCLK / [(16*2) * ((2*I2SDIV) + ODD)*8]

B、声道的帧长为32位时,Fs = I2SxCLK / [(32*2) * ((2*I2SDIV) + ODD)*4]

即:在MCKOE=1时,不管声道帧长为16位或32或,固定Fs= I2SxCLK / [256 * ((2*I2SDIV) + ODD)] 2、当关闭主时钟时(MCKOE =‘0’) :

A、声道的帧长为16位时,Fs = I2SxCLK / [(16*2) * ((2*I2SDIV) + ODD)] B、声道的帧长为32位时,Fs = I2SxCLK / [(32*2) * ((2*I2SDIV) + ODD)] 上述

1、I2SxCLK 的时钟源是系统时钟(即驱动AHB时钟的HSI、HSE或PLL )

2、第一个“2”表示左右声道; 3、“(2*I2SDIV) + ODD”表示I2SPR内bit8-0控制关系;

4、“16”或“32”表示帧长度,指的是I2SCFGR.CHLEN控制下的位宽;

5、“8”或“4”表示“I2S主时钟可以输出到外部音频设备,比率固定为256*Fs”模式下的256对齐系数。 6、Fs = 音频通道采样频率(参看I2S_AudioFreq取值); 7、I2SxCLK为I2Sx的外设时钟。 而:

I2S 的比特率即确定了在I2S 数据线上的数据流和I2S的时钟信号频率。 I2S比特率 = 每个声道的比特数 × 声道数目 × 音频采样频率 对于一个左右声道,16位音频,I2S比特率计算为:I2S 比特率 = 16 × 2 × Fs 如果包长为32位,则有:I2S 比特率 = 32 × 2 × Fs

[6]、I2S_CPOL:I2S静止态时钟极性:为高电平还是位低电平。 Table.03-6 空闲状态下,时钟的电平取值

I2S_CPOL I2S_CPOL_Low 描述/I2SCFGR.bit3 #define I2S时钟静止态为低电平 ((u16)0x0000) I2S_CPOL_High I2S时钟静止态为高电平 ((u16)0x0008) 在调用本函数之前,必须对上述结构体成员进行数据初始化设置。 函数原型如下:

void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct) {

u16 tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1; u32 tmp = 0;

RCC_ClocksTypeDef RCC_Clocks;

/* Check the I2S parameters */

assert_param(IS_SPI_23_PERIPH(SPIx));

assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));

assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));

assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput)); assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq)); assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));

/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/

/* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits *///全配置 SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask; //0xF040

//Bit6、Bit12-15为保留位,不改变,保持为0;

//备注:凡Mask直接清0寄存器位,保留位对应的Mask值一律保持为1,以保证不改变原0值状态。 SPIx->I2SPR = 0x0002;

/* Get the I2SCFGR register value */

tmpreg = SPIx->I2SCFGR;

/* If the default value has to be written, reinitialize i2sdiv and i2sodd*/ if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)//缺省频率为2Hz

{

i2sodd = (u16)0;//偶系数:Freq = i2sdiv*2。如果设置为1(奇系数),则Freq = i2sdiv*2+1 i2sdiv = (u16)2; //2分频值,结合上句,则实际时钟为2*2=4分频。

}

/* If the requested audio frequency is not the default, compute the prescaler */ else {

/* Check the frame length (For the Prescaler computing) */

if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)//通道位宽16位 {

/* Packet length is 16 bits */

packetlength = 1;//包长为1表示16位。此时,CHLEN = 0。 }

else//扩展16位?24位?32位? {

/* Packet length is 32 bits */

packetlength = 2; //包长为2表示32位。此时,CHLEN = 1。包长这里起到控制程序作用。 }

/* Get System Clock frequency */

RCC_GetClocksFreq(&RCC_Clocks);//来源于SYSCLK(AHB)—HSI? PLLCLK? HSE?

/* Compute the Real divider depending on the MCLK output state with a flaoting point */ if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)//MCKOE = 1 {

/* MCLK output is enabled */

tmp = (u16)(((10 * RCC_Clocks.SYSCLK_Frequency) / (256 * I2S_InitStruct->I2S_AudioFreq)) + 5); }// RCC_Clocks.SYSCLK_Frequency = HSI或HSE或PLLCLK = 8M、16M、24M、48M、72M。 else//MCKOE = 0 {

/* MCLK output is disabled */

tmp = (u16)(((10 * RCC_Clocks.SYSCLK_Frequency) / (32 * packetlength * \\

I2S_InitStruct->I2S_AudioFreq)) + 5);// packetlength* AudioFreq = I2S 比特率。 }

/* Remove the flaoting point */

tmp = tmp/10;

//*10、 +5、/10,以保证tmp取值为四舍五入。

//仅在(MCKOE = 1)8M时钟 48K、44.1K、22.05K取值,

// 16M时钟 48K、44.1K取值下,tmp = 1,其他取值都能保证>=2。 /* Check the parity of the divider */

i2sodd = (u16)(tmp & (u16)0x0001);//获取分频系数的奇偶性(LSB)。

/* Compute the i2sdiv prescaler */

i2sdiv = (u16)((tmp - i2sodd) / 2);//去除奇偶性后的分频值,即去掉LSB。

/* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */

i2sodd = (u16) (i2sodd << 8);//把决定奇偶性的LSB位左移8位,用于控制I2SPR.ODD位。 }

/* Test if the divider is 1 or 0 */ if ((i2sdiv < 2) || (i2sdiv > 0xFF)) {

/* Set the default values */ i2sdiv = 2;

i2sodd = 0; //如果分频系数小于2或大于0xFF,都把分频系数设置为:Default、偶分频。 }

/* Write to SPIx I2SPR register the computed value */

SPIx->I2SPR = (u16)(i2sdiv | i2sodd | I2S_InitStruct->I2S_MCLKOutput);

/* Configure the I2S with the SPI_InitStruct values */

tmpreg |= (u16)(I2S_Mode_Select | I2S_InitStruct->I2S_Mode | \\

I2S_InitStruct->I2S_Standard | I2S_InitStruct->I2S_DataFormat | \\ I2S_InitStruct->I2S_CPOL);

/* Write to SPIx I2SCFGR */

SPIx->I2SCFGR = tmpreg; }

被调用函数RCC_GetClocksFreq(&RCC_Clocks);如下

/*【04】函数SPI_StructInit

****************************************************************************** * Function Name : SPI_StructInit

* Description : Fills each SPI_InitStruct member with its default value. * Input : - SPI_InitStruct : pointer to a SPI_InitTypeDef structure * which will be initialized.

* Output : None * Return : None

*******************************************************************************/ Table 420. 给出了SPI_InitStruct各个成员的缺省值 Table.04-1 SPI_InitStruct缺省值

成员 SPI_Direction SPI_Mode SPI_DataSize SPI_CPOL SPI_CPHA SPI_NSS SPI_BaudRatePrescaler SPI_FirstBit 缺省值 SPI_Direction_2Lines_FullDuplex SPI_Mode_Slave SPI_DataSize_8b SPI_CPOL_Low SPI_CPHA_1Edge SPI_NSS_Hard SPI_BaudRatePrescaler_2 SPI_FirstBit_MSB SPI_CRCPolynomial 7 结构体I2S_InitTypeDef定义如下: typedef struct {

u16 I2S_Mode;

u16 I2S_Standard; u16 I2S_DataFormat; u16 I2S_MCLKOutput; u16 I2S_AudioFreq; u16 I2S_CPOL; }I2S_InitTypeDef;

例:

/* Initialize an SPI_InitTypeDef structure */ SPI_InitTypeDef SPI_InitStructure;

SPI_StructInit(&SPI_InitStructure); 函数原型如下:

void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) {

/*--------------- Reset SPI init structure parameters values -----------------*/ /* Initialize the SPI_Direction member */

SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;

/* initialize the SPI_Mode member */ SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;

/* initialize the SPI_DataSize member */

SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;

/* Initialize the SPI_CPOL member */

SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;

/* Initialize the SPI_CPHA member */ SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;

/* Initialize the SPI_NSS member */

SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;

/* Initialize the SPI_BaudRatePrescaler member */

SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;

/* Initialize the SPI_FirstBit member */

SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;

/* Initialize the SPI_CRCPolynomial member */ SPI_InitStruct->SPI_CRCPolynomial = 7; }

/*【05】函数I2S_StructInit

****************************************************************************** * Function Name : I2S_StructInit

* Description : Fills each I2S_InitStruct member with its default value. * Input : - I2S_InitStruct : pointer to a I2S_InitTypeDef structure


STM32F10x_SPI与I2S(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:Gossip girl

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: