STM32F10x - SPI与I2S - 图文
更新时间:2024-01-12 04:47:01 阅读量: 教育文库 文档下载
SPI与I2S
Table.0-1 SPI寄存器 No 1 2 3 4 5 6 7 8 9 寄存器 CR1 CR2 SR DR CRCPR RxCRCR TxCRCR I2S_CFGR I2SPR 描述 SPI控制寄存器1 SPI控制寄存器2 SPI状态寄存器 SPI数据寄存器 SPI CRC多项式寄存器 SPI接收CRC寄存器 SPI发送CRC寄存器 I2S配置寄存器 I2S预分频寄存器 SPI √ √ √ √ √ √ √ I2S √ √ √ √ √ 备注:小容量和中容量没有I2S接口。故STM32F103RBT6不需要考虑I2S库函数。 Table.0-2 库函数列表
No 函数名 描述 1 SPI_I2S_DeInit 将外设SPIx\\I2Sx寄存器重设为缺省值 2 SPI_Init 根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 3 I2S_Init 根据I2S_InitStruct中指定的参数初始化外设I2Sx寄存器 4 SPI_StructInit 把SPI_InitStruct中的每一个参数按缺省值填入 5 I2S_StructInit 把I2S_InitStruct中的每一个参数按缺省值填入 6 SPI_Cmd 使能或失能SPI外设 7 I2S_Cmd 使能或失能I2S外设 8 SPI_I2S_ITConfig 使能或失能指定的SPIx\\I2Sx中断 9 SPI_I2S_DMACmd 使能或失能指定SPIx\\I2Sx的DMA请求 10 SPI_I2S_SendData 通过外设SPIx\\I2Sx发送一个数据 11 SPI_I2S_ReceiveData 返回通过SPIx\\I2Sx最近接收的数据 12 SPI_NSSInternalSoftwareConfig 为选定的SPI软件配置内部NSS管脚 13 SPI_SSOutputCmd 使能或失能指定的SPI SS输出 14 SPI_DataSizeConfig 设置选定的SPI数据大小 15 SPI_TransmitCRC 发送SPIx的CRC值 16 SPI_CalculateCRC 使能或失能指定SPI的传输字CRC值计算 17 SPI_GetCRC 返回指定SPI的发送或者接受CRC寄存器值 18 SPI_GetCRCPolynomial 返回指定SPI的CRC多项式寄存器值 19 SPI_BiDirectionalLineConfig 选择指定SPI在双向模式下的数据传输方向 20 SPI_I2S_GetFlagStatus 检查指定的SPIx\\I2Sx标志位设置与否 21 SPI_I2S_ClearFlag 清除SPIx\\I2Sx的待处理标志位 22 SPI_I2S_GetITStatus 检查指定的SPI\\I2Sx中断发生与否 23 SPI_I2S_ClearITPendingBit 清除SPIx\\I2Sx的中断待处理位 注 标有SPI_I2S的函数,既符合SPI接口,也符合I2S接口;标示I2S的只能对应I2S接口 串行外设接口(SPI)提供与外部设备进行同步串行通讯的功能。接口可以被设置工作在主模式或者从模式。
/*【01】函数SPI_I2S_DeInit
****************************************************************************** * Function Name : SPI_I2S_DeInit
* Description : Deinitializes the SPIx peripheral registers to their default * reset values (Affects also the I2Ss).
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * Output : None * Return : None
*******************************************************************************/ void SPI_I2S_DeInit(SPI_TypeDef* SPIx) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
switch (*(u32*)&SPIx) {
case SPI1_BASE:
/* Enable SPI1 reset state */
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); /* Release SPI1 from reset state */
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); break;
case SPI2_BASE:
//I2S只有I2S2、I2S3,分别对应SPI2、SPI3。先开启SPI2外设,然后设置I2SCFGR可以开启I2S2或SPI2 /* Enable SPI2 reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); /* Release SPI2 from reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); break;
case SPI3_BASE:
/* Enable SPI3 reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE); /* Release SPI3 from reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE); break;
default: break; } }
/*【02】函数SPI_Init
****************************************************************************** * Function Name : SPI_Init
* Description : Initializes the SPIx peripheral according to the specified * parameters in the SPI_InitStruct.
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
* - SPI_InitStruct: pointer to a SPI_InitTypeDef structure that contains the * configuration information for the specified SPI peripheral. * Output : None * Return : None
******************************************************************************/ SPI_InitTypeDef structure:
typedef struct {
u16 SPI_Direction; u16 SPI_Mode; u16 SPI_DataSize; u16 SPI_CPOL; u16 SPI_CPHA; u16 SPI_NSS;
u16 SPI_BaudRatePrescaler; u16 SPI_FirstBit;
u16 SPI_CRCPolynomial; }SPI_InitTypeDef;
SPI_Direction:设置了SPI单向或者双向的数据模式。 Table.02-1 SPI_Direction值
SPI_Direction SPI_Direction_2Lines_RxOnly SPI_Direction_1Line_Rx SPI_Direction_1Line_Tx SPI_Mode:设置了SPI 工作模式。 Table .02-2 SPI_Mode值
SPI_Mode 描述/CR1.8/2 组合的意义 SPI_Mode_Master 设置为主SPI SPI_Mode_Slave 设置为从SPI SPI_DataSize:设置了SPI的数据大小。 Table.02-3 SPI_DataSize值
SPI_DataSize SPI_DataSize_16b SPI_DataSize_8b 描述/CR1.DFF/bit11 SPI发送接收16位帧结构 SPI发送接收8位帧结构 0x0800 0x0000 0x0104 SSI=1;MSTR=1 0x0000 描述CR.15/14/10 SPI设置为双线单向接收 SPI设置为单线双向接收 SPI设置为单线双向发送 组合的意义 SPI_Direction_2Lines_FullDuplex SPI设置为双线双向全双工 0x0000 BIDIMODE=0(双线双向): 0x0400 RXONLY:全双工、只接收 0x8000 BIDIMODE=1(单线双向): 0xC000 BIDIOE:只接收、只发送 SPI_CPOL:选择了串行时钟的稳态。 Table.02-4 SPI_ SPI_CPOL 值
SPI_CPOL 描述/CR1.CPOL SPI_CPOL_High 时钟悬空高 SPI_CPOL_Low 时钟悬空低 bit1 0x0002 0x0000 SPI_CPHA:设置了位捕获的时钟活动沿。 Table.02-5 SPI_SPI_CPHA值
SPI_CPHA SPI_CPHA_2Edge SPI_CPHA_1Edge 描述/CR1.CPHA/bit0 数据捕获于第二个时钟沿 数据捕获于第一个时钟沿 0x0001 0x0000 SPI_NSS:指定了NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理。 Table .02-6 SPI_NSS值
SPI_NSS SPI_NSS_Hard SPI_NSS_Soft 描述/CR1.SSM/bit9 NSS由外部管脚管理 0x0000 内部NSS信号由SSI位控制 0x0200 SPI_BaudRatePrescaler:用来定义波特率预分频的值,这个值用以设置发送和接收的SCK时钟。 Table.02-7 SPI_BaudRatePrescaler值
SPI_BaudRatePrescaler SPI_BaudRatePrescaler2 SPI_BaudRatePrescaler4 SPI_BaudRatePrescaler8 描述/CR1.BR[2:0] 波特率预分频值为2 波特率预分频值为4 波特率预分频值为8 bit5-4 0x0000 0x0008 0x0010 SPI_BaudRatePrescaler16 SPI_BaudRatePrescaler32 SPI_BaudRatePrescaler64 SPI_BaudRatePrescaler128 SPI_BaudRatePrescaler256 波特率预分频值为16 波特率预分频值为32 波特率预分频值为64 波特率预分频值为128 波特率预分频值为256 0x0018 0x0020 0x0028 0x0030 0x0038 注意:通讯时钟由主SPI的时钟分频而得,不需要设置从SPI的时钟。 SPI_FirstBit:指定了数据传输从MSB位还是LSB 位开始。 Table.02-8 SPI_FirstBit值 SPI_FirstBit 描述/CR1. LSBFIRST SPI_FisrtBit_MSB SPI_FisrtBit_LSB 例:
/* Initialize the SPI1 according to the SPI_InitStructure members */ SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DatSize = SPI_DatSize_16b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure);
函数原型如下:
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct) {
u16 tmpreg = 0;
/* check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
/* Check the SPI parameters */
assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler)); assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
/*---------------------------- SPIx CR1 Configuration ------------------------*/ /* Get the SPIx CR1 value */ tmpreg = SPIx->CR1;
/* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */ tmpreg &= CR1_CLEAR_Mask;// 0x3040,CR1除了CRCEN、CRCNEXT、SPE三个控制位,其他都清除。
bit7 数据传输从MSB位开始 0x0000 数据传输从LSB位开始 0x0080 SPI_CRCPolynomial:定义了用于CRC值计算的多项式:>= 0x1。
/* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler master/salve mode, CPOL and CPHA */
/* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */ /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */ /* Set LSBFirst bit according to SPI_FirstBit value */
/* Set BR bits according to SPI_BaudRatePrescaler value */ /* Set CPOL bit according to SPI_CPOL value */
/* Set CPHA bit according to SPI_CPHA value */
tmpreg |= (u16)((u32)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode | SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL | SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |
SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit); /* Write to SPIx CR1 */ SPIx->CR1 = tmpreg;
/* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
SPIx->I2SCFGR &= SPI_Mode_Select; // 0xF7FF,bit11:I2SMOD( 0--SPI;1--I2S )
/*---------------------------- SPIx CRCPOLY Configuration --------------------*/ /* Write to SPIx CRCPOLY */
SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial; }
/*【03】函数I2S_Init
****************************************************************************** * Function Name : I2S_Init
* Description : Initializes the SPIx peripheral according to the specified * parameters in the I2S_InitStruct.
* Input : - SPIx: where x can be 2 or 3 to select the SPI peripheral * (configured in I2S mode).
* - I2S_InitStruct: pointer to an I2S_InitTypeDef structure that * contains the configuration information for the specified * SPI peripheral configured in I2S mode. * Output : None
* Return : None
******************************************************************************/ 结构体I2S_InitTypeDef定义如下:
typedef struct {
u16 I2S_Mode;
u16 I2S_Standard; u16 I2S_DataFormat; u16 I2S_MCLKOutput; u16 I2S_AudioFreq; u16 I2S_CPOL; }I2S_InitTypeDef; [1]、I2S_Mode:
Table.03-1 I2S模式设置,设置主/从模式的发送/接收。 I2S_Mode 意义/I2SCFGR.bit9-8 #define Val
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
* which will be initialized. * Output : None
* Return : None
*******************************************************************************/ void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct) {
/*--------------- Reset I2S init structure parameters values -----------------*/ /* Initialize the I2S_Mode member */
I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
/* Initialize the I2S_Standard member */
I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
/* Initialize the I2S_DataFormat member */
I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
/* Initialize the I2S_MCLKOutput member */
I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
/* Initialize the I2S_AudioFreq member */
I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
/* Initialize the I2S_CPOL member */
I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low; }
/*【06】函数SPI_Cmd
****************************************************************************** * Function Name : SPI_Cmd
* Description : Enables or disables the specified SPI peripheral.
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * - NewState: new state of the SPIx peripheral. * This parameter can be: ENABLE or DISABLE. * Output : None
* Return : None
*******************************************************************************/ void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx)); assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE) {
/* Enable the selected SPI peripheral */
SPIx->CR1 |= CR1_SPE_Set;// 0x0040,开启SPI设备 } else {
/* Disable the selected SPI peripheral */ SPIx->CR1 &= CR1_SPE_Reset;// 0xFFBF } }
/*【07】函数I2S_Cmd
****************************************************************************** * Function Name : I2S_Cmd
* Description : Enables or disables the specified SPI peripheral (in I2S mode). * Input : - SPIx: where x can be 2 or 3 to select the SPI peripheral. * - NewState: new state of the SPIx peripheral. * This parameter can be: ENABLE or DISABLE. * Output : None * Return : None
*******************************************************************************/ void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) {
/* Check the parameters */
assert_param(IS_SPI_23_PERIPH(SPIx)); assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected SPI peripheral (in I2S mode) */ SPIx->I2SCFGR |= I2SCFGR_I2SE_Set;// 0x0400,开启I2S } else
{
/* Disable the selected SPI peripheral (in I2S mode) */ SPIx->I2SCFGR &= I2SCFGR_I2SE_Reset;// 0xFBFF }
}
/*【08】函数SPI_I2S_ITConfig
****************************************************************************** * Function Name : SPI_I2S_ITConfig
* Description : Enables or disables the specified SPI/I2S interrupts. * Input : - SPIx: where x can be :
* - 1, 2 or 3 in SPI mode * - 2 or 3 in I2S mode
* - SPI_I2S_IT: specifies the SPI/I2S interrupt source to be enabled or disabled. * This parameter can be one of the following values: * - SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
* - SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask * - SPI_I2S_IT_ERR: Error interrupt mask
* - NewState: new state of the specified SPI/I2S interrupt. * This parameter can be: ENABLE or DISABLE. * Output : None * Return : None
*******************************************************************************/
SPI_IT:输入参数SPI_IT使能或者失能SPI的中断。可以取下表的一个或者多个取值的组合作为该参数的值。 Table.08-1 SPI_IT值 SPI_I2S_IT 描述/CR2 SPI_I2S_IT_TXE 发送缓存空中断屏蔽 SPI_I2S_IT_RXNE 接收缓存非空中断屏蔽 SPI_I2S_IT_ERR 错误中断屏蔽 例:
/* Enable SPI2 Tx buffer empty interrupt */ SPI_ITConfig(SPI2, SPI_IT_TXE, ENABLE); 函数原型如下:
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, u8 SPI_I2S_IT, FunctionalState NewState) {
u16 itpos = 0, itmask = 0 ;
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_FUNCTIONAL_STATE(NewState)); assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
/* Get the SPI/I2S IT index */
itpos = SPI_I2S_IT >> 4;//取出IT在CR2的位置 /* Set the IT mask */
itmask = (u16)((u16)1 << itpos);
if (NewState != DISABLE) {
/* Enable the selected SPI/I2S interrupt */ SPIx->CR2 |= itmask;//开启中断允许 } else {
/* Disable the selected SPI/I2S interrupt */ SPIx->CR2 &= (u16)~itmask; } }
/*【09】函数SPI_I2S_DMACmd
****************************************************************************** * Function Name : SPI_I2S_DMACmd
* Description : Enables or disables the SPIx/I2Sx DMA interface. * Input : - SPIx: where x can be : * - 1, 2 or 3 in SPI mode
* - 2 or 3 in I2S mode
* - SPI_I2S_DMAReq: specifies the SPI/I2S DMA transfer request * to be enabled or disabled.
* This parameter can be any combination of the following values: * - SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request * - SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
#Val CR2中的位置 0x71 bit7 0x60 bit6 0x50 bit5 * - NewState: new state of the selected SPI/I2S DMA transfer * request.
* This parameter can be: ENABLE or DISABLE. * Output : None
* Return : None
*******************************************************************************/ SPI_DMAReq:SPI_DMAReq使能或者失能SPI Tx和/或SPI Rx的DMA传输请求。 Table.09-1 SPI_DMAReq值 SPI_I2S_DMAReq 描述/CR2 SPI_I2S_DMAReq_Tx 选择Tx缓存DMA传输请求 0x0002 bit1 SPI_I2S_DMAReq_Rx 选择Rx缓存DMA传输请求 0x0001 bit0 例:
/* Enable SPI2 Rx buffer DMA transfer request */ SPI_DMACmd(SPI2, SPI_DMAReq_Rx, ENABLE); 函数原型如下:
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, u16 SPI_I2S_DMAReq, FunctionalState NewState) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_FUNCTIONAL_STATE(NewState)); assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq));
if (NewState != DISABLE)
{
/* Enable the selected SPI/I2S DMA requests */ SPIx->CR2 |= SPI_I2S_DMAReq;//开启DMA请求。 } else
{
/* Disable the selected SPI/I2S DMA requests */ SPIx->CR2 &= (u16)~SPI_I2S_DMAReq; }
}
/*【10】函数SPI_I2S_SendData
****************************************************************************** * Function Name : SPI_I2S_SendData
* Description : Transmits a Data through the SPIx/I2Sx peripheral. * Input : - SPIx: where x can be :
* - 1, 2 or 3 in SPI mode * - 2 or 3 in I2S mode * - Data : Data to be transmitted.. * Output : None
* Return : None
*******************************************************************************/ void SPI_I2S_SendData(SPI_TypeDef* SPIx, u16 Data) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
/* Write in the DR register the data to be sent */ SPIx->DR = Data; }
/*【11】函数SPI_I2S_ReceiveData
****************************************************************************** * Function Name : SPI_I2S_ReceiveData
* Description : Returns the most recent received data by the SPIx/I2Sx peripheral. * Input : - SPIx: where x can be : * - 1, 2 or 3 in SPI mode * - 2 or 3 in I2S mode
* Output : None
* Return : The value of the received data.
*******************************************************************************/ u16 SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
/* Return the data in the DR register */ return SPIx->DR; }
/*【12】函数SPI_NSSInternalSoftwareConfig
****************************************************************************** * Function Name : SPI_NSSInternalSoftwareConfig
* Description : Configures internally by software the NSS pin for the selected * SPI.
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * - SPI_NSSInternalSoft: specifies the SPI NSS internal state. * This parameter can be one of the following values: * - SPI_NSSInternalSoft_Set: Set NSS pin internally
* - SPI_NSSInternalSoft_Reset: Reset NSS pin internally * Output : None
* Return : None
* Note : NSS = Slave Select
*******************************************************************************/ SPI_NSSInternalSoft:内部设置或者重置NSS管脚。 Table.12-1 SPI_DMAReq值
SPI_NSSInternalSoft SPI_NSSInternalSoft_Set SPI_NSSInternalSoft_Reset 例: 描述/CR1.SSI/bit8 内部设置NSS管脚 内部重置NSS管脚 #Val 0x0100 0xFEFF /* Set internaly by software the SPI1 NSS pin */
SPI_NSSInternalSoftwareConfig(SPI1, SPI_NSSInternalSoft_Set); /* Reset internaly by sofwtare the SPI2 NSS pin */
SPI_NSSInternalSoftwareConfig(SPI2, SPI_NSSInternalSoft_Reset);
函数原型如下:
void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, u16 SPI_NSSInternalSoft)
{
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset) {
/* Set NSS pin internally by software */ SPIx->CR1 |= SPI_NSSInternalSoft_Set; } else
{
/* Reset NSS pin internally by software */ SPIx->CR1 &= SPI_NSSInternalSoft_Reset; } }
/*【13】函数SPI_SSOutputCmd
****************************************************************************** * Function Name : SPI_SSOutputCmd
* Description : Enables or disables the SS output for the selected SPI. * Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * - NewState: new state of the SPIx SS output. * This parameter can be: ENABLE or DISABLE. * Output : None
* Return : None
*******************************************************************************/ void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx)); assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected SPI SS output */
SPIx->CR2 |= CR2_SSOE_Set;// 0x0004,开启在主模式下SS输出,该设备不能工作在多主设备模式 } else {
/* Disable the selected SPI SS output */
SPIx->CR2 &= CR2_SSOE_Reset;// 0xFFFB,禁止在主模式下SS输出,该设备可以工作在多主设备模式 } }
/*【14】函数SPI_DataSizeConfig
****************************************************************************** * Function Name : SPI_DataSizeConfig
* Description : Configures the data size for the selected SPI.
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * - SPI_DataSize: specifies the SPI data size.
* This parameter can be one of the following values:
* - SPI_DataSize_16b: Set data frame format to 16bit. * - SPI_DataSize_8b: Set data frame format to 8bit. * Output : None * Return : None
*******************************************************************************/ SPI_DataSize:设置8 位或者16位数据帧结构。 Table.14-1 SPI_DMAReq值
SPI_DataSize SPI_DataSize_8b 例: /* Set 8bit data frame format for SPI1 */ SPI_DataSizeConfig(SPI1, SPI_DataSize_8b); /*Set 16bit data frame format for SPI2 */ SPI_DataSizeConfig(SPI2, SPI_DataSize_16b);
函数原型如下:
void SPI_DataSizeConfig(SPI_TypeDef* SPIx, u16 SPI_DataSize) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx)); assert_param(IS_SPI_DATASIZE(SPI_DataSize));
/* Clear DFF bit */
SPIx->CR1 &= (u16)~SPI_DataSize_16b;//用“16b”值复位DFF位值。 /* Set new DFF bit value */ SPIx->CR1 |= SPI_DataSize; }
/*【15】函数SPI_TransmitCRC
****************************************************************************** * Function Name : SPI_TransmitCRC
* Description : Transmit the SPIx CRC value.
* Input : - SPIx(Not Include I2Sx): where x can be 1, 2 or 3 to select the SPI peripheral. * Output : None * Return : None
*******************************************************************************/ void SPI_TransmitCRC(SPI_TypeDef* SPIx) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
/* Enable the selected SPI CRC transmission */
SPIx->CR1 |= CR1_CRCNext_Set;// 0x1000,下一个发送CRC:1--下一个发送的值来自发送CRC寄存器 }//若为0--下一个发送的值来自发送缓冲区
/*【16】函数SPI_CalculateCRC
描述/CR1.DFF/bit11 设置数据帧格式为8位 #Value 0x0000 0x0800 SPI_DataSize_16b 设置数据帧格式为16位 ****************************************************************************** * Function Name : SPI_CalculateCRC
* Description : Enables or disables the CRC value calculation of the * transfered bytes.
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * - NewState: new state of the SPIx CRC value calculation. * This parameter can be: ENABLE or DISABLE. * Output : None * Return : None
*******************************************************************************/ void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx)); assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE) {
/* Enable the selected SPI CRC calculation */
SPIx->CR1 |= CR1_CRCEN_Set;// 0x2000,硬件CRC校验使能:开启CRC计算 } else
{
/* Disable the selected SPI CRC calculation */ SPIx->CR1 &= CR1_CRCEN_Reset;// 0xDFFF } }
/*【17】函数SPI_GetCRC
****************************************************************************** * Function Name : SPI_GetCRC
* Description : Returns the transmit or the receive CRC register value for * the specified SPI.
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * - SPI_CRC: specifies the CRC register to be read. * This parameter can be one of the following values: * - SPI_CRC_Tx: Selects Tx CRC register * - SPI_CRC_Rx: Selects Rx CRC register * Output : None
* Return : The selected CRC register value..
*******************************************************************************/ SPI_CRC:SPI_CRC选择SPI Rx 或SPI Tx的 CRC 寄存器。 Table.17-1 SPI_CRC值 SPI_CRC SPI_CRC_Tx SPI_CRC_Rx 例:
描述 选择Tx CRC寄存器 选择Rx CRC寄存器 (u8)0x00 (u8)0x01 /* Returns the SPI1 transmit CRC register */ u16 CRCValue;
CRCValue = SPI_GetCRC(SPI1, SPI_CRC_Tx); 函数原型如下:
u16 SPI_GetCRC(SPI_TypeDef* SPIx, u8 SPI_CRC) {
u16 crcreg = 0;
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx)); assert_param(IS_SPI_CRC(SPI_CRC));
if (SPI_CRC != SPI_CRC_Rx)//如果是TXCRC,读TXCRCR {
/* Get the Tx CRC register */ crcreg = SPIx->TXCRCR; }
else//否则是RXCRC,读RXCRCR {
/* Get the Rx CRC register */ crcreg = SPIx->RXCRCR; }
/* Return the selected CRC register */ return crcreg; }
/*【18】函数SPI_GetCRCPolynomial
****************************************************************************** * Function Name : SPI_GetCRCPolynomial
* Description : Returns the CRC Polynomial register value for the specified SPI. * Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * Output : None
* Return : The CRC Polynomial register value.
*******************************************************************************/ u16 SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
/* Return the CRC polynomial register */ return SPIx->CRCPR;//u16 }
/*【19】函数SPI_BiDirectionalLineConfig
****************************************************************************** * Function Name : SPI_BiDirectionalLineConfig
* Description : Selects the data transfer direction in bi-directional mode * for the specified SPI.
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. * - SPI_Direction: specifies the data transfer direction in
* bi-directional mode.
* This parameter can be one of the following values: * - SPI_Direction_Tx: Selects Tx transmission direction * - SPI_Direction_Rx: Selects Rx receive direction * Output : None * Return : None
*******************************************************************************/ SPI_Direction:SPI_Direction选择SPI在双向模式下的数据传输方向。 Table.19-1 SPI_CRC值
SPI_Direction 描述/CR1. SPI_Direction_Tx 选择Tx发送方向 SPI_Direction_Rx 选择Rx接受方向 例:
bit14 #Val 0x4000 0xBFFF /* Set the SPI2 in bidirectional transmit only mode */
SPI_BiDirectionalLineConfig(SPI_Direction_Tx); 函数原型如下:
void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, u16 SPI_Direction) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_DIRECTION(SPI_Direction));
if (SPI_Direction == SPI_Direction_Tx)
{
/* Set the Tx only mode */// 该位和BIDIMODE(=1)位一起决定在“单线双向”模式下数据的传输方向 SPIx->CR1 |= SPI_Direction_Tx;// 1(输出使能(只发模式)) } else {
/* Set the Rx only mode */
SPIx->CR1 &= SPI_Direction_Rx;// 0(输出禁止(只收模式)) } }
/*【20】函数SPI_I2S_GetFlagStatus
****************************************************************************** * Function Name : SPI_I2S_GetFlagStatus
* Description : Checks whether the specified SPI/I2S flag is set or not. * Input : - SPIx: where x can be :
* - 1, 2 or 3 in SPI mode
* - 2 or 3 in I2S mode
* - SPI_I2S_FLAG: specifies the SPI/I2S flag to check. * This parameter can be one of the following values: * - SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
* - SPI_I2S_FLAG_RXNE: Receive buffer not empty flag. * - SPI_I2S_FLAG_BSY: Busy flag. * - SPI_I2S_FLAG_OVR: Overrun flag. * - SPI_FLAG_MODF: Mode Fault flag. * - SPI_FLAG_CRCERR: CRC Error flag.
* - I2S_FLAG_UDR: Underrun Error flag. * - I2S_FLAG_CHSIDE: Channel Side flag. * Output : None
* Return : The new state of SPI_I2S_FLAG (SET or RESET).
*******************************************************************************/ SPI_FLAG:Table 441. 给出了所有可以被函数SPI_GetFlagStatus检查的标志位列表 Table.20-1 SPI_FLAG值
SPI_FLAG SPI_I2S_FLAG_BSY SPI_I2S_FLAG_OVR SPI_I2S_FLAG_MODF SPI_I2S_FLAG_CRCERR SPI_I2S_FLAG_UDR SPI_I2S_FLAG_CHSIDE SPI_I2S_FLAG_TXE SPI_I2S_FLAG_RXNE 描述/SR.bit7-0 忙标志位 超出标志位(overrun) 模式错位标志位 CRC错误标志位 发生下溢(underrun) 需要传输或者接收右声道 发送缓存空标志位 接受缓存非空标志位 #Val 0x0080 0x0040 0x0020 0x0010 ERRIE 0x0008 0x0004 0x0002 TXEIE 0x0001 RXNEIE 控制位 —— 函数原型如下:
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, u16 SPI_I2S_FLAG) {
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
/* Check the status of the specified SPI/I2S flag */ if ((SPIx->SR & SPI_I2S_FLAG) != (u16)RESET) {
/* SPI_I2S_FLAG is set */ bitstatus = SET; } else
{
/* SPI_I2S_FLAG is reset */ bitstatus = RESET; }
/* Return the SPI_I2S_FLAG status */ return bitstatus; }
/*【21】函数SPI_I2S_ClearFlag
****************************************************************************** * Function Name : SPI_I2S_ClearFlag
* Description : Clears the SPIx/I2Sx pending flags. * Input : - SPIx: where x can be : * - 1, 2 or 3 in SPI mode * - 2 or 3 in I2S mode
* - SPI_I2S_FLAG: specifies the SPI/I2S flag to clear. * This parameter can be one of the following values:
* - SPI_I2S_FLAG_OVR: Overrun flag * - SPI_FLAG_MODF: Mode Fault flag. * - SPI_FLAG_CRCERR: CRC Error flag. * - I2S_FLAG_UDR: Underrun Error flag.
* Note: Before clearing OVR flag, it is mandatory to read
* SPI_I2S_DR register, so that the last data is not lost. * Output : None
* Return : None
*******************************************************************************/ 可以清除的Flag只有4个:如下表:
Table.21-1可以清除的中断标志位如下:(对照Table.20-1)
SPI_I2S_FLAG SPI_I2S_FLAG_BSY SPI_I2S_FLAG_OVR SPI_FLAG_MODF SPI_FLAG_CRCERR I2S_FLAG_UDR I2S_FLAG_CHSIDE SPI_I2S_FLAG_TXE SPI_I2S_FLAG_RXNE 函数原型如下: void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, u16 SPI_I2S_FLAG) {
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG));
/* SPI_FLAG_MODF flag clear */ if(SPI_I2S_FLAG == SPI_FLAG_MODF) {
/* Read SR register */
(void)SPIx->SR;//[1]读或写SR
/* Write on CR1 register */
SPIx->CR1 |= CR1_SPE_Set; //[2]写CR1。 }//通过[1][2]步骤,可以清除MODF标志位
/* SPI_I2S_FLAG_OVR flag or I2S_FLAG_UDR flag clear */
else if ((SPI_I2S_FLAG == SPI_I2S_FLAG_OVR) || (SPI_I2S_FLAG == I2S_FLAG_UDR))
{
/* Read SR register (Before clearing OVR flag, it is mandatory to read SPI_I2S_DR register)*/ (void)SPIx->SR;//对于上溢标志OVR和下溢标志UDR,读SR即可清除这两位中断标志 }
else /* SPI_FLAG_CRCERR flag clear */ {
/* Clear the selected SPI flag */
SPIx->SR = (u16)~SPI_I2S_FLAG;//对于CRCERR,只要直接写0即可清除。 } }
描述/SR.bit7-0 忙标志位 超出标志位(overrun) 模式错位标志位 CRC错误标志位 发生下溢(underrun) 发送缓存空标志位 接收缓存非空标志位 #Val 0x0080 0x0040 0x0020 0x0010 0x0008 0x0002 0x0001 可否清除 清除方式 —— 读SR 读SR->写CR1 直接写0 读SR 读SR,但要求OVR、UDR、ERRIE被清除之后。 写数据到DR 或令I2SE =0 控制位 —— ERRIE 需要传输或者接收右声道 0x0004 从DR读数据 TXEIE RXNEIE
/*【22】函数SPI_I2S_GetITStatus
****************************************************************************** * Function Name : SPI_I2S_GetITStatus
* Description : Checks whether the specified SPI/I2S interrupt has occurred or not. * Input : - SPIx: where x can be : * - 1, 2 or 3 in SPI mode
* - 2 or 3 in I2S mode
* - SPI_I2S_IT: specifies the SPI/I2S interrupt source to check. * This parameter can be one of the following values: * - SPI_I2S_IT_TXE: Transmit buffer empty interrupt. * - SPI_I2S_IT_RXNE: Receive buffer not empty interrupt. * - SPI_I2S_IT_OVR: Overrun interrupt. * - SPI_IT_MODF: Mode Fault interrupt. * - SPI_IT_CRCERR: CRC Error interrupt. * - I2S_IT_UDR: Underrun Error interrupt.
* Output : None
* Return : The new state of SPI_I2S_IT (SET or RESET).
*******************************************************************************/ SPI_I2S_IT:下表给出了所有可以被函数SPI_ GetITStatus检查的中断标志位列表。 Table.22-1 SPI_IT值(SR中的CHSIDE和BUSY位本函数不检查)
SPI_I2S_IT SPI_I2S_IT_TXE SPI_I2S_IT_RXNE SPI_I2S_IT_OVR SPI_IT_MODF SPI_IT_CRCERR I2S_IT_UDR 例: /* Test if the SPI1 Overrun interrupt has occurred or not */ ITStatus Status;
Status = SPI_GetITStatus(SPI1, SPI_IT_OVR);
函数原型如下:
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, u8 SPI_I2S_IT) {
ITStatus bitstatus = RESET;
u16 itpos = 0, itmask = 0, enablestatus = 0;
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
/* Get the SPI/I2S IT index */
itpos = (u16)((u16)0x01 << (SPI_I2S_IT & (u8)0x0F));//取出中断标志在SR中的Bit位置。
/* Get the SPI/I2S IT mask */
itmask = SPI_I2S_IT >> 4;//取出中断产生的允许位在CR2中的bit位置 /* Set the IT mask */
itmask = (u16)((u16)0x01 << itmask);
描述/SR 发送缓存空中断标志位 超出中断标志位 模式错误标志位 CRC错误标志位 下溢中断标志位 #Value (u8)0x71 (u8)0x56 (u8)0x55 (u8)0x54 (u8)0x53 SR中的位置 在CR2中控制位位置 bit1 bit0 bit6 bit5 bit4 bit3 bit7=TXEIE bit6=RXNEIE bit5=ERRIE OVR、MODF、CRCERR、UDR标志位只有在ERRIE=1时才能产生 接受缓存非空中断标志位 (u8)0x60 /* Get the SPI_I2S_IT enable bit status */ enablestatus = (SPIx->CR2 & itmask) ;
/* Check the status of the specified SPI/I2S interrupt */
if (((SPIx->SR & itpos) != (u16)RESET) && enablestatus)
//SR中的标志位与CR2对应的控制位同时为1时,表明中断已被发生,并且有效。 {
/* SPI_I2S_IT is set */ bitstatus = SET; } else
{
/* SPI_I2S_IT is reset */ bitstatus = RESET; }
/* Return the SPI_I2S_IT status */ return bitstatus; }
/*【23】函数SPI_I2S_ClearITPendingBit
****************************************************************************** * Function Name : SPI_I2S_ClearITPendingBit
* Description : Clears the SPIx/I2Sx interrupt pending bits. * Input : - SPIx: where x can be : * - 1, 2 or 3 in SPI mode
* - 2 or 3 in I2S mode
* - SPI_I2S_IT: specifies the SPI/I2S interrupt pending bit to clear. * This parameter can be one of the following values: * - SPI_I2S_IT_OVR: Overrun interrupt. * - SPI_IT_MODF: Mode Fault interrupt. * - SPI_IT_CRCERR: CRC Error interrupt. * - I2S_IT_UDR: Underrun Error interrupt. * Output : None * Return : None
*******************************************************************************/ 下表给出了可以被清除的中断标志:
Table.23-1 可被清除的中断标志如下表。
[1]、本表完全采用Table.22-1 给出的参数值。 [2]、清除方式,参考Table.20-1。
SPI_I2S_IT SPI_I2S_IT_TXE SPI_I2S_IT_RXNE SPI_I2S_IT_OVR SPI_IT_MODF SPI_IT_CRCERR I2S_IT_UDR 函数原型如下: {
描述/SR 发送缓存空中断标志位 #Value (u8)0x71 SR中的位置 在CR2中控制位位置 可清除 bit1 bit0 bit6 bit5 bit4 bit3 bit7=TXEIE bit6=RXNEIE 间接 间接 接受缓存非空中断标志位 (u8)0x60 超出中断标志位 (u8)0x56 模式错误标志位 CRC错误标志位 下溢中断标志位 (u8)0x55 (u8)0x54 (u8)0x53 bit5=ERRIE 本函数 OVR、MODF、CRCERR、直接清UDR标志位只有在除。 ERRIE=1时才能产生 void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, u8 SPI_I2S_IT)
u16 itpos = 0;
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT));
/* SPI_IT_MODF pending bit clear */ if(SPI_I2S_IT == SPI_IT_MODF) {
/* Read SR register */ (void)SPIx->SR;
/* Write on CR1 register */ SPIx->CR1 |= CR1_SPE_Set;
}//清除MODF位的操作方式:先读SR,再写CR1。
/* SPI_I2S_IT_OVR or I2S_IT_UDR pending bit clear */
else if((SPI_I2S_IT == SPI_I2S_IT_OVR) || (SPI_I2S_IT == I2S_IT_UDR)) {
/* Read SR register */
(void)(SPIx->SR);//对于清除OVR和UDR位的操作方式:只要读SR即可。 }
else /* SPI_IT_CRCERR pending bit clear */ {
/* Get the SPI/I2S IT index */
itpos = (u16)((u16)0x01 << (SPI_I2S_IT & (u8)0x0F));//取出CRCERR在SR中的位值( = bit4) /* Clear the selected SPI/I2S interrupt pending bits */
SPIx->SR = (u16)~itpos;//对于清除CRCERR位的操作方式:直接写0
//本语句不必采用“SPIx->SR &= (u16)~itpos;”的“&”操作: //写‘1’不能改变SR中其他7位中断标志的状态。 } }
正在阅读:
长三角城乡区域收入不平衡及演化_基于基尼系数分解方法_杜建国05-21
酒店餐饮物资损耗处理办法05-06
消防安全各项制度(水口小学周仁金)03-17
新进人员考察报告04-22
00208国际财务管理06-28
微型小说精选1000字11-21
水浒传中的歇后语02-12
家长辅导孩子学好英语口语的十大经验05-07
五篇感人微小说精选11-21
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- STM32F10x
- 图文
- SPI
- I2S
- 九年级英语教师教学工作计划
- 建筑学专业实习周记18篇
- SPWM调制法逆变器的调制方式
- 发电机漏氢质量保证措施
- 软件工程导论作业第一章 - 图文
- 辅导讲义答案 第二章
- 人教版选修5《有机化学基础》全套测试试题(共十五套)
- 怎样当好新时期农村党支部书记和班子成员
- 六年级奥数 计算 突破繁分数(ABC级).学生版
- 管理学院第一次团员暨学生代表大会会议材料
- 农村清洁工程建设项目建议书暨可行性研究报告书
- 2016年中考英语试卷答案及解析与点评9
- 湖北高院民事审判工作座谈会会议纪要2013
- 浙江省印刷行业企业名录2018版621家 - 图文
- 地方国家权力机关应对突发事件的作用
- 玉林基督教本土化的表现及影响毕业论文
- 桥梁监控测量方案
- 申请一类维修企业资质报告
- 派丽蒙时尚太阳镜,阳光路上有你有我
- 基层宣传工作如何为一线职工传递正能量