01. I2C简介
I2C(内部集成电路)总线接口用作微控制器和 I2C 串行总线之间的接口。它提供多主模式功能,可以控制所有I2C总线特定的序列、协议、仲裁和时序。它支持标准和快速模式。它还与 SMBus 2.0 兼容。
它可以用于多种用途,包括 CRC 生成和验证、SMBus(系统管理总线)以及 PMBus(电源管理总线)。
根据器件的不同,可利用 DMA 功能来减轻 CPU 的工作量。
02. 相关类型
I2C Init structure
- /**
- * @brief I2C Init structure definition
- */
- typedef struct
- {
- uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency.
- This parameter must be set to a value lower than 400kHz */
- uint16_t I2C_Mode; /*!< Specifies the I2C mode.
- This parameter can be a value of @ref I2C_mode */
- uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
- This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
- uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address.
- This parameter can be a 7-bit or 10-bit address. */
- uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement.
- This parameter can be a value of @ref I2C_acknowledgement */
- uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged.
- This parameter can be a value of @ref I2C_acknowledged_address */
- }I2C_InitTypeDef;
复制代码
I2C_Exported_Constants
- /** @defgroup I2C_Exported_Constants
- * @{
- */
- #define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \
- ((PERIPH) == I2C2) || \
- ((PERIPH) == I2C3))
- /** @defgroup I2C_Digital_Filter
- * @{
- */
- #define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000F)
- /**
- * @}
- */
复制代码
I2C_mode- /** @defgroup I2C_mode
- * @{
- */
- #define I2C_Mode_I2C ((uint16_t)0x0000)
- #define I2C_Mode_SMBusDevice ((uint16_t)0x0002)
- #define I2C_Mode_SMBusHost ((uint16_t)0x000A)
- #define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \
- ((MODE) == I2C_Mode_SMBusDevice) || \
- ((MODE) == I2C_Mode_SMBusHost))
复制代码
I2C_duty_cycle_in_fast_mode
- /** @defgroup I2C_duty_cycle_in_fast_mode
- * @{
- */
- #define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */
- #define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */
- #define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \
- ((CYCLE) == I2C_DutyCycle_2))
复制代码
I2C_acknowledgement
- /** @defgroup I2C_acknowledgement
- * @{
- */
- #define I2C_Ack_Enable ((uint16_t)0x0400)
- #define I2C_Ack_Disable ((uint16_t)0x0000)
- #define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \
- ((STATE) == I2C_Ack_Disable))
复制代码
I2C_transfer_direction
- /** @defgroup I2C_transfer_direction
- * @{
- */
- #define I2C_Direction_Transmitter ((uint8_t)0x00)
- #define I2C_Direction_Receiver ((uint8_t)0x01)
- #define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \
- ((DIRECTION) == I2C_Direction_Receiver))
复制代码
I2C_acknowledged_address
- /** @defgroup I2C_acknowledged_address
- * @{
- */
- #define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000)
- #define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000)
- #define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \
- ((ADDRESS) == I2C_AcknowledgedAddress_10bit))
复制代码
I2C_registers
- /** @defgroup I2C_registers
- * @{
- */
- #define I2C_Register_CR1 ((uint8_t)0x00)
- #define I2C_Register_CR2 ((uint8_t)0x04)
- #define I2C_Register_OAR1 ((uint8_t)0x08)
- #define I2C_Register_OAR2 ((uint8_t)0x0C)
- #define I2C_Register_DR ((uint8_t)0x10)
- #define I2C_Register_SR1 ((uint8_t)0x14)
- #define I2C_Register_SR2 ((uint8_t)0x18)
- #define I2C_Register_CCR ((uint8_t)0x1C)
- #define I2C_Register_TRISE ((uint8_t)0x20)
- #define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \
- ((REGISTER) == I2C_Register_CR2) || \
- ((REGISTER) == I2C_Register_OAR1) || \
- ((REGISTER) == I2C_Register_OAR2) || \
- ((REGISTER) == I2C_Register_DR) || \
- ((REGISTER) == I2C_Register_SR1) || \
- ((REGISTER) == I2C_Register_SR2) || \
- ((REGISTER) == I2C_Register_CCR) || \
- ((REGISTER) == I2C_Register_TRISE))
复制代码
I2C_NACK_position
- /** @defgroup I2C_NACK_position
- * @{
- */
- #define I2C_NACKPosition_Next ((uint16_t)0x0800)
- #define I2C_NACKPosition_Current ((uint16_t)0xF7FF)
- #define IS_I2C_NACK_POSITION(POSITION) (((POSITION) == I2C_NACKPosition_Next) || \
- ((POSITION) == I2C_NACKPosition_Current))
复制代码
I2C_SMBus_alert_pin_level
- /** @defgroup I2C_SMBus_alert_pin_level
- * @{
- */
- #define I2C_SMBusAlert_Low ((uint16_t)0x2000)
- #define I2C_SMBusAlert_High ((uint16_t)0xDFFF)
- #define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \
- ((ALERT) == I2C_SMBusAlert_High))
复制代码
I2C_PEC_position
- /** @defgroup I2C_PEC_position
- * @{
- */
- #define I2C_PECPosition_Next ((uint16_t)0x0800)
- #define I2C_PECPosition_Current ((uint16_t)0xF7FF)
- #define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \
- ((POSITION) == I2C_PECPosition_Current))
复制代码
I2C_interrupts_definition
- /** @defgroup I2C_interrupts_definition
- * @{
- */
- #define I2C_IT_BUF ((uint16_t)0x0400)
- #define I2C_IT_EVT ((uint16_t)0x0200)
- #define I2C_IT_ERR ((uint16_t)0x0100)
- #define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00))
复制代码
I2C_interrupts_definition
- /** @defgroup I2C_interrupts_definition
- * @{
- */
- #define I2C_IT_SMBALERT ((uint32_t)0x01008000)
- #define I2C_IT_TIMEOUT ((uint32_t)0x01004000)
- #define I2C_IT_PECERR ((uint32_t)0x01001000)
- #define I2C_IT_OVR ((uint32_t)0x01000800)
- #define I2C_IT_AF ((uint32_t)0x01000400)
- #define I2C_IT_ARLO ((uint32_t)0x01000200)
- #define I2C_IT_BERR ((uint32_t)0x01000100)
- #define I2C_IT_TXE ((uint32_t)0x06000080)
- #define I2C_IT_RXNE ((uint32_t)0x06000040)
- #define I2C_IT_STOPF ((uint32_t)0x02000010)
- #define I2C_IT_ADD10 ((uint32_t)0x02000008)
- #define I2C_IT_BTF ((uint32_t)0x02000004)
- #define I2C_IT_ADDR ((uint32_t)0x02000002)
- #define I2C_IT_SB ((uint32_t)0x02000001)
- #define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00))
- #define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \
- ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \
- ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \
- ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \
- ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \
- ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \
- ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB))
复制代码
SR2 register flags
- /**
- * @brief SR2 register flags
- */
- #define I2C_FLAG_DUALF ((uint32_t)0x00800000)
- #define I2C_FLAG_SMBHOST ((uint32_t)0x00400000)
- #define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000)
- #define I2C_FLAG_GENCALL ((uint32_t)0x00100000)
- #define I2C_FLAG_TRA ((uint32_t)0x00040000)
- #define I2C_FLAG_BUSY ((uint32_t)0x00020000)
- #define I2C_FLAG_MSL ((uint32_t)0x00010000)
复制代码
SR1 register flags
- /**
- * @brief SR1 register flags
- */
- #define I2C_FLAG_SMBALERT ((uint32_t)0x10008000)
- #define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000)
- #define I2C_FLAG_PECERR ((uint32_t)0x10001000)
- #define I2C_FLAG_OVR ((uint32_t)0x10000800)
- #define I2C_FLAG_AF ((uint32_t)0x10000400)
- #define I2C_FLAG_ARLO ((uint32_t)0x10000200)
- #define I2C_FLAG_BERR ((uint32_t)0x10000100)
- #define I2C_FLAG_TXE ((uint32_t)0x10000080)
- #define I2C_FLAG_RXNE ((uint32_t)0x10000040)
- #define I2C_FLAG_STOPF ((uint32_t)0x10000010)
- #define I2C_FLAG_ADD10 ((uint32_t)0x10000008)
- #define I2C_FLAG_BTF ((uint32_t)0x10000004)
- #define I2C_FLAG_ADDR ((uint32_t)0x10000002)
- #define I2C_FLAG_SB ((uint32_t)0x10000001)
- #define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00))
- #define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \
- ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \
- ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \
- ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \
- ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \
- ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \
- ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \
- ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \
- ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \
- ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \
- ((FLAG) == I2C_FLAG_SB))
复制代码
03. 相关函数
- /* Function used to set the I2C configuration to the default reset state *****/
- void I2C_DeInit(I2C_TypeDef* I2Cx);
- /* Initialization and Configuration functions *********************************/
- void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
- void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);
- void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_DigitalFilterConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DigitalFilter);
- void I2C_AnalogFilterCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);
- void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address);
- void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle);
- void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition);
- void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert);
- void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- /* Data transfers functions ***************************************************/
- void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
- uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
- /* PEC management functions ***************************************************/
- void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition);
- void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
- uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx);
- /* DMA transfers management functions *****************************************/
- void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
- /* Interrupts, events and flags management functions **************************/
- uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register);
- void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState);
- /*
- ===============================================================================
- I2C State Monitoring Functions
- ===============================================================================
- This I2C driver provides three different ways for I2C state monitoring
- depending on the application requirements and constraints:
- 1. Basic state monitoring (Using I2C_CheckEvent() function)
- -----------------------------------------------------------
- It compares the status registers (SR1 and SR2) content to a given event
- (can be the combination of one or more flags).
- It returns SUCCESS if the current status includes the given flags
- and returns ERROR if one or more flags are missing in the current status.
- - When to use
- - This function is suitable for most applications as well as for startup
- activity since the events are fully described in the product reference
- manual (RM0090).
- - It is also suitable for users who need to define their own events.
- - Limitations
- - If an error occurs (ie. error flags are set besides to the monitored
- flags), the I2C_CheckEvent() function may return SUCCESS despite
- the communication hold or corrupted real state.
- In this case, it is advised to use error interrupts to monitor
- the error events and handle them in the interrupt IRQ handler.
- Note
- For error management, it is advised to use the following functions:
- - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR).
- - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
- Where x is the peripheral instance (I2C1, I2C2 ...)
- - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the
- I2Cx_ER_IRQHandler() function in order to determine which error occurred.
- - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd()
- and/or I2C_GenerateStop() in order to clear the error flag and source
- and return to correct communication status.
- 2. Advanced state monitoring (Using the function I2C_GetLastEvent())
- --------------------------------------------------------------------
- Using the function I2C_GetLastEvent() which returns the image of both status
- registers in a single word (uint32_t) (Status Register 2 value is shifted left
- by 16 bits and concatenated to Status Register 1).
- - When to use
- - This function is suitable for the same applications above but it
- allows to overcome the mentioned limitation of I2C_GetFlagStatus()
- function.
- - The returned value could be compared to events already defined in
- this file or to custom values defined by user.
- This function is suitable when multiple flags are monitored at the
- same time.
- - At the opposite of I2C_CheckEvent() function, this function allows
- user to choose when an event is accepted (when all events flags are
- set and no other flags are set or just when the needed flags are set
- like I2C_CheckEvent() function.
- - Limitations
- - User may need to define his own events.
- - Same remark concerning the error management is applicable for this
- function if user decides to check only regular communication flags
- (and ignores error flags).
- 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus())
- -----------------------------------------------------------------------
- Using the function I2C_GetFlagStatus() which simply returns the status of
- one single flag (ie. I2C_FLAG_RXNE ...).
- - When to use
- - This function could be used for specific applications or in debug
- phase.
- - It is suitable when only one flag checking is needed (most I2C
- events are monitored through multiple flags).
- - Limitations:
- - When calling this function, the Status register is accessed.
- Some flags are cleared when the status register is accessed.
- So checking the status of one Flag, may clear other ones.
- - Function may need to be called twice or more in order to monitor
- one single event.
- */
- /*
- ===============================================================================
- 1. Basic state monitoring
- ===============================================================================
- */
- ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);
- /*
- ===============================================================================
- 2. Advanced state monitoring
- ===============================================================================
- */
- uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx);
- /*
- ===============================================================================
- 3. Flag-based state monitoring
- ===============================================================================
- */
- FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
- void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
- ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
- void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
复制代码
04. 结构体封装
- /**
- * @brief Inter-integrated Circuit Interface
- */
- typedef struct
- {
- __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */
- uint16_t RESERVED0; /*!< Reserved, 0x02 */
- __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */
- uint16_t RESERVED1; /*!< Reserved, 0x06 */
- __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */
- uint16_t RESERVED2; /*!< Reserved, 0x0A */
- __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */
- uint16_t RESERVED3; /*!< Reserved, 0x0E */
- __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */
- uint16_t RESERVED4; /*!< Reserved, 0x12 */
- __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */
- uint16_t RESERVED5; /*!< Reserved, 0x16 */
- __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */
- uint16_t RESERVED6; /*!< Reserved, 0x1A */
- __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */
- uint16_t RESERVED7; /*!< Reserved, 0x1E */
- __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */
- uint16_t RESERVED8; /*!< Reserved, 0x22 */
- __IO uint16_t FLTR; /*!< I2C FLTR register, Address offset: 0x24 */
- uint16_t RESERVED9; /*!< Reserved, 0x26 */
- } I2C_TypeDef;
复制代码
|