《STM32从零开始学习历程》——I2C固件库
《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);}
}
《STM32从零开始学习历程》——I2C固件库相关推荐
- 《STM32从零开始学习历程》——SPI固件库
<STM32从零开始学习历程>@EnzoReventon SPI固件库 相关链接: SPI物理层及FLASH芯片介绍 SPI协议层 SPI特性及架构 参考资料: [野火EmbedFire] ...
- 《STM32从零开始学习历程》——I2C协议层
<STM32从零开始学习历程>@EnzoReventon I2C理论部分--协议层 相关资料: I2C物理层介绍 I2C固件库介绍 STM32的I2C特性及架构介绍 参考资料: [野火Em ...
- 《STM32从零开始学习历程》——I2C向EEPROM写入一字节数据(I2C硬件)
<STM32从零开始学习历程>@EnzoReventon I2C向EEPROM写入一字节数据(I2C硬件) 相关链接: I2C物理层介绍 I2C协议层介绍 I2C固件库介绍 STM32的I ...
- 《STM32从零开始学习历程》——SPI特性及架构
<STM32从零开始学习历程>@EnzoReventon SPI特性及架构 相关链接: SPI物理层及FLASH芯片介绍 SPI协议层 SPI固件库 参考资料: [野火EmbedFire] ...
- 《STM32从零开始学习历程》——SPI物理层及FLASH芯片介绍
<STM32从零开始学习历程>@EnzoReventon SPI物理层及FLASH芯片介绍 相关链接: SPI协议层 SPI特性及架构 SPI固件库 参考资料: [野火EmbedFire] ...
- 《STM32从零开始学习历程》——CAN通讯协议协议层
<STM32从零开始学习历程>@EnzoReventon CAN通讯协议协议层 相关链接: <STM32从零开始学习历程>--CAN通讯协议物理层 CAN-bus规范 V2.0 ...
- 《STM32从零开始学习历程》——DMA直接存储区访问理论知识
<STM32从零开始学习历程>@EnzoReventon DMA-直接存储区访问理论知识 本文主要介绍STM32F4 DMA直接存储区的理论知识部分,本文主要参考手册为: [野火Embed ...
- 《STM32从零开始学习历程》——CAN通讯代码详解
<STM32从零开始学习历程>@EnzoReventon CAN通讯代码详解 相关链接: <STM32从零开始学习历程>--CAN通讯协议物理层 CAN-bus规范 V2.0版 ...
- 《STM32从零开始学习历程》——USART串口通讯实验篇1——中断接收与发送
<STM32从零开始学习历程>@EnzoReventon USART串口通讯实验篇1--中断接收与发送 最近开始接触了STM32F4xx系列单片机,对于我这个从零开始学习的小白来说,可谓困 ...
最新文章
- exchange十种常见退信原因
- 12月中国域名服务商Top20市场份额解析(图)
- 图像处理理论(八)——Meanshift, Camshift, Optical flow
- java 数组处理_JAVA操作数组
- 集算器访问HTTP数据的代码示例
- 关于体育的python毕业设计_Python实例13:体育竞技分析
- iptables 开启3306端口
- 【超详细】在Linux上远程登录遇到的若干问题及解决方法(一)
- 开发环境、测试环境、生产环境
- python后端教程_Python学习教程(技术干货):关于前后端分离开发入门
- matlab中结构体使用方法
- java监控屏幕_Java实现简单屏幕监控
- 小米8装magisk
- re库中group(), groups(), groupdict() 用法
- Unified Functional Testing(UFT)15.0.2入门保姆级教程(二),图文详解。QTP
- 基片集成波导原理_基片集成波导
- PyCharm 里面的 c、m、F、f、v、p 分别代表什么含义?
- 最近大火的chatGPT是什么?它是怎样聊天的?
- 软件工程实验-医院患者监护系统设计
- 10、自上而下的电路架构设计