📄 stm32f0xx_i2c.c
字号:
else
{
/* Disable 10-bit header only mode */
I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_HEAD10R);
}
}
/**
* @brief Generates I2C communication Acknowledge.
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
* @param NewState: new state of the Acknowledge.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable ACK generation */
I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_NACK);
}
else
{
/* Enable NACK generation */
I2Cx->CR2 |= I2C_CR2_NACK;
}
}
/**
* @brief Returns the I2C slave matched address .
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
* @retval The value of the slave matched address .
*/
uint8_t I2C_GetAddressMatched(I2C_TypeDef* I2Cx)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
/* Return the slave matched address in the SR1 register */
return (uint8_t)(((uint32_t)I2Cx->ISR & I2C_ISR_ADDCODE) >> 16) ;
}
/**
* @brief Returns the I2C slave received request.
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
* @retval The value of the received request.
*/
uint16_t I2C_GetTransferDirection(I2C_TypeDef* I2Cx)
{
uint32_t tmpreg = 0;
uint16_t direction = 0;
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
/* Return the slave matched address in the SR1 register */
tmpreg = (uint32_t)(I2Cx->ISR & I2C_ISR_DIR);
/* If write transfer is requested */
if (tmpreg == 0)
{
/* write transfer is requested */
direction = I2C_Direction_Transmitter;
}
else
{
/* Read transfer is requested */
direction = I2C_Direction_Receiver;
}
return direction;
}
/**
* @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
* @param Address: specifies the slave address to be programmed.
* @param Number_Bytes: specifies the number of bytes to be programmed.
* This parameter must be a value between 0 and 255.
* @param ReloadEndMode: new state of the I2C START condition generation.
* This parameter can be one of the following values:
* @arg I2C_Reload_Mode: Enable Reload mode .
* @arg I2C_AutoEnd_Mode: Enable Automatic end mode.
* @arg I2C_SoftEnd_Mode: Enable Software end mode.
* @param StartStopMode: new state of the I2C START condition generation.
* This parameter can be one of the following values:
* @arg I2C_No_StartStop: Don't Generate stop and start condition.
* @arg I2C_Generate_Stop: Generate stop condition (Number_Bytes should be set to 0).
* @arg I2C_Generate_Start_Read: Generate Restart for read request.
* @arg I2C_Generate_Start_Write: Generate Restart for write request.
* @retval None
*/
void I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode)
{
uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_SLAVE_ADDRESS(Address));
assert_param(IS_RELOAD_END_MODE(ReloadEndMode));
assert_param(IS_START_STOP_MODE(StartStopMode));
/* Get the CR2 register value */
tmpreg = I2Cx->CR2;
/* clear tmpreg specific bits */
tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
/* update tmpreg */
tmpreg |= (uint32_t)(((uint32_t)Address & I2C_CR2_SADD) | (((uint32_t)Number_Bytes << 16 ) & I2C_CR2_NBYTES) | \
(uint32_t)ReloadEndMode | (uint32_t)StartStopMode);
/* update CR2 register */
I2Cx->CR2 = tmpreg;
}
/**
* @}
*/
/** @defgroup I2C_Group3 SMBUS management functions
* @brief SMBUS management functions
*
@verbatim
===============================================================================
##### SMBUS management functions #####
===============================================================================
[..] This section provides a set of functions that handles SMBus communication
and timeouts detection.
[..] The SMBus Device default address (0b1100 001) is enabled by calling I2C_Init()
function and setting I2C_Mode member of I2C_InitTypeDef() structure to
I2C_Mode_SMBusDevice.
[..] The SMBus Host address (0b0001 000) is enabled by calling I2C_Init()
function and setting I2C_Mode member of I2C_InitTypeDef() structure to
I2C_Mode_SMBusHost.
[..] The Alert Response Address (0b0001 100) is enabled using I2C_SMBusAlertCmd()
function.
[..] To detect cumulative SCL stretch in master and slave mode, TIMEOUTB should be
configured (in accordance to SMBus specification) using I2C_TimeoutBConfig()
function then I2C_ExtendedClockTimeoutCmd() function should be called to enable
the detection.
[..] SCL low timeout is detected by configuring TIMEOUTB using I2C_TimeoutBConfig()
function followed by the call of I2C_ClockTimeoutCmd(). When adding to this
procedure the call of I2C_IdleClockTimeoutCmd() function, Bus Idle condition
(both SCL and SDA high) is detected also.
@endverbatim
* @{
*/
/**
* @brief Enables or disables I2C SMBus alert.
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @param NewState: new state of the I2Cx SMBus alert.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_SMBusAlertCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable SMBus alert */
I2Cx->CR1 |= I2C_CR1_ALERTEN;
}
else
{
/* Disable SMBus alert */
I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_ALERTEN);
}
}
/**
* @brief Enables or disables I2C Clock Timeout (SCL Timeout detection).
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @param NewState: new state of the I2Cx clock Timeout.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_ClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable Clock Timeout */
I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TIMOUTEN;
}
else
{
/* Disable Clock Timeout */
I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMOUTEN);
}
}
/**
* @brief Enables or disables I2C Extended Clock Timeout (SCL cumulative Timeout detection).
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @param NewState: new state of the I2Cx Extended clock Timeout.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_ExtendedClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable Clock Timeout */
I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TEXTEN;
}
else
{
/* Disable Clock Timeout */
I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TEXTEN);
}
}
/**
* @brief Enables or disables I2C Idle Clock Timeout (Bus idle SCL and SDA
* high detection).
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @param NewState: new state of the I2Cx Idle clock Timeout.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_IdleClockTimeoutCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable Clock Timeout */
I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TIDLE;
}
else
{
/* Disable Clock Timeout */
I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIDLE);
}
}
/**
* @brief Configures the I2C Bus Timeout A (SCL Timeout when TIDLE = 0 or Bus
* idle SCL and SDA high when TIDLE = 1).
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @param Timeout: specifies the TimeoutA to be programmed.
* @retval None
*/
void I2C_TimeoutAConfig(I2C_TypeDef* I2Cx, uint16_t Timeout)
{
uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
assert_param(IS_I2C_TIMEOUT(Timeout));
/* Get the old register value */
tmpreg = I2Cx->TIMEOUTR;
/* Reset I2Cx TIMEOUTA bit [11:0] */
tmpreg &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMEOUTA);
/* Set I2Cx TIMEOUTA */
tmpreg |= (uint32_t)((uint32_t)Timeout & I2C_TIMEOUTR_TIMEOUTA) ;
/* Store the new register value */
I2Cx->TIMEOUTR = tmpreg;
}
/**
* @brief Configures the I2C Bus Timeout B (SCL cumulative Timeout).
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @param Timeout: specifies the TimeoutB to be programmed.
* @retval None
*/
void I2C_TimeoutBConfig(I2C_TypeDef* I2Cx, uint16_t Timeout)
{
uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
assert_param(IS_I2C_TIMEOUT(Timeout));
/* Get the old register value */
tmpreg = I2Cx->TIMEOUTR;
/* Reset I2Cx TIMEOUTB bit [11:0] */
tmpreg &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMEOUTB);
/* Set I2Cx TIMEOUTB */
tmpreg |= (uint32_t)(((uint32_t)Timeout << 16) & I2C_TIMEOUTR_TIMEOUTB) ;
/* Store the new register value */
I2Cx->TIMEOUTR = tmpreg;
}
/**
* @brief Enables or disables I2C PEC calculation.
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @param NewState: new state of the I2Cx PEC calculation.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable PEC calculation */
I2Cx->CR1 |= I2C_CR1_PECEN;
}
else
{
/* Disable PEC calculation */
I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PECEN);
}
}
/**
* @brief Enables or disables I2C PEC transmission/reception request.
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @param NewState: new state of the I2Cx PEC request.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void I2C_PECRequestCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable PEC transmission/reception request */
I2Cx->CR1 |= I2C_CR2_PECBYTE;
}
else
{
/* Disable PEC transmission/reception request */
I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR2_PECBYTE);
}
}
/**
* @brief Returns the I2C PEC.
* @param I2Cx: where x can be 1 to select the I2C peripheral.
* @retval The value of the PEC .
*/
uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx)
{
/* Check the parameters */
assert_param(IS_I2C_1_PERIPH(I2Cx));
/* Return the slave matched address in the SR1 register */
return (uint8_t)((uint32_t)I2Cx->PECR & I2C_PECR_PEC);
}
/**
* @}
*/
/** @defgroup I2C_Group4 I2C registers management functions
* @brief I2C registers management functions
*
@verbatim
===============================================================================
##### I2C registers management functions #####
===============================================================================
[..] This section provides a functions that allow user the management of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -