《STM32从零开始学习历程》@EnzoReventon
STM32 I2C固件库介绍
相关资料:
I2C物理层介绍
I2C协议层介绍
STM32的I2C特性及架构介绍
参考资料:
[野火EmbedFire]《STM32库开发实战指南——基于野火霸天虎开发板》
[正点原子]STM32F4开发指南-库函数版本_V1.2
[ST]《STM32F4xx中文参考手册》
I2C初始化函数介绍
typedef struct
{
uint32_t I2C_ClockSpeed; /*!< 设置SCL时钟频率,此值要低于40 0000 */
uint16_t I2C_Mode; /*!< 指定工作模式,可以选择I2C模式以及SMBUS */
uint16_t I2C_DutyCycle; /*!< 指定时钟占空比,可以选择low/high = 2:1或16:9模式 */
uint16_t I2C_OwnAddress1; /*!< 指定自身的I2C设备地址 */
uint16_t I2C_Ack; /*!< 使能或关闭响应(一般都要使能)*/
uint16_t I2C_AcknowledgedAddress; /*!< 指定地址的长度,可以为7位或者10位 */
}I2C_InitTypeDef;
- I2C_ClockSpeed: 设置I2C的传输速率,在调用初始化函数时,函数会根据我们输入的数值经过运算后把时钟因子写入到I2C的时钟控制寄存器CCR。而我们写入的这个参数值不得高于400KHz。
实际上由于CCR寄存器不能写入小数类型的时钟因子,影响到SCL的实际频率可能会低于本成员设置的参数值,这时除了通讯稍慢一点以外,不会对I2C的标准通讯造成其它影响。 - I2C_Mode: 选择I2C的使用方式,有I2C模式(I2C_Mode_I2C )和SMBus主、从模式(I2C_Mode_SMBusHost、 I2C_Mode_SMBusDevice ) 。
I2C不需要在此处区分主从模式,直接设置I2C_Mode_I2C即可。 - I2C_DutyCycle: 设置I2C的SCL线时钟的占空比。该配置有两个选择,分别为低电平时间比高电平时间为2:1 ( I2C_DutyCycle_2)和16:9(I2C_DutyCycle_16_9)。
其实这两个模式的比例差别并不大,一般要求都不会如此严格,这里随便选就可以了。 - I2C_OwnAddress1: 配置STM32的I2C设备自己的地址,每个连接到I2C总线上的设备都要有一个自己的地址,作为主机也不例外。地址可设置为7位或10位(受下面I2C_AcknowledgeAddress成员决定),只要该地址是I2C总线上唯一的即可。
STM32的I2C外设可同时使用两个地址,即同时对两个地址作出响应,这个结构成员I2C_OwnAddress1配置的是默认的、OAR1寄存器存储的地址,若需要设置第二个地址寄存器OAR2,可使用
I2C_OwnAddress2Config函数来配置,OAR2不支持10位地址。 - I2C_Ack_Enable: 配置I2C应答是否使能,设置为使能则可以发送响应信号。一般配置为允许应答(I2C_Ack_Enable),这是绝大多数遵循I2C标准的设备的通讯要求,改为禁止应答(I2C_Ack_Disable)往往会导致通讯错误。
- I2C_AcknowledgeAddress: 选择I2C的寻址模式是7位还是10位地址。这需要根据实际连接到I2C总线上设备的地址进行选择,这个成员的配置也影响到I2C_OwnAddress1成员,只有这里设置成10位模式时,I2C_OwnAddress1才支持10位地址。
配置好I2C初始化函数之后,对I2C进行初始化,使用I2C_Init函数:
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitSturct)
I2C固件库的使用
(1)MDK5中点击Functions,找到stm32f4xx_i2c.c,双击点开,即可看到所有函数,点击相应函数即可定位到函数定义区域查看相关注释与参数。
(2)使用STM32F4xx_DSP_StdPeriph_Lib_V1.4.0固件库chm查询。STM32F4xx_DSP_StdPeriph_Lib_V1.4.0下载地址。
I2C相关函数介绍
本章节介绍一下常用的几个函数。
- I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) 函数:用来产生I2C通讯开始信号的函数。共有两个参数,一个是选择I2Cx,可以选择1~3,根据芯片提供I2C数量来选择;第二个是状态选择,ENABLE与DISABLE。
/** 函数源码
* @brief Generates I2Cx communication START condition.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @param NewState: new state of the I2C START condition generation.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Generate a START condition */
I2Cx->CR1 |= I2C_CR1_START;
}
else
{
/* Disable the START condition generation */
I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_START);
}
}
- I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) 函数:与上一个开始信号类似,为发送通讯停止信号。参数与开始信号函数一样。
/**
* @brief Generates I2Cx communication STOP condition.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @param NewState: new state of the I2C STOP condition generation.
* This parameter can be: ENABLE or DISABLE.
* @retval None.
*/
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Generate a STOP condition */
I2Cx->CR1 |= I2C_CR1_STOP;
}
else
{
/* Disable the STOP condition generation */
I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_STOP);
}
}
- void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)函数:为发送设备地址函数。
I2C_TypeDef* I2Cx:为选择I2C。
uint8_t Address:为八位设备地址。
uint8_t I2C_Direction:方向,Transmitter mode发送器,Receiver mode接收器。
/**
* @brief Transmits the address byte to select the slave device.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @param Address: specifies the slave address which will be transmitted
* @param I2C_Direction: specifies whether the I2C device will be a Transmitter
* or a Receiver.
* This parameter can be one of the following values
* @arg I2C_Direction_Transmitter: Transmitter mode
* @arg I2C_Direction_Receiver: Receiver mode
* @retval None.
*/
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_DIRECTION(I2C_Direction));
/* Test on the direction to set/reset the read/write bit */
if (I2C_Direction != I2C_Direction_Transmitter)
{
/* Set the address bit0 for read */
Address |= I2C_OAR1_ADD0;
}
else
{
/* Reset the address bit0 for write */
Address &= (uint8_t)~((uint8_t)I2C_OAR1_ADD0);
}
/* Send the address */
I2Cx->DR = Address;
}
- void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data):为发送数据函数。
- uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx):为接收数据函数。
/**
* @brief Sends a data byte through the I2Cx peripheral.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @param Data: Byte to be transmitted..
* @retval None
*/
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
/* Write in the DR register the data to be sent */
I2Cx->DR = Data;
}
=====================================================================================
/**
* @brief Returns the most recent received data by the I2Cx peripheral.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @retval The value of the received data.
*/
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)
{
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
/* Return the data in the DR register */
return (uint8_t)I2Cx->DR;
}
- FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)状态标志位函数:用来判断指定功能的完成完成状态。
uint32_t I2C_FLAG:可以选择不同的状态判定功能。
/**
* @brief Checks whether the specified I2C flag is set or not.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @param I2C_FLAG: specifies the flag to check.
* This parameter can be one of the following values:
* @arg I2C_FLAG_DUALF: Dual flag (Slave mode)
* @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode)
* @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode)
* @arg I2C_FLAG_GENCALL: General call header flag (Slave mode)
* @arg I2C_FLAG_TRA: Transmitter/Receiver flag
* @arg I2C_FLAG_BUSY: Bus busy flag
* @arg I2C_FLAG_MSL: Master/Slave flag
* @arg I2C_FLAG_SMBALERT: SMBus Alert flag
* @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag
* @arg I2C_FLAG_PECERR: PEC error in reception flag
* @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
* @arg I2C_FLAG_AF: Acknowledge failure flag
* @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
* @arg I2C_FLAG_BERR: Bus error flag
* @arg I2C_FLAG_TXE: Data register empty flag (Transmitter)
* @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag
* @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode)
* @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode)
* @arg I2C_FLAG_BTF: Byte transfer finished flag
* @arg I2C_FLAG_ADDR: Address sent flag (Master mode) "ADSL"如果该地址被发送出去了,那么标志位将会置1.
* Address matched flag (Slave mode)"ENDAD"
* @arg I2C_FLAG_SB: Start bit flag (Master mode)
* @retval The new state of I2C_FLAG (SET or RESET). 判断下标志状态,SET为1,RESET为0.
*/
- ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT)中断标志位函数:同样与标志位判断函数用法一样。
/**
* @brief Checks whether the specified I2C interrupt has occurred or not.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @param I2C_IT: specifies the interrupt source to check.
* This parameter can be one of the following values:
* @arg I2C_IT_SMBALERT: SMBus Alert flag
* @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag
* @arg I2C_IT_PECERR: PEC error in reception flag
* @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode)
* @arg I2C_IT_AF: Acknowledge failure flag
* @arg I2C_IT_ARLO: Arbitration lost flag (Master mode)
* @arg I2C_IT_BERR: Bus error flag
* @arg I2C_IT_TXE: Data register empty flag (Transmitter)
* @arg I2C_IT_RXNE: Data register not empty (Receiver) flag
* @arg I2C_IT_STOPF: Stop detection flag (Slave mode)
* @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode)
* @arg I2C_IT_BTF: Byte transfer finished flag
* @arg I2C_IT_ADDR: Address sent flag (Master mode) "ADSL"
* Address matched flag (Slave mode)"ENDAD"
* @arg I2C_IT_SB: Start bit flag (Master mode)
* @retval The new state of I2C_IT (SET or RESET).
*/
- ★ 比起I2C_GetFlagStatus & I2C_GetITStatus更好用的一个标志位判断函数为:ErrorStatus I2C_CheckEvent(I2C_TypeDef I2Cx, uint32_t I2C_EVENT) 函数,这个函数是专门用来检查EVx事件的。
下面是可以供选择的EV事件,在写代码时会用到。
/**
* @brief Checks whether the last I2Cx Event is equal to the one passed
* as parameter.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @param I2C_EVENT: specifies the event to be checked.
* This parameter can be one of the following values:
* @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: EV1
* @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: EV1
* @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: EV1
* @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: EV1
* @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: EV1
* @arg I2C_EVENT_SLAVE_BYTE_RECEIVED: EV2
* @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF): EV2
* @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL): EV2
* @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED: EV3
* @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF): EV3
* @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL): EV3
* @arg I2C_EVENT_SLAVE_ACK_FAILURE: EV3_2
* @arg I2C_EVENT_SLAVE_STOP_DETECTED: EV4
* @arg I2C_EVENT_MASTER_MODE_SELECT: EV5
* @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: EV6
* @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: EV6
* @arg I2C_EVENT_MASTER_BYTE_RECEIVED: EV7
* @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING: EV8
* @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED: EV8_2
* @arg I2C_EVENT_MASTER_MODE_ADDRESS10: EV9
*
* @note For detailed description of Events, please refer to section I2C_Events
* in stm32f4xx_i2c.h file.
*
* @retval An ErrorStatus enumeration value:
* - SUCCESS: Last event is equal to the I2C_EVENT
* - ERROR: Last event is different from the I2C_EVENT
*/
- void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)响应函数:配置成ENABLE时,接收到数据时会响应。
/**
* @brief Enables or disables the specified I2C acknowledge feature.
* @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
* @param NewState: new state of the I2C Acknowledgement.
* 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 the acknowledgement */
I2Cx->CR1 |= I2C_CR1_ACK;
}
else
{
/* Disable the acknowledgement */
I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK);
}
}
转载:https://blog.csdn.net/qq_33693310/article/details/115459901
查看评论