目录
- 1.I2C
- 2.MPU6050
- 3.软件操作MPU6050
- 4.I2C通信外设
- 5.结构体和相关api
-
- 5.1 结构体
- 5.2 API
-
- 5.2.1 基本功能函数
-
- 1. `void I2C_DeInit(I2C_TypeDef* I2Cx)`
- 2. `void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)`
- 3. `void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)`
- 4. `void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)`
- 5. `void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState)`
- 6. `void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)`
- 7. `void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)`
- 8. `void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)`
- 9. `void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)`
- 10. `uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)`
- 11. `void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)`
- 12. `ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)`
- **5.2.2 其他函数简述**
- 5.2.3 EV事件
- 6.硬件操作MPU6050
1.I2C
https://blog.csdn.net/caiji0169/article/details/142891513
可以先看下之前写的文章
1.1 简介
2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线
两根通信线:SCL(Serial Clock)、SDA(Serial Data)同步,半双工
带数据应答
支持总线挂载多设备(一主多从、多主多从)
从左到右分别是:陀螺仪模块、OLED模块、AT24C02存储模块、时钟模块。可以看出都是有SCL和SDA,相比于串口由全双工变为半双工,一根线兼具发送和接收,最大化利用资源。
1.2 硬件电路
所有I2C设备的SCL连在一起,SDA连在一起
设备的SCL和SDA均要配置成开漏输出模式
SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右
1.3 时序基本单元
起始和终止:
起始条件:SCL高电平期间,SDA从高电平切换到低电平
-
终止条件:SCL高电平期间,SDA从低电平切换到高电平
-
发送数据:
发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节
接收数据:
接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)
发送和接收应答:
发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)
1.4 时序实例
1.4.1 指定地址写
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)
Start Addr Wr [A] Data [A] Data [A] … [A] Data [A] P
传输的数据格式,标黄的表示此时传输的数据来自从设备
- Start:开始信号
- Addr:要传输的I2C设备的地址,一般是7bit
- Wr:方向,写。1bit表示,写是0
- [A]:I2C设备的回应,找到I2C设备了,它是不是得给个回应说我是你要找到人。然后主设备发送数据给I2C设备,它是不是也得回应说我收到了
- Data:不用多说了,就是数据,一般是8bit
- P:结束信号
1.4.2 当前地址读
对于指定设备(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data)
1.4.3 指定地址读
对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)
需要注意的是,主角是主设备哦,比如I2C控制器
Start Addr Rd [A] [Data] A [Data] A … A [Data] NA P
- Start:开始信号
- Addr:要传输的I2C设备的地址
- Rd:方向,读。1bit表示,读是1
- [A]:I2C设备的回应,找到I2C设备了,它是不是得给个回应说我是你要找到人。然后I2C设备就可以开始传输信号了
- A:主设备的回应,诶?I2C外设给我发消息了,我收到了是不是得给个回应??
- Data:来自I2C外设的数据
- P:结束信号
2.MPU6050
2.1 简介
MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,通过数据融合,可进一步得到姿态角,常应用于平衡车、飞行器等需要检测自身姿态的场景
3轴加速度计(Accelerometer):测量X、Y、Z轴的加速度
功能
- 测量 X、Y、Z 三个轴的加速度。
- 基于牛顿第二定律 F=maF = maF=ma 工作,测量芯片相对于惯性系的线性加速度。
特点
- 静态稳定性:加速度计能够测量静止时的引力加速度(如地球的重力加速度 ggg)。
例如,若 MPU6050 没有其他运动,仅受重力作用,加速度计会检测到 Z 轴方向的 ggg。 - 动态测量:在运动状态下,通过测定受力方向,可以推算当前运动方向和大小。
工作原理类比
可以类比为一个小球在正方体内的运动:
-
- 当正方体运动时,小球会偏向与运动方向相反的一侧。
- 测量小球作用在墙壁上的力 FFF,通过 F=maF = maF=ma 反推出加速度 aaa。
常见用途
- 检测平移运动。
- 在组合算法中,用来计算物体的姿态角。
3轴陀螺仪传感器(Gyroscope):测量X、Y、Z轴的角速度
功能
- 测量 X、Y、Z 三个轴的角速度(单位:°/s\degree/s°/s 或 rad/srad/srad/s)。
- 能够感知物体围绕各个轴旋转的快慢。
特点
- 静态稳定性:陀螺仪能检测旋转状态,与加速度计不同,它对静止或匀速直线运动不敏感。
- 通过 角速度积分 可以得到 角度变化,但需要注意积分方法会受到噪声影响。
噪声与漂移问题
噪声:由于环境和传感器内部的热噪声,角速度在物体静止时并不为零。
漂移:积分的累积效应会将噪声叠加到最终的角度值,导致随时间推移角度偏移越来越大。
-
- 例如,静止状态下即便角速度理论上为零,噪声也会导致积分计算出的角度不断增加或减少。
常见用途
- 检测旋转运动。
- 在姿态解算中,与加速度计的数据融合用于补偿噪声影响。
为了准确计算物体的姿态角(如俯仰角、横滚角),通常需要融合加速度计和陀螺仪的数据。
加速度计:用于提供长时间的静态参考(重力方向)。
陀螺仪:用于快速响应角速度变化,提供动态的短期稳定性。
融合算法:常用 卡尔曼滤波 或 互补滤波。
-
- 卡尔曼滤波:利用概率模型结合陀螺仪与加速度计数据,抑制噪声和漂移。
- 互补滤波:通过权重调整两者的贡献,低通滤波处理加速度计数据,高通滤波处理陀螺仪数据。
2.2 参数
16位ADC采集传感器的模拟信号,量化范围:-32768~32767
参数解释
- MPU6050 内部使用 16 位 ADC 将加速度和角速度的模拟信号转换为数字信号。
- 数据表示范围:−32768-32768−32768 到 +32767+32767+32767(有符号整型)。
- 数据分辨率:量化间隔由满量程范围和 16 位量化共同决定。
计算公式
分辨率 = 满量程范围 ÷ 2162^{16}216
-
- 例如,若加速度计配置为 ±2g,分辨率为 2×2÷65536≈0.000061g2 × 2 ÷ 65536 ≈ 0.000061 , g2×2÷65536≈0.000061g。
- 若陀螺仪配置为 ±250°/sec,分辨率为 2×250÷65536≈0.00763°/sec2 × 250 ÷ 65536 ≈ 0.00763°/sec2×250÷65536≈0.00763°/sec。
选择建议
应根据应用场景选择合适的满量程范围:
-
- 若运动较为平缓,建议选择较小的满量程范围(如 ±2g 和 ±250°/sec),提高分辨率。
- 若运动剧烈或涉及高速旋转,需选择较大的满量程范围(如 ±16g 和 ±2000°/sec),避免饱和(超出量程)。
加速度计满量程选择:±2、±4、±8、±16(g)
选择依据
应根据目标物体的运动幅度选择:
-
- ±2g:适合微小震动检测,如精密设备的姿态感知。
- ±4g 或 ±8g:适合中等强度运动,如普通机器人、手持设备检测。
- ±16g:适合高速或剧烈运动,如运动相机、飞行器振动检测。
影响
- 较小量程提供更高分辨率,但超出范围会造成数据饱和。
- 较大量程适应性强,但分辨率降低。
陀螺仪满量程选择: ±250、±500、±1000、±2000(°/sec)
选择依据
根据物体的旋转速度选择:
-
- ±250 °**/sec°/sec****°/**sec:适合缓慢旋转的场景,如姿态微调。
- ±500 或 ±1000 °**/sec°/sec****°/**sec:适合中速旋转,如机器人控制。
- ±2000 °**/sec°/sec****°/**sec:适合高速旋转场景,如无人机或陀螺仪校准。
影响
- 类似加速度计,较小量程提供更高分辨率,较大量程适应高速旋转。
可配置的数字低通滤波器
选择依据
根据物体的旋转速度选择:
-
- ±250 °**/sec°/sec****°/**sec:适合缓慢旋转的场景,如姿态微调。
- ±500 或 ±1000 °**/sec°/sec****°/**sec:适合中速旋转,如机器人控制。
- ±2000 °**/sec°/sec****°/**sec:适合高速旋转场景,如无人机或陀螺仪校准。
影响
- 类似加速度计,较小量程提供更高分辨率,较大量程适应高速旋转。
可配置的时钟源
可选时钟
- 内部时钟(8MHz)
- 外部参考(如 32.768kHz 晶振)
选择依据
- 使用内部时钟:默认配置,适合一般应用。
- 使用外部参考时钟:适合高精度场景(如多传感器同步)。
可配置的采样分频
功能
- 采样分频用于降低数据输出速率(ODR),控制 MPU6050 的功耗和带宽。
计算公式
实际采样频率 = 基础采样频率 ÷ (1 + 分频器值)
-
- 基础采样频率通常为 1kHz。
- 例如,分频器值设为 3,则实际采样频率为 1000÷(1+3)=250Hz1000 ÷ (1 + 3) = 250Hz1000÷(1+3)=250Hz。
选择建议
- 高采样频率:动态场景,要求较快数据更新(如 500Hz)。
- 低采样频率:静态场景,降低功耗和噪声(如 50Hz)。
I2C从机地址:1101000(AD0=0)
1101001(AD0=1)
这种是二进制的,而如果是16进制来表示一个地址,是有两种表示方式的,假设AD0引脚为1,此时地址为1101000:
- 直接低位表示,也就是110 1000,也就是是0x68,然后左移1位或上W/R(0/1)就是发送的地址+读/写,此时是正常把0x68当作MPU的地址
- 第2种则是将1101000左移一位当作设备的地址,也就是0xD0,之后再或上读写位1/0就是0xD1 / 0xD0,这样可以很清晰的看出是读还是写操作
参数之间的联系
- 分辨率与满量程:满量程范围越小,分辨率越高,但动态范围受限。
- 滤波器与采样频率:滤波器的截止频率应低于采样频率的一半(符合奈奎斯特定理)。
- 采样频率与时钟源:时钟源的精度影响采样频率的稳定性。
- 加速度与陀螺仪数据融合:
-
- 加速度计提供低频稳定性。
- 陀螺仪提供高频动态响应。
- 两者需通过滤波或融合算法结合使用。
2.3 硬件电路
左上角是一个LDO低压差线性稳定器,左下角是8针的排针,右边的则是MPU的芯片
引脚 | 功能 |
---|---|
VCC、GND | 电源 |
SCL、SDA | I2C通信引脚 |
XCL、XDA | 主机I2C通信引脚 |
AD0 | 从机地址最低位 |
INT | 中断信号输出 |
XCK和XDA通常就是用于外接磁力计或者气压计,这样MPU的芯片就可以通过这些扩展接口去读取扩展芯片的数据,在MU6050中是有DMP单元的,可以进行数据融合和姿态解算
2.4 框图
2.5 文档
剩下的去看文档
📎RM-MPU-6000A.pdf – 存储映射
📎PS-MPU-6000A.pdf – 产品说明书
寄存器只需要看这一部分:
分别是采样频率分频器、配置寄存器、陀螺仪配置寄存器、加速度计配置寄存器
加速度计XYZ轴数据寄存器、温度传感器数据寄存器、陀螺仪XYZ轴数据寄存器。_H表示高8位、_L表示低8位
电源管理寄存器1、2和和器件ID号。
3.软件操作MPU6050
User:
Hardware:
其中:
/**
* 函 数:I2C接收应答位
* 参 数:无
* 返 回 值:接收到的应答位,范围:0~1,0表示应答,1表示非应答
*/
uint8_t MyI2C_ReceiveAck(void)
{
uint8_t AckBit; //定义应答位变量
MyI2C_W_SDA(1); //接收前,主机先确保释放SDA,避免干扰从机的数据发送
MyI2C_W_SCL(1); //释放SCL,主机机在SCL高电平期间读取SDA
AckBit = MyI2C_R_SDA(); //将应答位存储到变量里
MyI2C_W_SCL(0); //拉低SCL,开始下一个时序模块
return AckBit; //返回定义应答位变量
}
还是需要提一下,I2C通信的引脚是属于开漏模式+上拉的模式,不要认为MyI2C_W_SDA(1);
后MyI2C_R_SDA()
读到的就是高电平,这时候进行释放操作,避免干扰从机的数据发送,从机是能够主动拉低SDA的,因此如果此时被拉低了AckBit
就是0,也就是主机收到回应信号ACK。
对MPU6050进行初始化和操作需要对其寄存器进行配置,具体的寄存器配置地址需要去查看其产品存储映射手册。
4.I2C通信外设
对应参考手册
4.1 简介
STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担
支持多主机模型(也就是主机不一定是stm32,也可以是I2C总线上的其它抢到主权的I2C外设)
支持7位/10位地址模式
支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)
支持DMA
兼容SMBus协议
STM32F103C8T6 硬件I2C资源:I2C1、I2C2
4.2 I2C框图
\1. SDA 和 SCL
- SDA: 串行数据线,用于双向数据传输。
- SCL: 串行时钟线,用于同步数据传输。
这两根线是I2C总线的核心,主从设备通过它们进行通信。
\2. 数据控制模块
功能: 管理I2C数据的接收和发送,包括数据存储和比较。
组成模块:
-
- 数据移位寄存器: 将接收或发送的数据按照位移次序处理(串行/并行转换)。
- 比较器: 比较从设备接收的地址是否匹配主机发出的目标地址。
- 帧错误校验(PEC)计算器: 在SMBus模式下,用于生成和校验包错误码,确保数据完整性。
\3. 地址管理模块
功能: 处理I2C设备的地址。
组成模块:
-
- 自身地址寄存器: 存储当前设备的I2C地址,用于匹配主机发出的目标地址。
- 双地址存储器: 用于支持从设备的第二个地址(某些情况下设备可以有多个地址)。
- PEC寄存器: 用于存储错误校验码。
\4. 时钟控制模块
功能: 控制I2C通信时钟频率。
组成模块:
-
- 时钟控制寄存器(CCR): 配置SCL时钟频率,以匹配I2C标准(如标准模式100kHz或快速模式400kHz)。
- 控制寄存器(CR1 & CR2): 配置I2C模块的工作模式(如使能I2C、启用中断等)。
- 状态寄存器(SR1 & SR2): 存储I2C工作状态(如总线忙、数据传输完成、错误状态等)。
\5. 控制逻辑电路
功能: 管理整个I2C接口的操作流程,包括:
-
- 生成中断: 通知处理器当前I2C事件(如传输完成、错误等)。
- DMA请求与响应: 支持直接存储器访问(DMA),在需要传输大量数据时提升性能。
\6. SMBALERT(可选信号)
- 功能: SMBus模式下用于报告警告信号(如设备错误)。
- 注意: 如果禁用了SMBus功能,则此信号不可用。
整体功能流程
- 主设备通过SCL生成时钟信号并控制通信时序。
- 数据通过SDA传输,由数据控制模块管理。
- 地址模块负责匹配主设备发送的目标地址,从设备根据匹配结果决定是否应答。
- 控制逻辑电路协调I2C的状态更新、中断处理和DMA操作。
- 时钟控制模块确保通信时钟符合规范。
- 数据校验模块(PEC)在特定模式下增强传输可靠性。
4.3 基本结构
4.4 主机发送/接收
主机发送:
需要记住发送的时候,先要往数据寄存器中写入数据,才能转交给移位寄存器去进行发送。EV8事件,也就是此时移位寄存器是有数据的,当是数据寄存器DR是空的,当主机对DR寄存器(Data Register)写入数据后,DR寄存器为非空,就会清除该EV8事件。其余的也是类似的原理,就是类似于标志位的作用
主机接收:
结合参考手册中对寄存器的描述进行理解:
4.5 软件/硬件波形对比
5.结构体和相关api
对于STM32内部集成了硬件I2C收发电路,是有相关的库函数去直接操作的,对于其电路的相关寄存器等进行配置,只需要通过一个结构体来完成。最基本需要配置的结构可以参考:
5.1 结构体
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;
1. **I2C_ClockSpeed**
作用:指定 I2C 的时钟频率(通信速率)。
说明:
-
- 该参数的值必须低于 400kHz,符合 I2C 标准模式(≤100kHz)或快速模式(≤400kHz)。
- 在配置该参数时,需要结合 I2C 的主机时钟频率(PCLK1)来计算配置寄存器值。
典型值:
-
100000
:标准模式(100kHz)。400000
:快速模式(400kHz)。
2. **I2C_Mode**
作用:指定 I2C 模式。
说明:
-
- 决定 I2C 工作于 I2C 模式 还是 SMBus 模式。
可取值:
-
I2C_Mode_I2C
:标准 I2C 模式。I2C_Mode_SMBusDevice
:SMBus 设备模式。I2C_Mode_SMBusHost
:SMBus 主机模式。
3. **I2C_DutyCycle**
作用:指定快速模式下的占空比。
说明:
-
- 仅在 快速模式(Fast Mode) 下有效,用于控制 SCL 时钟的高电平和低电平的时间比例。
可取值:
-
I2C_DutyCycle_2
:占空比 1:2。I2C_DutyCycle_16_9
:占空比 16:9。
4. **I2C_OwnAddress1**
作用:指定 I2C 设备的第一个地址。
说明:
-
- 在主从设备通信中,从设备需要有一个唯一的地址,主设备使用该地址与其通信。
- 支持 7 位地址 或 10 位地址。
取值范围:
-
- 7 位地址:0x01 到 0x7F。
- 10 位地址:0x000 到 0x3FF。
注意:
-
- 地址模式(7 位/10 位)由
I2C_AcknowledgedAddress
参数控制。
- 地址模式(7 位/10 位)由
5. **I2C_Ack**
作用:使能或禁用应答(ACK)。
说明:
-
- 主机或从机是否在接收到数据后发送 ACK 信号。
- 如果禁用 ACK,I2C 将在数据接收后发送 NACK 信号,表明数据不被接受。
可取值:
-
I2C_Ack_Enable
:使能 ACK。I2C_Ack_Disable
:禁用 ACK。
6. **I2C_AcknowledgedAddress**
作用:指定从设备地址的模式。
说明:
-
- 配置从设备地址的类型,是 7 位地址还是 10 位地址。
可取值:
-
I2C_AcknowledgedAddress_7bit
:7 位地址。I2C_AcknowledgedAddress_10bit
:10 位地址。
使用示例
#include "stm32f10x.h"
void I2C_Config(void)
{
I2C_InitTypeDef I2C_InitStruct;
// 初始化 I2C 外设时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// 配置 I2C 参数
I2C_InitStruct.I2C_ClockSpeed = 100000; // 100kHz 标准模式
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; // I2C 模式
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 占空比 1:2
I2C_InitStruct.I2C_OwnAddress1 = 0x30; // 从设备地址为 0x30
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; // 使能应答
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // 使用 7 位地址
// 初始化 I2C 外设
I2C_Init(I2C1, &I2C_InitStruct);
// 使能 I2C 外设
I2C_Cmd(I2C1, ENABLE);
}
5.2 API
5.2.1 基本功能函数
1. void I2C_DeInit(I2C_TypeDef* I2Cx)
- 作用:将指定的 I2C 外设寄存器重置为默认值。
- 使用场景:需要重新配置 I2C 外设时调用。
- 示例:
I2C_DeInit(I2C1); // 重置 I2C1
2. void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
作用:初始化 I2C 外设,根据提供的配置结构体
I2C_InitStruct
配置 I2C。参数:
-
I2Cx
:指定目标 I2C 外设(如 I2C1 或 I2C2)。I2C_InitStruct
:包含配置参数的结构体,包括通信速率、地址模式等。
示例:
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_ClockSpeed = 100000; // 设置时钟频率为 100kHz
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; // 工作在 I2C 模式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // 标准模式,占空比 2
I2C_InitStructure.I2C_OwnAddress1 = 0x30; // 本机地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // 开启 ACK
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // 7 位地址模式
I2C_Init(I2C1, &I2C_InitStructure);
3. void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)
作用:填充
I2C_InitStruct
结构体的默认值,便于快速配置。默认值:
-
- 时钟频率:10kHz
- 模式:I2C
- 占空比:
I2C_DutyCycle_2
- 本机地址:0
- 地址模式:7 位
- ACK:关闭
示例:
I2C_InitTypeDef I2C_InitStructure;
I2C_StructInit(&I2C_InitStructure); // 填充默认值
4. void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
作用:使能或禁用指定的 I2C 外设。
参数:
-
I2Cx
:目标 I2C 外设。NewState
:ENABLE
(使能)或DISABLE
(禁用)。
示例:
I2C_Cmd(I2C1, ENABLE); // 启动 I2C1
5. void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
- 作用:使能或禁用指定 I2C 的 DMA 请求。
- 使用场景:当使用 DMA 控制数据传输时。
- 示例:
I2C_DMACmd(I2C1, ENABLE); // 启动 I2C1 的 DMA 请求
6. void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
- 作用:生成 I2C 的起始信号。
- 使用场景:I2C 主机模式下,用于启动数据传输。
- 示例:
I2C_GenerateSTART(I2C1, ENABLE); // 生成起始信号
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); // 等待起始信号成功
7. void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
- 作用:生成 I2C 的停止信号。
- 使用场景:主机发送完成后终止通信。
- 示例:
I2C_GenerateSTOP(I2C1, ENABLE); // 生成停止信号
8. void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
- 作用:使能或禁用 I2C 的 ACK 应答。
- 使用场景:读取多字节数据时,需要根据情况开启或关闭 ACK。
- 示例:
I2C_AcknowledgeConfig(I2C1, ENABLE); // 开启 ACK 应答
9. void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)
- 作用:向数据寄存器发送一个字节数据。
- 使用场景:主机发送数据。
- 示例:
I2C_SendData(I2C1, 0x55); // 发送数据 0x55
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // 等待数据发送完成
10. uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)
- 作用:从数据寄存器读取一个字节数据。
- 使用场景:主机或从机接收数据。
- 示例:
uint8_t data = I2C_ReceiveData(I2C1); // 接收数据
11. void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
作用:向总线发送 7 位从机地址。
参数:
-
Address
:从机地址。I2C_Direction
:通信方向(I2C_Direction_Transmitter
或I2C_Direction_Receiver
)。
示例:
I2C_Send7bitAddress(I2C1, 0x50, I2C_Direction_Transmitter); // 发送从机地址(写)
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // 等待地址发送完成
12. ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
作用:检查 I2C 状态寄存器中是否发生指定事件。
参数:
-
I2C_EVENT
:待检测的事件(例如I2C_EVENT_MASTER_MODE_SELECT
)。
示例:
if (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) == SUCCESS) {
// 事件检测成功
}
5.2.2 其他函数简述
void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState)
:配置 I2C 中断。FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
:检查指定的标志位状态。void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
:清除指定的标志位。void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
:触发软件复位。void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle)
:配置快速模式下的占空比。
5.2.3 EV事件
主机模式 (Master Mode) 事件
EV5: 主机模式选择
- 宏定义:
#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL, SB flags */
功能:
当主机发送 START 条件 后,等待此事件,以确认 START 条件已正确释放到总线。标志说明:
-
- SB (Start Bit): 表示 START 条件已被生成。
- MSL (Master Mode): 表示设备处于主模式。
- BUSY: 总线处于忙碌状态。
EV6: 从设备地址确认。主机发送地址后,可能触发以下两种情况:
- 发送模式选择
-
- 宏定义:
#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE, TRA flags */
-
- 功能: 表示主机成功发送了地址,并进入发送模式(Master Transmitter)。
- 标志说明:
-
-
- ADDR: 地址被确认。
- TRA: 设备处于发送模式。
- TXE: 数据寄存器为空。
-
- 接收模式选择
-
- 宏定义:
#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL, ADDR flags */
-
- 功能: 表示主机成功发送了地址,并进入接收模式(Master Receiver)。
- 标志说明:
-
-
- ADDR: 地址被确认。
-
EV9: 10 位地址模式
- 宏定义:
#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL, ADD10 flags */
功能: 主机发送 10 位地址的前 8 位后,等待此事件以发送剩余的地址。
标志说明:
-
- ADD10: 10 位寻址模式标志。
EV7: 数据接收完成
- 宏定义:
#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL, RXNE flags */
功能: 表示主机接收到一个数据字节。
标志说明:
-
- RXNE: 数据寄存器非空,数据已准备好读取。
EV8 和 EV8_2: 数据发送
- EV8: 数据传输中
-
- 宏定义:
#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
-
- 功能: 数据写入数据寄存器,并正在移位到发送总线上。
- 标志说明:
-
-
- TXE: 数据寄存器为空,准备接受新数据。
-
- EV8_2: 数据传输完成
-
- 宏定义:
#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE, BTF flags */
-
- 功能: 表示数据字节已完全传输到总线。
- 标志说明:
-
-
- BTF (Byte Transfer Finished): 数据字节传输完成。
-
从机模式 (Slave Mode) 事件
EV1: 从机地址匹配,可能触发以下三种情况:
- 接收模式匹配
-
- 宏定义:
#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY, ADDR flags */
-
- 功能: 表示从机地址匹配,进入接收模式。
- 发送模式匹配
-
- 宏定义:
#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE, ADDR flags */
-
- 功能: 表示从机地址匹配,进入发送模式。
- 通用调用匹配
-
- 宏定义:
#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL, BUSY flags */
-
- 功能: 表示从机接收到通用调用地址(0x00)。
EV2: 从机接收字节
- 宏定义:
#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY, RXNE flags */
功能: 表示从机接收到一个数据字节。
标志说明:
-
- RXNE: 数据寄存器非空。
EV3 和 EV3_2: 从机发送
- EV3: 字节发送中
-
- 宏定义:
#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY, TXE flags */
-
- 功能: 数据正在移位到总线上。
- EV3_2: 主机发送 NACK
-
- 宏定义:
#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */
-
- 功能: 主机发送 NACK 表示停止通信。
EV4: 停止条件检测
- 宏定义:
#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */
- 功能: 表示主机发送 STOP 条件,通信终止。
6.硬件操作MPU6050
Hardware:
User: