stm32之IIC

发布于:2025-05-10 ⋅ 阅读:(17) ⋅ 点赞:(0)

img

1.I2C

https://blog.csdn.net/caiji0169/article/details/142891513

可以先看下之前写的文章

1.1 简介

2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线

两根通信线:SCL(Serial Clock)、SDA(Serial Data)同步,半双工

带数据应答

支持总线挂载多设备(一主多从、多主多从)

img

从左到右分别是:陀螺仪模块、OLED模块、AT24C02存储模块、时钟模块。可以看出都是有SCL和SDA,相比于串口由全双工变为半双工,一根线兼具发送和接收,最大化利用资源。

1.2 硬件电路

所有I2C设备的SCL连在一起,SDA连在一起

设备的SCL和SDA均要配置成开漏输出模式

SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右

img

1.3 时序基本单元

起始和终止:

  • 起始条件:SCL高电平期间,SDA从高电平切换到低电平

    • img
  • 终止条件:SCL高电平期间,SDA从低电平切换到高电平

    • img

发送数据:

发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节

img

接收数据:

接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)

img

发送和接收应答:

发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答

img

接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)

img

1.4 时序实例

1.4.1 指定地址写

对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)

img

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)

img

1.4.3 指定地址读

对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)

img

需要注意的是,主角是主设备哦,比如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)。
  • 能够感知物体围绕各个轴旋转的快慢。

特点

  • 静态稳定性:陀螺仪能检测旋转状态,与加速度计不同,它对静止或匀速直线运动不敏感。
  • 通过 角速度积分 可以得到 角度变化,但需要注意积分方法会受到噪声影响。

噪声与漂移问题

  • 噪声:由于环境和传感器内部的热噪声,角速度在物体静止时并不为零。

  • 漂移:积分的累积效应会将噪声叠加到最终的角度值,导致随时间推移角度偏移越来越大。

    • 例如,静止状态下即便角速度理论上为零,噪声也会导致积分计算出的角度不断增加或减少。

常见用途

  • 检测旋转运动。
  • 在姿态解算中,与加速度计的数据融合用于补偿噪声影响。

img

为了准确计算物体的姿态角(如俯仰角、横滚角),通常需要融合加速度计和陀螺仪的数据。

  • 加速度计:用于提供长时间的静态参考(重力方向)。

  • 陀螺仪:用于快速响应角速度变化,提供动态的短期稳定性。

  • 融合算法:常用 卡尔曼滤波互补滤波

    • 卡尔曼滤波:利用概率模型结合陀螺仪与加速度计数据,抑制噪声和漂移。
    • 互补滤波:通过权重调整两者的贡献,低通滤波处理加速度计数据,高通滤波处理陀螺仪数据。

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:

  1. 直接低位表示,也就是110 1000,也就是是0x68,然后左移1位或上W/R(0/1)就是发送的地址+读/写,此时是正常把0x68当作MPU的地址
  2. 第2种则是将1101000左移一位当作设备的地址,也就是0xD0,之后再或上读写位1/0就是0xD1 / 0xD0,这样可以很清晰的看出是读还是写操作

参数之间的联系

  1. 分辨率与满量程:满量程范围越小,分辨率越高,但动态范围受限。
  2. 滤波器与采样频率:滤波器的截止频率应低于采样频率的一半(符合奈奎斯特定理)。
  3. 采样频率与时钟源:时钟源的精度影响采样频率的稳定性。
  4. 加速度与陀螺仪数据融合
    • 加速度计提供低频稳定性。
    • 陀螺仪提供高频动态响应。
    • 两者需通过滤波或融合算法结合使用。

2.3 硬件电路

img

左上角是一个LDO低压差线性稳定器,左下角是8针的排针,右边的则是MPU的芯片

引脚 功能
VCC、GND 电源
SCL、SDA I2C通信引脚
XCL、XDA 主机I2C通信引脚
AD0 从机地址最低位
INT 中断信号输出

XCK和XDA通常就是用于外接磁力计或者气压计,这样MPU的芯片就可以通过这些扩展接口去读取扩展芯片的数据,在MU6050中是有DMP单元的,可以进行数据融合和姿态解算

2.4 框图

img

2.5 文档

剩下的去看文档

📎RM-MPU-6000A.pdf – 存储映射

📎PS-MPU-6000A.pdf – 产品说明书

寄存器只需要看这一部分:

img

分别是采样频率分频器、配置寄存器、陀螺仪配置寄存器、加速度计配置寄存器

img

加速度计XYZ轴数据寄存器、温度传感器数据寄存器、陀螺仪XYZ轴数据寄存器。_H表示高8位、_L表示低8位

img

电源管理寄存器1、2和和器件ID号。

3.软件操作MPU6050

10-1 软件I2C读写MPU6050.zip

img

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通信外设

对应参考手册img

4.1 简介

STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担

支持多主机模型(也就是主机不一定是stm32,也可以是I2C总线上的其它抢到主权的I2C外设)

支持7位/10位地址模式

支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)

支持DMA

兼容SMBus协议

STM32F103C8T6 硬件I2C资源:I2C1、I2C2

4.2 I2C框图

img


\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功能,则此信号不可用。

整体功能流程

  1. 主设备通过SCL生成时钟信号并控制通信时序。
  2. 数据通过SDA传输,由数据控制模块管理。
  3. 地址模块负责匹配主设备发送的目标地址,从设备根据匹配结果决定是否应答。
  4. 控制逻辑电路协调I2C的状态更新、中断处理和DMA操作。
  5. 时钟控制模块确保通信时钟符合规范。
  6. 数据校验模块(PEC)在特定模式下增强传输可靠性。

4.3 基本结构

img

4.4 主机发送/接收

主机发送:

img

需要记住发送的时候,先要往数据寄存器中写入数据,才能转交给移位寄存器去进行发送。EV8事件,也就是此时移位寄存器是有数据的,当是数据寄存器DR是空的,当主机对DR寄存器(Data Register)写入数据后,DR寄存器为非空,就会清除该EV8事件。其余的也是类似的原理,就是类似于标志位的作用


主机接收:

img


结合参考手册中对寄存器的描述进行理解:

img

4.5 软件/硬件波形对比

img

5.结构体和相关api

对于STM32内部集成了硬件I2C收发电路,是有相关的库函数去直接操作的,对于其电路的相关寄存器等进行配置,只需要通过一个结构体来完成。最基本需要配置的结构可以参考:

img

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 参数控制。

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 外设。
    • NewStateENABLE(使能)或 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_TransmitterI2C_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: 从设备地址确认。主机发送地址后,可能触发以下两种情况:

  1. 发送模式选择
    • 宏定义:
#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE, TRA flags */
    • 功能: 表示主机成功发送了地址,并进入发送模式(Master Transmitter)。
    • 标志说明:
      • ADDR: 地址被确认。
      • TRA: 设备处于发送模式。
      • TXE: 数据寄存器为空。
  1. 接收模式选择
    • 宏定义:
#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: 数据寄存器非空,数据已准备好读取。

EV8EV8_2: 数据发送

  1. EV8: 数据传输中
    • 宏定义:
#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
    • 功能: 数据写入数据寄存器,并正在移位到发送总线上。
    • 标志说明:
      • TXE: 数据寄存器为空,准备接受新数据。
  1. EV8_2: 数据传输完成
    • 宏定义:
#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE, BTF flags */
    • 功能: 表示数据字节已完全传输到总线。
    • 标志说明:
      • BTF (Byte Transfer Finished): 数据字节传输完成。

从机模式 (Slave Mode) 事件

EV1: 从机地址匹配,可能触发以下三种情况:

  1. 接收模式匹配
    • 宏定义:
#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY, ADDR flags */
    • 功能: 表示从机地址匹配,进入接收模式。
  1. 发送模式匹配
    • 宏定义:
#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE, ADDR flags */
    • 功能: 表示从机地址匹配,进入发送模式。
  1. 通用调用匹配
    • 宏定义:
#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: 数据寄存器非空。

EV3EV3_2: 从机发送

  1. EV3: 字节发送中
    • 宏定义:
#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY, TXE flags */
    • 功能: 数据正在移位到总线上。
  1. 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

📎10-2 硬件I2C读写MPU6050.zip

img

Hardware:

User:


网站公告

今日签到

点亮在社区的每一天
去签到