📄 stm32f0xx_spi.c
字号:
* and the product configuration). But in case the prescaler value is greater
* than 511, the default value (0x02) will be configured instead.
* @retval None
*/
void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
{
uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
uint32_t tmp = 0;
RCC_ClocksTypeDef RCC_Clocks;
uint32_t sourceclock = 0;
/* Check the I2S parameters */
assert_param(IS_SPI_1_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;
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)
{
i2sodd = (uint16_t)0;
i2sdiv = (uint16_t)2;
}
/* 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)
{
/* Packet length is 16 bits */
packetlength = 1;
}
else
{
/* Packet length is 32 bits */
packetlength = 2;
}
/* I2S Clock source is System clock: Get System Clock frequency */
RCC_GetClocksFreq(&RCC_Clocks);
/* Get the source clock value: based on System Clock value */
sourceclock = RCC_Clocks.SYSCLK_Frequency;
/* Compute the Real divider depending on the MCLK output state with a floating point */
if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
{
/* MCLK output is enabled */
tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
}
else
{
/* MCLK output is disabled */
tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
}
/* Remove the floating point */
tmp = tmp / 10;
/* Check the parity of the divider */
i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
/* Compute the i2sdiv prescaler */
i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
/* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
i2sodd = (uint16_t) (i2sodd << 8);
}
/* Test if the divider is 1 or 0 or greater than 0xFF */
if ((i2sdiv < 2) || (i2sdiv > 0xFF))
{
/* Set the default values */
i2sdiv = 2;
i2sodd = 0;
}
/* Write to SPIx I2SPR register the computed value */
SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
/* Configure the I2S with the SPI_InitStruct values */
tmpreg |= (uint16_t)(SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \
(uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
(uint16_t)I2S_InitStruct->I2S_CPOL))));
/* Write to SPIx I2SCFGR */
SPIx->I2SCFGR = tmpreg;
}
/**
* @brief Enables or disables the specified SPI peripheral.
* @param SPIx: where x can be 1 or 2 to select the SPI peripheral.
* @param NewState: new state of the SPIx peripheral.
* This parameter can be: ENABLE or DISABLE.
* @retval 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 |= SPI_CR1_SPE;
}
else
{
/* Disable the selected SPI peripheral */
SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
}
}
/**
* @brief Enables or disables the TI Mode.
* @note This function can be called only after the SPI_Init() function has
* been called.
* @note When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA
* are not taken into consideration and are configured by hardware
* respectively to the TI mode requirements.
* @param SPIx: where x can be 1 to select the SPI peripheral.
* @param NewState: new state of the selected SPI TI communication mode.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_SPI_1_PERIPH(SPIx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the TI mode for the selected SPI peripheral */
SPIx->CR2 |= SPI_CR2_FRF;
}
else
{
/* Disable the TI mode for the selected SPI peripheral */
SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRF);
}
}
/**
* @brief Enables or disables the specified SPI peripheral (in I2S mode).
* @param SPIx: where x can be 1 to select the SPI peripheral.
* @param NewState: new state of the SPIx peripheral.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_SPI_1_PERIPH(SPIx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected SPI peripheral in I2S mode */
SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE;
}
else
{
/* Disable the selected SPI peripheral in I2S mode */
SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE);
}
}
/**
* @brief Configures the data size for the selected SPI.
* @param SPIx: where x can be 1 or 2 to select the SPI peripheral.
* @param SPI_DataSize: specifies the SPI data size.
* For the SPIx peripheral this parameter can be one of the following values:
* @arg SPI_DataSize_4b: Set data size to 4 bits
* @arg SPI_DataSize_5b: Set data size to 5 bits
* @arg SPI_DataSize_6b: Set data size to 6 bits
* @arg SPI_DataSize_7b: Set data size to 7 bits
* @arg SPI_DataSize_8b: Set data size to 8 bits
* @arg SPI_DataSize_9b: Set data size to 9 bits
* @arg SPI_DataSize_10b: Set data size to 10 bits
* @arg SPI_DataSize_11b: Set data size to 11 bits
* @arg SPI_DataSize_12b: Set data size to 12 bits
* @arg SPI_DataSize_13b: Set data size to 13 bits
* @arg SPI_DataSize_14b: Set data size to 14 bits
* @arg SPI_DataSize_15b: Set data size to 15 bits
* @arg SPI_DataSize_16b: Set data size to 16 bits
* @retval None
*/
void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
{
uint16_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_DATA_SIZE(SPI_DataSize));
/* Read the CR2 register */
tmpreg = SPIx->CR2;
/* Clear DS[3:0] bits */
tmpreg &= (uint16_t)~SPI_CR2_DS;
/* Set new DS[3:0] bits value */
tmpreg |= SPI_DataSize;
SPIx->CR2 = tmpreg;
}
/**
* @brief Configures the FIFO reception threshold for the selected SPI.
* @param SPIx: where x can be 1 or 2 to select the SPI peripheral.
* @param SPI_RxFIFOThreshold: specifies the FIFO reception threshold.
* This parameter can be one of the following values:
* @arg SPI_RxFIFOThreshold_HF: RXNE event is generated if the FIFO
* level is greater or equal to 1/2.
* @arg SPI_RxFIFOThreshold_QF: RXNE event is generated if the FIFO
* level is greater or equal to 1/4.
* @retval None
*/
void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold)
{
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_RX_FIFO_THRESHOLD(SPI_RxFIFOThreshold));
/* Clear FRXTH bit */
SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH);
/* Set new FRXTH bit value */
SPIx->CR2 |= SPI_RxFIFOThreshold;
}
/**
* @brief Selects the data transfer direction in bidirectional mode for the specified SPI.
* @param SPIx: where x can be 1 or 2 to select the SPI peripheral.
* @param SPI_Direction: specifies the data transfer direction in bidirectional mode.
* This parameter can be one of the following values:
* @arg SPI_Direction_Tx: Selects Tx transmission direction
* @arg SPI_Direction_Rx: Selects Rx receive direction
* @retval None
*/
void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t 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 */
SPIx->CR1 |= SPI_Direction_Tx;
}
else
{
/* Set the Rx only mode */
SPIx->CR1 &= SPI_Direction_Rx;
}
}
/**
* @brief Configures internally by software the NSS pin for the selected SPI.
* @note - This function can be called only after the SPI_Init() function has
* been called.
* @param SPIx: where x can be 1 or 2 to select the SPI peripheral.
* @param SPI_NSSInternalSoft: specifies the SPI NSS internal state.
* This parameter can be one of the following values:
* @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
* @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
* @retval None
*/
void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t 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;
}
}
/**
* @brief Enables or disables the SS output for the selected SPI.
* @note - This function can be called only after the SPI_Init() function has
* been called and the NSS hardware management mode is selected.
* @param SPIx: where x can be 1 or 2 to select the SPI peripheral.
* @param NewState: new state of the SPIx SS output.
* This parameter can be: ENABLE or DISABLE.
* @retval 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 |= SPI_CR2_SSOE;
}
else
{
/* Disable the selected SPI SS output */
SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
}
}
/**
* @brief Enables or disables the NSS pulse management mode.
* @note This function can be called only after the SPI_Init() function has
* been called.
* @note When TI mode is selected, the control bits NSSP is not taken into
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -