ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

STM32 I2C(IIC)第三课学习笔记

STM32 I2C(IIC)第三课学习笔记 STM32 I2CIIC第三课学习笔记嵌入式学习笔记 · 第 3 课今天学习了 I2C 总线的基本电路、通信协议以及 STM32 上 I2C 模块的使用CubeMX 配置和读写数据流程整理成文方便复习。文章目录STM32 I2CIIC第三课学习笔记一、为什么需要 I2C串口的缺点二、I2C 的基本电路1. 两线制总线2. 开漏输出 上拉电阻3. 逻辑线与4. 总线电路结构图5. 主机如何发时钟、如何发数据三、I2C 的通信协议1. 一帧数据的组成2. 完整时序图3. 起始位与停止位4. 寻址与数据方向四、I2C 模块的使用STM32CubeMX 配置1. 使能 I2CMode 选择2. Parameter Settings 参数配置3. 速度模式与占空比4. IO 引脚的初始化5. 连接电路硬件接线五、写数据主机 → 从机0. 读写都要看状态寄存器 SR1 / SR21. 写一字节的时序2. HAL 库函数六、读数据从机 → 主机1. 读一字节的时序2. HAL 库函数3. 读写的共同点七、I2C 知识点速查表八、记忆口诀汇总一、为什么需要 I2C串口的缺点第一课学了 GPIO第二课学了串口USART。串口很好用但它有一个明显的短板串口是点对点通信——一台设备只能和一台设备通信想让 MCU 同时挂多个外设屏幕、传感器、EEPROM…串口会占掉很多引脚。I2CInter-Integrated Circuit集成电路间总线也写作 IIC就是为解决一主多从而来的只用 2 根线SDA 数据线 SCL 时钟线就能在一条总线上挂多个设备每个设备用唯一的地址区分。本课的学习脉络课程目录主题内容1I2C 总线的电路结构2数据线和时钟线3逻辑线与4主机如何发送时钟信号5主机如何发送数据6从机如何发送数据二、I2C 的基本电路1. 两线制总线线名称作用SDA数据线Serial Data双向传输数据SCL时钟线Serial Clock主机产生时钟信号控制节奏2. 开漏输出 上拉电阻I2C 总线上每个设备的 SDA/SCL 引脚都是开漏输出Open-Drain结构只能主动拉低输出 0输出 1 时引脚呈高阻态释放总线电平由外部上拉电阻拉到 VCC 决定。所以 I2C 电路必须有上拉电阻典型 4.7kΩVCC ──[上拉电阻]── SDA VCC ──[上拉电阻]── SCL3. 逻辑线与多个设备的引脚并联在同一条线上就形成了逻辑线与关系只要任意一个设备拉低整条总线就是低电平 所有设备都释放高阻时总线被上拉电阻拉为高电平。记忆I2C 开漏输出 上拉电阻 逻辑线与谁拉低谁说了算。4. 总线电路结构图图解析VCC 通过两个上拉电阻分别接到 SDA 和 SCL 两条总线总线上并联挂载 1 个主机STM32F103和 2 个从机每个器件的 SDA 引脚都连到 SDA 总线、SCL 引脚都连到 SCL 总线任意时刻只有一方在总线上发言其他设备保持高阻不干扰。5. 主机如何发时钟、如何发数据时钟信号只由主机产生。主机通过翻转 SCL 输出方波时钟告诉从机现在该采数据了主机发数据在 SCL 为低电平时改变 SDA 电平SCL 变高后从机采样 SDA——保证数据在时钟高电平期间稳定从机发数据同样在 SCL 低电平时改变 SDA由主机继续提供时钟此时 SCL 仍由主机控制。三、I2C 的通信协议本部分学习脉络课程目录主题内容1I2C 通信的基本流程2I2C 的数据帧格式3起始位和停止位4寻址5传输数据6例子1. 一帧数据的组成一次完整的 I2C 通信一帧由以下部分组成部分说明起始位 STARTSCL高 时SDA 由高变低下降沿标志通信开始7 位地址 R/W主机发送从机地址7 位 读/写位0写1读应答 ACK从机收到地址后拉低 SDA表示我在继续数据字节数据按字节传输MSB最高位先发每字节后跟一个 ACK应答 ACK / 非应答 NACK每字节后接收方应答读数据最后一字节主机回 NACK表示够了结束停止位 STOPSCL高 时SDA 由低变高上升沿标志通信结束2. 完整时序图图解析以写 1 字节为例从机地址 0x50起始位SCL高 时 SDA 拉低地址字节先发 7 位地址A6…A0 1010000再发 R/W 位写0应答第 9 个时钟从机拉低 SDA 表示 ACK数据字节D7…D0 按 MSB 先发每 8 位后从机再回一个 ACK停止位SCL高 时 SDA 拉高总线释放。3. 起始位与停止位图解析起始位和停止位的共同点是都在 SCL高电平时观察 SDA 的变化起始位 STARTSCL高 时 SDA 出现下降沿高→低停止位 STOPSCL高 时 SDA 出现上升沿低→高。记忆起始是降停止是升判断时机都在 SCL 高电平。4. 寻址与数据方向总线上每个从机有唯一7 位地址如 0x50、0x3C地址后紧跟R/W 位0主机写主机发数据、从机收1主机读从机发数据、主机收从机比对地址匹配的才应答ACK不匹配的保持沉默。四、I2C 模块的使用STM32CubeMX 配置本部分学习脉络课程目录主题内容1I2C 模块简介2IO 引脚的初始化3连接电路4I2C 的速度模式5时钟信号的占空比6I2C 模块的初始化1. 使能 I2CMode 选择图解析在 Pinout Configuration 中选中 I2C1Mode 下拉有 4 个选项选项说明Disable不使用默认I2C标准 I2C 模式本课用这个SMBus-Alert-modeSMBus 告警模式I2C 的衍生常用于电源管理SMBus-two-wire-InterfaceSMBus 两线接口模式I2C 选I2C即可SMBus 是 Intel 在 I2C 基础上定义的衍生协议引脚与 I2C 兼容。2. Parameter Settings 参数配置图解析主机模式常用配置参数值说明I2C Speed Mode速度模式Standard Mode标准模式 100kHz另有 Fast Mode 400kHzI2C Clock Speed (Hz)100000时钟频率 100kHz对应标准模式Clock No Stretch ModeDisabled允许从机时钟拉伸保持默认即可Primary Address Length7-bit使用 7 位从机地址Dual Address AcknowledgeDisabled关闭双地址应答只用主地址Primary slave address0本机作为从机时的地址主机模式可留 0General Call address detectionDisabled关闭通用呼叫地址3. 速度模式与占空比速度模式速率典型场景标准模式 Standard Mode100 kbit/s大多数传感器、EEPROM快速模式 Fast Mode400 kbit/s高速传感器、显示模块时钟占空比标准模式 SCL 高低电平比例接近 1:1快速模式可通过配置调整占空比T_low/T_high。CubeMX 中 Speed Mode 选好后会自动给出对应频率与占空比参数。4. IO 引脚的初始化选好 I2C1 后CubeMX 会自动把默认引脚配置为 I2C 功能PB6 → SCLI2C1_SCLPB7 → SDAI2C1_SDAGPIO 模式自动设为复用开漏AF_OD 上拉——正好符合 I2C 开漏输出、靠上拉电阻拉高的电气要求不需要手动改。5. 连接电路硬件接线实际接线时对照模块引脚丝印图解析这是硬件上 I2C 引脚的丝印标注D21_SDA 数据线、D21_SCL 时钟线接线时把 STM32 的 PB7(SDA) 接模块 SDA、PB6(SCL) 接模块 SCL再共地GND并供电VCC。若模块/板上没有上拉电阻需要在 SDA、SCL 上各接一个 4.7kΩ 上拉到 VCC。接线四根线VCC、GND、SDAPB7、SCLPB6SDA 对 SDA、SCL 对 SCLI2C 不用交叉。五、写数据主机 → 从机0. 读写都要看状态寄存器 SR1 / SR2图解析HAL 库的读写函数内部就是轮询这两个状态寄存器来判断通信走到哪一步了标志位寄存器含义读写中的用途TxESR1发送数据寄存器空写数据可以写入下一个字节RxNESR1接收数据寄存器非空读数据收到一个字节可以读出BTFSR1字节发送/接收完成一字节传输结束SBSR1起始位已发送通信已经开始ADDRSR1地址匹配/发送完成从机已响应地址AFSR1应答失败从机不应答地址错/设备未接BUSYSR2总线忙总线被占用先等待释放对应关系HAL_I2C_Master_Transmit内部循环等待TxE再写数据HAL_I2C_Master_Receive内部等待RxNE再读数据出错时查AF开始前查BUSY是否空闲。1. 写一字节的时序起始位 → 从机地址R/W(0) → ACK → 数据字节 → ACK → 停止位2. HAL 库函数// 主机向从机地址 0x50 发送 1 个字节 0x53uint8_tdata0x53;HAL_I2C_Master_Transmit(hi2c1,0x501,data,1,100);说明HAL 接口中地址要7 位地址左移 1 位0x501 0xA0HAL 内部会自动加 R/W 位。// 向从机 0x50 的寄存器地址 0x00 写入 1 字节如操作 EEPROM/传感器寄存器HAL_I2C_Mem_Write(hi2c1,0x501,0x00,I2C_MEMADD_SIZE_8BIT,data,1,100);六、读数据从机 → 主机1. 读一字节的时序起始位 → 从机地址R/W(1) → ACK → 数据字节 → NACK主机不应答 → 停止位读多字节时只有最后一个字节主机回 NACK表示读完收工随后发停止位。2. HAL 库函数uint8_trx0;HAL_I2C_Master_Receive(hi2c1,0x501,rx,1,100);// 从从机 0x50 的寄存器地址 0x00 读取 1 字节HAL_I2C_Mem_Read(hi2c1,0x501,0x00,I2C_MEMADD_SIZE_8BIT,rx,1,100);3. 读写的共同点环节谁来做产生起始位/停止位主机产生时钟 SCL主机发送从机地址主机发送数据写主机读从机应答 ACK接收方拉低 SDA最后一个字节后主机回 NACK 再发停止位七、I2C 知识点速查表项目内容信号线SDA数据、SCL时钟两线制电气结构开漏输出 外部上拉电阻典型 4.7kΩ总线逻辑逻辑线与任一设备拉低则总线为低起始位SCL高 时 SDA 下降沿停止位SCL高 时 SDA 上升沿地址7 位地址 R/W 位0写1读数据发送顺序MSB 先发最高位在前应答接收方拉低 SDA ACK读最后一字节主机回 NACK速度模式标准 100kHz / 快速 400kHzF103 I2C1 引脚PB6SCL、PB7SDAGPIO 复用开漏 上拉写数据 HALHAL_I2C_Master_Transmit / HAL_I2C_Mem_Write读数据 HALHAL_I2C_Master_Receive / HAL_I2C_Mem_Read接线SDA 对 SDA、SCL 对 SCL、共地共电源不交叉八、记忆口诀汇总I2C 两线制SDA 传数据SCL 传时钟开漏输出靠上拉。起始是降、停止是升判断时机在 SCL 高电平。地址 7 位加读写应答就是拉低线。主机发时钟、发地址写数据主机发读数据从机发最后字节回 NACK。I2C 接线不交叉SDA 对 SDASCL 对 SCL共地共电源。本文为第三课学习笔记如有错误欢迎评论区指正。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进