一、IIC通信
•I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线
•两根通信线:SCL(Serial Clock)、SDA(Serial Data)
•同步,半双工
•带数据应答
•支持总线挂载多设备(一主多从、多主多从)
硬件电路
•所有I2C设备的SCL连在一起,SDA连在一起
•设备的SCL和SDA均要配置成开漏输出模式
•SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右

IIC时序基本单元
SC始终由主机控制产生,从机只能拉伸,不能主动发送时钟。
•起始条件:SCL高电平期间,SDA从高电平切换到低电平
•终止条件:SCL高电平期间,SDA从低电平切换到高电平

发送一个字节:
SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节
接收一个字节:
SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)
接收应答:
主机发完 1 --> 主机释放 SDA --> 从机拉低 SDA(0)= 应答,从机不拉低 SDA(1)= 非应答。
发送应答:
主机收完 1 字节 --> 主机控制 SDA --> 主机拉低 SDA(0)= 应答,主机拉高 SDA(1)= 非应答。
IIC时序
指定地址写
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)
起始条件 (S) --> 从机地址 + 写命令 (0xD0) --> 从机应答(RA:0)--> 寄存器地址 (0x19) --> 从机应答(RA:0)--> 数据 (0xAA) --> 从机应答(RA:0)--> 停止条件 (P)

当前地址读
对于指定设备(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data)
起始条件 (S) --> 从机地址 + 读命令 (0xD1) --> 从机应答(RA:0)-->接收数据 (0x0F)-->主机非应答(RA:1)--> 停止条件 (P)

指定地址读
对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)
起始条件 (S) --> 从机地址 + 写命令 (0xD0) --> 从机应答(RA:0)--> 寄存器地址 (0x19) --> 从机应答(RA:0)--> 重复起始条件 (Sr) --> 从机地址 + 读命令 (0xD1) --> 从机应答(RA:0)--> 接收数据 (0xAA) --> 主机非应答(SA:1)--> 停止条件 (P)
这里要指定地址读,所以主机一开始进行写操作指定从机和读取地址,然后转换为读操作(不能直接转换,要发送Sr)

二、MPU6050
简介
•MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,通过数据融合,可进一步得到姿态角,常应用于平衡车、飞行器等需要检测自身姿态的场景
•3轴加速度计(Accelerometer):测量X、Y、Z轴的加速度
•3轴陀螺仪传感器(Gyroscope):测量X、Y、Z轴的角速度
加速度计:具有静态稳定性,动态不稳定
陀螺仪:具有动态稳定性,不具有静态稳定性。
MPU6050参数
•16位ADC采集传感器的模拟信号,量化范围:-32768~32767
•加速度计满量程选择:±2、±4、±8、±16(g)
•陀螺仪满量程选择: ±250、±500、±1000、±2000(°/sec)
•可配置的数字低通滤波器
•可配置的时钟源
•可配置的采样分频
•
•I2C从机地址:1101000(接地:AD0=0)→ 0x68 → 写 0xD0,读 0xD1
1101001(接 VCC:AD0=1)→ 0x69 → 写 0xD2,读 0xD3
硬件电路


电源与稳压模块
- 输入 :
VCC_5V作为系统主电源。 - LDO 稳压:Q2 是一颗 3.3V LDO,将 5V 转换为稳定的 3.3V 输出,为整个传感器模块供电。
- 滤波电容 :
- C3(4.7µF):LDO 输入滤波,抑制电源纹波。
- C10(10µF)、C12(0.1µF):LDO 输出滤波,提供稳定的 3.3V 电压。
- 状态指示:R201(1kΩ)和 LED D1 组成电源指示灯,3.3V 上电后 LED 点亮,直观显示模块工作状态。
MPU-6050 核心电路
- 供电与去耦 :
VDD(13 脚)和VLOGIC(11 脚)均连接到 3.3V。- C102(0.1µF)是 MPU-6050 的电源去耦电容,必须靠近芯片放置,滤除高频噪声。
- I2C 通信 :
SDA(23 脚)和SCL(24 脚)是 I2C 通信引脚,通过 4.7kΩ 上拉电阻 R4、R5 连接到 3.3V,确保总线在空闲时为高电平。- 从图中
AD0(9 脚)接地可知,MPU-6050 的 I2C 从机地址为 0x68(7 位地址)。
- 辅助 I2C(AUX) :
AUX_DA(XDA, 6 脚)和AUX_CL(XCL, 7 脚)是 MPU-6050 的辅助 I2C 接口,用于外接磁力计等传感器,图中通过 J1 接口引出,方便扩展。
- 中断与其他 :
INT(12 脚)是中断输出引脚,可用于向主控(如 STM32)发送数据就绪等信号。- C11、C13(0.01µF, 0.1µF)是去耦电容,C14(2200pF)是内部稳压电路的滤波电容,均按 datasheet 要求配置。
J1(CON1):辅助接口
- 引出了
XDA、XCL、AD0、INT信号。 - R6(4.7kΩ)将
AD0下拉到地,固定了 I2C 地址;同时也方便用户通过跳线帽改变AD0电平,切换地址为 0x69。
框图

-
传感与采集模块
- 3 轴加速度计(X/Y/Z Accel)和 3 轴陀螺仪(X/Y/Z Gyro),每个通道都带有自测试(Self test)功能。
- 内置温度传感器(Temp Sensor)。
- 所有模拟信号均通过 16 位 ADC 转换为数字量,送入信号调理模块(Signal Conditioning)。
-
信号处理与控制模块
- 信号调理(Signal Conditioning):对原始数据进行滤波、校准等预处理。
- 数字运动处理器(DMP):内置硬件加速引擎,可直接运行姿态解算等复杂算法,减轻主控 MCU 负担。
- FIFO:用于缓存传感器数据,支持批量读取,降低总线通信频率。
- 中断状态寄存器:管理数据就绪、FIFO 溢出等中断事件,通过 INT 引脚输出。
-
通信与接口模块
- 主 / 从 I2C/SPI 接口:支持与主控 MCU 通信,同时可通过 AUX_DA/AUX_CL 外接磁力计等传感器。
- 串行接口多路复用器:实现主从 I2C 通道的灵活切换。
-
电源与时钟模块
- 偏置与 LDO:为芯片内部电路提供稳定的电源。
- 时钟模块:支持外部时钟输入(CLKIN)和内部时钟输出(CLKOUT)。
- 电荷泵:为陀螺仪提供必要的驱动电压。
三、IIC外设
简介
•STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担
•支持多主机模型
•支持7位/10位地址模式
•支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)
•支持DMA
•兼容SMBus协议
•STM32F103C8T6 硬件I2C资源:I2C1、I2C2
结构
框图

基本结构

数据寄存器 DR
- 唯一性 :I2C 是半双工通信,因此只存在一个 DR 寄存器,它既是发送缓冲区,也是接收缓冲区。
- CPU 视角 :
- 当你执行
I2C1->DR = data时,CPU 将并行数据写入 DR,准备发送。 - 当你执行
uint8_t rx = I2C1->DR时,CPU 从 DR 中读取刚刚接收到的并行数据。
- 当你执行
移位寄存器
- 硬件视角:移位寄存器直接与 SDA 引脚相连,负责在 SCL 时钟的驱动下,将并行数据逐位转换成串行数据发送出去,或者将串行数据逐位移入并转换成并行数据。(实行的是高位先行)
- 协作关系 :
- 发送时:CPU 将数据写入 DR,硬件自动将 DR 中的数据并行加载到移位寄存器,然后在 SCL 控制下逐位移出到 SDA 线。
- 接收时:移位寄存器在 SCL 控制下,从 SDA 线逐位移入数据,填满后,硬件自动将其并行加载到 DR 中,等待 CPU 读取。
这种设计实现了 CPU 与外设硬件之间的高效解耦,CPU 只需要操作 DR,而复杂的时序和移位工作由硬件自动完成。
主机发送

7 位地址主发送流程
- EV5 :产生起始条件(S),硬件置位
SB位。软件需读取 SR1,然后将从机地址写入 DR 寄存器以清除该事件。 - EV6 :地址发送完成并收到应答,硬件置位
ADDR位。软件需依次读取 SR1 和 SR2 来清除该事件。 - EV8_1:地址发送后,数据寄存器(DR)和移位寄存器都为空。此时应写入第一个数据字节。
- EV8:数据字节发送完成,DR 为空,移位寄存器非空。此时应写入下一个数据字节,直到所有数据发送完毕。
- EV8_2 :最后一个数据字节发送完成,
TxE和BTF位均被置位。此时软件应产生停止条件(P)来结束通信。
10 位地址主发送流程
10 位地址模式是 7 位模式的扩展,多了一个发送地址高 4 位的步骤:
- EV5:产生起始条件。
- EV9 :发送帧头(包含地址高 4 位),硬件置位
ADDR10位。软件需读取 SR1,然后写入地址低 8 位到 DR。 - EV6 :地址低 8 位发送完成,硬件置位
ADDR位。软件清除该事件。 - 后续的 EV8_1 、EV8 、EV8_2 事件处理与 7 位模式完全一致。
- SR 是只读寄存器:CPU 只能读取里面的标志位,不能直接修改;标志位的清除通常通过 "读特定寄存器 + 写数据" 的方式完成(比如读 SR1 + 读 SR2 清除 ADDR 位)。
- 不同外设的 SR 不同:比如 USART 也有 SR(USART_SR),但里面的标志位和 I2C_SR 完全不一样,不要混淆。
主机接收

7 位地址主接收流程
- EV5 :产生起始条件(S),硬件置位
SB位。软件需读取 SR1,然后将从机地址(带读位)写入 DR 寄存器以清除该事件。 - EV6 :地址发送完成并收到应答,硬件置位
ADDR位。软件需依次读取 SR1 和 SR2 来清除该事件。 - EV6_1 :仅在接收 1 个字节 时触发。在清除
ADDR后,需立即清除 ACK 位并设置 STOP 位,为接收最后一个字节做准备。 - EV7 :一个数据字节接收完成,硬件置位
RxNE位。软件需读取 DR 寄存器来清除该事件并获取数据。此事件在接收多个字节时重复发生。 - EV7_1 :最后一个数据字节接收完成,硬件置位
RxNE位。软件需读取 DR,然后设置ACK=0(发送 NACK)和STOP(产生停止条件)来结束通信。
10 位地址主接收流程
10 位地址模式比 7 位模式更复杂,需要两次地址发送和一个重复起始条件:
- EV5:产生起始条件,发送帧头(写地址)。
- EV9 :帧头发送完成,硬件置位
ADDR10位。软件读取 SR1 后写入地址低 8 位。 - EV6 :地址低 8 位发送完成,硬件置位
ADDR位。软件清除该事件后,必须产生一个重复起始条件(S<sub>r</sub>)。 - EV5:重复起始条件产生,发送帧头(读地址)。
- 后续的 EV6 、EV6_1 、EV7 、EV7_1 事件处理与 7 位模式一致。
软硬对比
软件

硬件

硬件 I2C
- SCL 时钟:非常规整、均匀,频率稳定,几乎没有抖动。这是因为时钟由 STM32 的外设硬件定时器精确生成。
- SDA 跳变:数据位的跳变严格遵守 I2C 协议,发生在 SCL 为低电平期间,时序干净利落。
- 整体观感:波形平滑、专业,符合 I2C 规范,通信可靠性高。
软件 I2C
- SCL 时钟:波形有明显的 "毛刺" 和不均匀性,高低电平持续时间不一致。这是因为 SCL 是由 CPU 通过 GPIO 翻转模拟出来的,受中断、其他任务和指令执行时间影响。
- SDA 跳变:虽然也遵循协议,但跳变时机不如硬件 I2C 精准,可能存在微小的时序偏差。
- 整体观感:波形略显 "粗糙",通信速率和稳定性受 CPU 负载影响较大。
波形背后的原理
- 硬件 I2C:CPU 只需要向 DR 寄存器写入数据或读取数据,剩下的起始条件、地址发送、数据移位、应答检测、停止条件等所有复杂时序,都由外设硬件自动完成。这就像一辆自动驾驶汽车,CPU 只需要下达目的地指令。
- 软件 I2C:CPU 必须手动控制每一个步骤:拉低 SDA 产生起始条件、翻转 SCL 发送每一位数据、读取 SDA 检测应答、拉高 SDA 产生停止条件。这就像手动驾驶,CPU 全程操控方向盘和油门。