STM32IIC协议基础及Cube配置
- 一,I²C协议简介
- 二,I²C协议基础概念
- 三,I²C通信流程详解
-
- [1. 通信准备与起始条件](#1. 通信准备与起始条件)
- [2. 从设备寻址](#2. 从设备寻址)
- [3. 地址应答](#3. 地址应答)
- [4. 数据传输](#4. 数据传输)
- [5. 重复起始条件](#5. 重复起始条件)
- [6. 停止条件](#6. 停止条件)
- 四,I²C高级机制
- 五,I²C与其他通信协议对比
- 六,I²C实际应用示例
- 七,CubeMX配置
-
- [1,I2C: 模式选择](#1,I2C: 模式选择)
-
-
- 1,模式 (Mode)
- [2,I2C 速度模式 (I2C Speed Mode)](#2,I2C 速度模式 (I2C Speed Mode))
-
- [2,I2C: 时钟配置](#2,I2C: 时钟配置)
-
-
- [1,I2C 时钟速度 (I2C Clock Speed - Hz)](#1,I2C 时钟速度 (I2C Clock Speed - Hz))
- 2,快速模式占空比 (Clock Duty Cycle - Fast Mode)
- 3,时序寄存器 (Timing Register - I2C_TIMINGR - 适用于高级型号)
-
- [3,I2C: 寻址模式](#3,I2C: 寻址模式)
- [4,I2C: 从机特性](#4,I2C: 从机特性)
-
-
- [1,本机地址 1 (Primary Slave Address)](#1,本机地址 1 (Primary Slave Address))
- 2,双地址模式 (Dual Address Mode)
- 3,广播呼叫地址检测 (General Call Address Detection)
- 4,时钟延长 (Clock Stretching)
-
- [5,I2C: DMA 配置](#5,I2C: DMA 配置)
-
-
- [1,添加 DMA 请求 (Add DMA Request)](#1,添加 DMA 请求 (Add DMA Request))
- [2,DMA 通道配置 (DMA Request Settings)](#2,DMA 通道配置 (DMA Request Settings))
-
- [6,I2C: 中断配置 (NVIC)](#6,I2C: 中断配置 (NVIC))
-
-
- [1,NVIC 设置 (NVIC Settings)](#1,NVIC 设置 (NVIC Settings))
- [2,相关的 HAL 回调函数](#2,相关的 HAL 回调函数)
-
- [7,I2C: GPIO 配置](#7,I2C: GPIO 配置)
-
-
- 1,引脚选择 (Pin Selection)
- [2,GPIO 配置 (GPIO Settings Tab)](#2,GPIO 配置 (GPIO Settings Tab))
-
一,I²C协议简介
I²C(Inter-Integrated Circuit,读作"I-squared-C")是一种由飞利浦公司(现恩智浦半导体)开发的串行(一根数据线)通信总线,广泛应用于连接微控制器和低速外围设备。
1,核心特点
1,仅需两根信号线:串行数据线(SDA)和串行时钟线(SCL)
2,支持多主机多从机架构(最多128个设备,使用7位寻址)
3,每个设备都有唯一的地址
4,通信速率灵活(标准模式100kHz,快速模式400kHz等)
5,内置硬件应答机制确保可靠传输
6,支持总线仲裁,解决多主机冲突
2,应用场景
1,传感器连接与控制(温度、湿度、压力、加速度等)
2,存储设备通信(EEPROM、Flash等)
3,显示屏和LED驱动器控制
4,电源管理系统
5,实时时钟(RTC)
6,音频系统(例如数字音量控制)
7,摄像头模块通信
二,I²C协议基础概念
I²C协议基于一套精确的信号时序和状态转换。了解这些基础概念是掌握I²C通信的关键。
1,总线结构
I²C总线由两条开漏信号线组成:串行数据线(SDA)和串行时钟线(SCL)。总线上的所有设备并联连接,并通过上拉电阻默认保持高电平。开漏结构允许多个设备共享同一条总线而不会产生电平冲突。
参与IIC协议通信的引脚要配置位开漏模式
2,主从架构
I²C网络中的设备分为主设备和从设备。主设备负责产生时钟信号、启动通信、寻址从设备和控制数据流向。从设备则响应主设备的命令,根据要求发送或接收数据。一个I²C总线可以有多个主设备和多个从设备。
3,设备寻址
I²C协议使用7位或10位地址空间来唯一标识每个从设备。常见的7位地址方式支持最多128个设备。主设备通过在总线上发送目标设备的地址和一个读/写位来选择通信对象。地址可由厂商预设或通过硬件配置。
4,起始和停止条件
I²C通信使用特殊的总线状态表示通信的开始和结束。起始条件(START)是在SCL高电平时,SDA从高变为低;停止条件(STOP)是在SCL高电平时,SDA从低变为高。这两种条件定义了一个完整通信帧的边界。
5,数据传输
数据在SCL时钟的控制下按位传输,遵循"最高有效位(MSB)优先"原则。数据在SCL低电平期间准备,在SCL高电平期间采样。一个完整的字节传输包含8位数据和1位应答。SDA电平在SCL高电平期间必须保持稳定。
6,应答机制
I²C协议的可靠性源于其内置的应答机制。每传输8位数据后,接收方需发送一个应答位(ACK)。应答位为低电平(0)表示成功接收,高电平(1)表示非应答(NACK)。这种机制使发送方能够确认数据已被正确接收。
三,I²C通信流程详解
一次完整的I²C通信包含多个状态和阶段,每个阶段都有明确的时序要求和信号特征。
1. 通信准备与起始条件
通信始于起始条件:SCL保持高电平,SDA从高电平变为低电平。这一特殊转换向所有设备发出信号,表明主设备将开始新的通信,并将总线标记为"忙"状态,防止其他主设备访问总线。
起始条件后,总线上所有从设备都会进入"警戒"模式,准备接收并比对接下来的地址数据。起始条件是所有I²C通信的第一步,表示主设备已获得总线控制权。
2. 从设备寻址
主设备发送7位(或10位)从设备地址,紧跟一个读/写控制位。读/写位为0表示主设备将向从设备写入数据,为1表示主设备请求从从设备读取数据。所有从设备接收并比对此地址,仅地址匹配的从设备继续参与后续通信。
7位地址为I²C协议最常用的寻址方式,支持最多128个设备(实际可用地址更少,因为部分地址被保留为特殊用途)。10位寻址则是对7位寻址的扩展,可支持多达1024个设备。
3. 地址应答
地址传输后,从设备通过发送应答位(ACK)确认接收。如果总线上存在匹配地址的从设备,它会将SDA线拉低一个时钟周期(发送ACK);如果不存在匹配的从设备,SDA线保持高电平(NACK)。
应答机制是I²C协议可靠性的关键,它使主设备能够确认从设备是否存在并响应通信请求。若收到NACK,主设备通常会发送停止条件终止当前通信尝试。
4. 数据传输
地址确认后,主设备和从设备开始根据之前的读/写位进行数据交换。数据以8位字节为单位传输,方向由读/写位决定。每个字节后必须有一个应答位,无论是主设备还是从设备接收数据,接收方都负责提供应答。
在写操作中,主设备发送数据,从设备接收并应答;在读操作中,从设备发送数据,主设备接收并应答。这种双向通信能力使I²C适用于各种传感器和外设交互场景。数据传输可以包含多个字节,没有固定限制。
5. 重复起始条件
在不释放总线的情况下,主设备可以发送新的起始条件,这称为重复起始。这在需要切换通信方向的场景中特别有用,例如先向从设备写入寄存器地址,然后从该寄存器读取数据。重复起始避免了其他主设备在操作中途获取总线控制权。
重复起始与普通起始条件具有相同的时序特征:SCL高,SDA由高变低。区别在于重复起始不需要先发送停止条件,可以在任何字节传输完成后立即发出,维持总线控制权的连续性。
6. 停止条件
通信结束于停止条件:SCL保持高电平,SDA从低电平变为高电平。这一转换表明主设备释放总线,将总线状态恢复为"空闲"。停止条件后,任何主设备都可以通过发送起始条件获取总线控制权。
停止条件是I²C通信完成的标志,它告知所有设备当前通信已完全结束。在复杂的多字节传输操作中,停止条件提供了明确的通信终止点,有助于设备状态机的正确复位。
四,I²C高级机制
除了基本的通信流程,I²C协议还提供了多种高级机制,以支持更复杂的通信需求和解决多种实际问题。
1,总线仲裁
在多主机I²C系统中,可能出现两个或更多主设备同时尝试控制总线的情况。I²C协议通过"线与"特性实现非破坏性仲裁:如果多个主设备同时发送数据,尝试输出"1"但检测到总线为"0"的主设备会识别出冲突,自动释放总线控制权。这种机制确保只有一个主设备能完成通信,而失败的主设备可以稍后重试。
2,时钟同步
当主设备将SCL拉高时,实际上只是释放了SCL线,由上拉电阻使其变为高电平。I²C允许从设备通过将SCL拉低来延长时钟低电平周期,这种机制称为"时钟拉伸"。从设备可以利用这一特性延缓通信,直到准备好处理下一个数据位。这对处理速度较慢的从设备尤为重要,让它们能够与高速主设备匹配工作。
3,多字节寻址
为突破7位寻址的128个设备限制,I²C支持10位寻址模式。10位寻址使用特殊的前缀格式:第一个字节以"11110"开头,后跟10位地址的高2位和读/写位;第二个字节包含10位地址的低8位。这种拓展寻址可支持高达1024个设备,同时与7位寻址设备保持兼容性,两种寻址方式的设备可共存于同一总线。
4,通用调用地址
I²C协议预留了特殊地址0x00作为"通用调用地址"。当主设备向此地址发送数据时,总线上所有从设备都应接收并处理该数据,实现广播功能。通用调用常用于全局复位、同步多个设备行为或同时更新多个设备的配置。通用调用后的第一个数据字节通常包含一个命令码,定义所有从设备应执行的具体操作。
5,高速模式和快速模式+
标准I²C通信速率为100kHz,但现代应用对更高速率有需求。I²C协议定义了多种高速模式:快速模式(400kHz)、快速模式+(1MHz)和高速模式(3.4MHz)。高速模式使用特殊的电平转换器和信号质量控制技术,以确保高频下的信号完整性。使用这些高速模式时,需要特别注意信号电平、上拉电阻值和信号线长度,以避免反射和串扰问题。
6,安全扩展
为满足安全需求,I²C协议添加了加密和认证扩展。I²C加密通常基于现有安全模块和加密芯片,在数据传输层上增加加密功能。这些安全特性对物联网设备、工业控制和安全关键应用尤为重要,能够防止未授权访问和数据篡改。安全扩展包括设备认证、加密数据传输和安全启动等功能。
五,I²C与其他通信协议对比
在嵌入式系统中,常见的几种串行通信协议各有优缺点。了解它们的区别有助于为不同应用场景选择合适的通信方式。
特性 | I²C | SPI | UART |
---|---|---|---|
信号线数量 | 2 (SDA, SCL) | 3+n (MOSI, MISO, SCK, n×SS) | 2 (TX, RX) |
总线拓扑 | 多主多从(共享总线) | 单主多从(每从设备一根SS线) | 点对点(通常为两设备间通信) |
最大设备数 | 理论上128个(7位地址)1024个(10位地址) | 取决于微控制器GPIO数量 | 2(点对点) |
通信速率 | 100kHz(标准)400kHz(快速)1MHz(快速+)3.4MHz(高速) | 可达数十MHz | 通常115.2kbps以下,高速可达几Mbps |
通信方式 | 半双工(双向但不能同时) | 全双工(可同时收发) | 全双工(可同时收发) |
时钟同步 | 同步(由SCL控制) | 同步(由SCK控制) | 异步(需双方约定波特率) |
应答机制 | 有(每字节后ACK/NACK) | 无(需自行实现) | 无(需自行实现) |
总线仲裁 | 支持(多主设备冲突检测) | 不支持 | 不支持 |
主要优势 | 配线简单,支持多设备,内置寻址和应答 | 高速,简单易实现,全双工通信 | 仅需两线,无需时钟线,可远距离通信 |
主要劣势 | 速度相对较慢,实现较复杂 | 需要较多引脚,无标准协议规范 | 无同步机制,速率有限,需额外错误检测 |
六,I²C实际应用示例
I²C协议在各种嵌入式系统中有广泛应用。以下是几个常见的应用场景示例,展示了I²C协议如何在实际项目中发挥作用。
1,温度传感器读取
微控制器通过I²C总线读取温度传感器(如TMP102或LM75)的温度数据。通信流程包括:主设备发送起始条件,发送传感器地址和读操作位,传感器返回温度数据(通常为16位值),最后主设备发送停止条件结束通信。
这种应用充分利用了I²C的简单接口和标准通信流程,使得添加多个类似传感器变得简单高效,只需确保每个传感器具有唯一地址即可。
2,OLED显示屏控制
通过I²C总线控制OLED显示模块(如SSD1306驱动芯片)。主控制器首先发送控制命令设置显示参数(如对比度、翻转等),然后发送图形数据更新显示内容。每次数据传输都伴随应答确认,确保显示正确更新。
OLED显示模块应用展示了I²C协议在大量数据传输场景中的能力,通过简单的两线接口传输大量图形数据,降低了接口复杂度。
3,EEPROM数据存储
使用I²C接口的EEPROM芯片存储配置数据或用户信息。写入操作时,主设备发送起始条件,EEPROM地址,存储单元地址,然后发送要写入的数据;读取操作需要先写入要读取的地址,然后发送重复起始条件,切换到读模式获取数据。
EEPROM应用充分利用了I²C的重复起始特性,允许在不释放总线的情况下从写模式切换到读模式,简化了寄存器访问操作。
4,多传感器系统集成
在一个智能监控系统中,单个I²C总线可连接多个传感器:气压传感器、湿度传感器、光线传感器等。主控制器轮询各传感器获取环境数据,每个传感器具有唯一地址以区分。这种方式大大简化了系统布线复杂度。
多传感器集成是I²C协议最显著的优势应用,通过共享的两线总线连接多种不同类型的传感器,实现系统扩展的同时保持连接简洁。
七,CubeMX配置
1,I2C: 模式选择
I2C 模式选择决定了 STM32 在 I2C 总线上扮演的角色以及基本的工作方式。
1,模式 (Mode)
在 CubeMX 的下拉菜单中选择 I2C 外设的工作模式。
I2C
SMBus Device
SMBus Host
Disabled
I2C: 最常用 标准的 I2C 模式,STM32 可以作为主机 (Master) 或从机 (Slave)。
SMBus Device/Host: 系统管理总线模式,是 I2C 的一个变种,具有更严格的时序和协议要求,例如超时检测、PEC (Packet Error Checking) 等。通常用于电源管理或特定的传感器。
Disabled: 禁用该 I2C 外设。
配置建议: 除非明确需要 SMBus 协议,否则选择 I2C 模式。
2,I2C 速度模式 (I2C Speed Mode)
选择 I2C 总线的最大通信速率。
Standard Mode (标准模式)
Fast Mode (快速模式)
Fast Mode Plus (快速模式+)
Standard Mode: 最高速率 100 kHz。兼容性最好。
Fast Mode: 最高速率 400 kHz。是目前应用最广泛的速度。
Fast Mode Plus: 最高速率 1 MHz。需要外设和 GPIO 都支持 FMP+ 特性(并非所有 STM32 型号都支持)。
说明: 实际通信速率由 "时钟配置" 中的具体设置决定,这里选择的是支持的最高模式。
配置建议: 根据从设备支持的最高速率以及系统需求选择。Fast Mode (400 kHz) 是最常用的选择。
核心选择: 通常情况下,选择 Mode: I2C 和 Speed Mode: Fast Mode 即可满足大部分应用场景。具体的 SCL 时钟频率在 "时钟配置" 中设置。
2,I2C: 时钟配置
配置 I2C 的 SCL 时钟频率和相关的时序参数,直接影响通信速率和稳定性。
1,I2C 时钟速度 (I2C Clock Speed - Hz)
设置 SCL 线上的时钟频率,单位是 Hz。这个值必须小于或等于在 "模式选择" 中设定的 Speed Mode 的上限。
100000 (100 kHz - Standard Mode)
400000 (400 kHz - Fast Mode)
1000000 (1 MHz - Fast Mode Plus)
自定义值
CubeMX 会根据这个目标频率和 I2C 的输入时钟频率 (I2CCLK,通常来自 APB1 时钟) 自动计算所需的时钟控制寄存器 (CCR) 的值。
I2CCLK 频率: I2C 的时钟源频率 (可在 Clock Configuration 标签页查看) 对可配置的 I2C Clock Speed 范围有影响。例如,如果 APB1 频率较低,可能无法达到 400kHz。手册要求 I2CCLK 至少是 Standard Mode 频率的 2 倍,Fast Mode 频率的 3 倍。
2,快速模式占空比 (Clock Duty Cycle - Fast Mode)
仅在选择 Fast Mode 时有效。用于设置 SCL 时钟在高电平和低电平的时间比例。
I2C_DUTYCYCLE_2 (Tlow/Thigh = 2)
I2C_DUTYCYCLE_16_9 (Tlow/Thigh = 16/9)
DUTYCYCLE_2: 低电平时间是高电平时间的 2 倍。这是推荐和常用的设置。
DUTYCYCLE_16_9: 低电平时间是高电平时间的 16/9 倍。在某些特定从设备或总线条件下可能需要。
配置建议: 通常选择 I2C_DUTYCYCLE_2。
3,时序寄存器 (Timing Register - I2C_TIMINGR - 适用于高级型号)
对于一些较新的 STM32 型号 (如 G0, G4, L4, H7 等),不再使用 Clock Speed 和 Duty Cycle 配置,而是直接配置一个 32 位的时序寄存器 I2C_TIMINGR。CubeMX 提供了一个图形化工具或输入框来辅助计算这个值。
你需要输入以下参数,CubeMX 会计算出 TIMINGR 的值:
Timing (期望时钟速度): 例如 400000 Hz。
Rise Time (ns): SCL 和 SDA 信号的上升时间。取决于总线电容和上拉电阻,典型值 100ns (Fast Mode) 或 1000ns (Standard Mode)。
Fall Time (ns): SCL 和 SDA 信号的下降时间。通常较短,典型值 10ns - 300ns。
CubeMX 会根据 I2C 输入时钟频率和这些参数,计算出 TIMINGR 寄存器中的 PRESC, SCLDEL, SDADEL, SCLH, SCLL 字段值。
如果你的 CubeMX 界面是直接配置 TIMINGR 寄存器,请参考 I²C 规范和芯片手册关于时序参数 (tSU;DAT, tHD;STA, tLOW, tHIGH 等) 的要求来设置 Rise Time 和 Fall Time。
配置建议:
设置 I2C Clock Speed 为从设备支持的最大值 (通常 100kHz 或 400kHz)。
如果使用 Fast Mode,Duty Cycle 通常选 DUTYCYCLE_2。
如果配置 TIMINGR,根据 I2C 规范和总线实际情况设置 Rise/Fall Time,然后输入期望的 Clock Speed。
确保 I2C 输入时钟 (I2CCLK) 频率足够高,以支持所需的速度模式。
注意: 不正确的时钟或时序配置会导致通信失败或不稳定。务必检查从设备的数据手册对时序的要求。
3,I2C: 寻址模式
配置 STM32 在 I2C 总线上识别和使用的地址格式。
1,主要寻址模式 (Primary Addressing Mode - Master)
当 STM32 作为 I2C 主机时,它需要知道与之通信的从设备的地址格式。
7-bit address
10-bit address
7-bit address: 最常用 使用 7 位地址来寻址从设备。总线上可以有 128 个唯一地址(排除保留地址后约 112 个)。地址在主机发送的第一个字节的高 7 位 (bit 7:1),bit 0 是读写位 (R/W)。
10-bit address: 使用 10 位地址来寻址从设备。需要发送两个字节来表示地址。用于地址空间需求更大的系统,但兼容性不如 7 位。
说明: 这个设置仅影响主机模式下 HAL 库函数的行为 (例如 HAL_I2C_Master_Transmit 的地址参数处理)。如果需要同时与 7 位和 10 位地址的从设备通信,HAL 库函数通常能根据你传入的地址值自动处理。
配置建议: 通常选择 7-bit address。如果你确定只与 10 位设备通信,可以选择 10-bit。
2,从机地址配置 (Slave Address Settings - Slave Mode)
当 STM32 作为 I2C 从机时,需要配置它在总线上响应的地址。这部分设置在 "Slave Features" 中进行配置。
在此处配置的 "Primary Addressing Mode" 也会影响从机模式下本机地址的解释(是按 7 位还是 10 位格式配置)。
例如:
如果选择 7-bit address 模式,在 Slave Features 中配置的 Own Address 1/2 应为 7 位地址值 (例如 0x3C)。HAL 库会处理地址匹配逻辑。发送到总线时,HAL 库或硬件会自动将其左移一位并加上读写位。
如果选择 10-bit address 模式,在 Slave Features 中配置的 Own Address 1/2 应为 10 位地址值。
核心: I2C 地址是通信的基础。
主机模式下,确保了解从设备的地址格式(7 位还是 10 位)以及具体的地址值。
从机模式下,在 Slave Features 中正确配置本机地址,并确保与主机使用的地址格式一致。
7 位地址是绝对主流,优先考虑使用 7 位地址。
补充: I2C 地址空间中有一些保留地址,如 0x00 (General Call) 和 0x78-0x7B (10 位地址前缀) 等,不应用于普通从设备地址。
4,I2C: 从机特性
当 STM32 配置为 I2C 从机时,需要设置以下参数来定义其行为。
1,本机地址 1 (Primary Slave Address)
设置 STM32 作为从机时响应的第一个 I2C 地址。地址长度(7 位或 10 位)由 "寻址模式" 中的设置决定。
输入值: 直接输入地址值,例如 0x3C (对于 7 位地址)。注意: 这里输入的是 7 位地址本身,不需要左移或添加读写位,CubeMX 和 HAL 库会自动处理。
2,双地址模式 (Dual Address Mode)
Disabled
Enabled
如果启用,STM32 可以响应两个不同的从机地址。
Disabled: 只响应 "本机地址 1"。
Enabled: 同时响应 "本机地址 1" 和 "本机地址 2"。
本机地址 2 (Secondary Slave Address): 仅在启用双地址模式时需要配置,格式与地址 1 相同。
应用场景: 当一个物理设备需要在逻辑上扮演两个不同角色的从设备时。
3,广播呼叫地址检测 (General Call Address Detection)
Disabled
Enabled
I2C 协议定义了一个特殊的地址 0x00 作为广播呼叫地址。主机向该地址发送消息时,总线上所有支持广播呼叫的从机都应该响应(通常用于同时配置或命令多个设备)。
Disabled: STM32 从机忽略发往 0x00 地址的消息。
Enabled: STM32 从机接收并响应发往 0x00 地址的消息。
4,时钟延长 (Clock Stretching)
Enabled
Disabled
时钟延长是 I2C 从设备在需要更多时间处理数据(例如准备发送的数据或存储接收的数据)时,可以将 SCL 线拉低以暂停总线通信的一种机制。
Enabled: 推荐/标准 允许 STM32 从机在必要时拉低 SCL 线。这是符合 I2C 标准的行为,提高了从机处理的可靠性。
Disabled: 禁止 STM32 从机进行时钟延长。如果从机处理速度不够快,可能会导致数据丢失或通信错误。只有在确定主机不支持时钟延长或追求极低延迟且能保证从机处理速度的情况下才考虑禁用。
重要: 大多数情况下应保持 Enabled。禁用时钟延长可能导致难以调试的通信问题。
配置建议 (从机模式):
正确设置 本机地址 1。
按需启用 双地址模式 和 广播呼叫地址检测。
保持 时钟延长 (Clock Stretching) 为 Enabled 状态,除非有特殊理由。
5,I2C: DMA 配置
使用 DMA (Direct Memory Access) 可以在 CPU 不干预的情况下自动传输 I2C 数据,显著提高总线利用率和系统性能,特别是在高速或大数据量传输时。
1,添加 DMA 请求 (Add DMA Request)
在 CubeMX 的 I2C 配置页面下找到 "DMA Settings" 标签页。根据需要,可以为发送 (Tx) 和/或接收 (Rx) 添加 DMA 请求。
点击 "Add" 按钮,选择:
I2Cx_TX: 用于主机发送数据或从机发送数据。
I2Cx_RX: 用于主机接收数据或从机接收数据。
2,DMA 通道配置 (DMA Request Settings)
为每个添加的 DMA 请求 (Tx 或 Rx) 配置参数:
1,Stream/Channel: 选择一个可用的 DMA 通道/流 (CubeMX 通常会自动分配)。
2,Direction: 方向。
I2Cx_TX: Memory To Peripheral
I2Cx_RX: Peripheral To Memory
(由 CubeMX 自动设置)。
3,Priority: DMA 通道优先级 (Low, Medium, High, Very High)。
4,Mode: DMA 传输模式。
Normal: 常用 传输完指定长度的数据后停止。适用于大多数 I2C 传输场景。
Circular: 环形模式。在 I2C 中使用较少,除非有特定的连续流数据处理需求(例如连接到一个持续产生数据的传感器,并且需要环形缓冲)。
5,Increment Address: 地址自增设置。
Peripheral: 不勾选 I2C 数据寄存器 (DR) 地址固定。
Memory: 勾选 内存缓冲区地址需要递增。
6,Data Width: 数据宽度(外设 Peripheral / 内存 Memory)。
推荐配置: Peripheral: Byte, Memory: Byte。
原因: I2C 是基于字节 (8 位) 的串行协议,其数据寄存器 (DR) 每次读写都是一个字节。使用 Byte-Byte 传输可以精确匹配协议,避免数据对齐或截断问题。
配置建议:
对于需要较高传输速率或大数据量(几十字节以上)的 I2C 通信,强烈建议启用 DMA (Tx 和 Rx 都启用)。
Mode 通常设置为 Normal。
Increment Address 勾选 Memory,不勾选 Peripheral。
Data Width 设置为 Peripheral: Byte, Memory: Byte,并使用 uint8_t 类型的 DMA 缓冲区。
使用 DMA 时,通常还需要配合启用 NVIC 中的 DMA 中断来获知传输完成。
HAL 库函数: 启用 DMA 后,应使用带 DMA 的 HAL 函数进行传输,例如: HAL_I2C_Master_Transmit_DMA(), HAL_I2C_Master_Receive_DMA(), HAL_I2C_Slave_Transmit_DMA(), HAL_I2C_Slave_Receive_DMA()。
6,I2C: 中断配置 (NVIC)
I2C 外设可以产生多种中断事件,通知 CPU 传输状态、错误条件或需要处理数据。
1,NVIC 设置 (NVIC Settings)
需要在 CubeMX 的 "NVIC Settings" 标签页中,为对应的 I2C 外设启用中断。通常有两个主要的中断向量:
I2Cx event interrupt (事件中断): 用于处理正常的传输事件,如字节发送/接收完成、地址匹配、传输开始/结束等。
I2Cx error interrupt (错误中断): 用于处理总线错误、仲裁丢失、应答失败 (NACK)、溢出/欠载等异常情况。
Event Interrupt: Enabled
Error Interrupt: Enabled
配置建议:
不使用 DMA,中断驱动模式: 必须启用 Event Interrupt 和 Error Interrupt。
使用 DMA 模式:
推荐启用 Error Interrupt: 用于捕获和处理通信错误。
Event Interrupt 通常可以禁用: 因为传输完成的通知由 DMA 中断处理 (需要在 DMA 配置中启用对应 DMA 通道的中断)。但在某些复杂场景或从机模式下,可能仍需启用 Event Interrupt 来处理特定事件 (如地址匹配)。
中断优先级 (Preemption Priority / Sub Priority): 根据系统需求合理配置,确保实时性要求高的中断具有更高优先级。
2,相关的 HAL 回调函数
启用中断后,HAL 库会在相应事件发生时调用对应的回调函数(弱定义,用户需在自己的代码中重新实现)。
主要回调函数:
主机模式:
HAL_I2C_MasterTxCpltCallback(): 主机发送完成 (中断或 DMA 模式)。
HAL_I2C_MasterRxCpltCallback(): 主机接收完成 (中断或 DMA 模式)。
从机模式:
HAL_I2C_SlaveTxCpltCallback(): 从机发送完成 (中断或 DMA 模式)。
HAL_I2C_SlaveRxCpltCallback(): 从机接收完成 (中断或 DMA 模式)。
HAL_I2C_AddrCallback(): 地址匹配成功 (仅中断模式下,用于判断主机访问意图)。
HAL_I2C_ListenCpltCallback(): 从机停止监听 (例如收到 Stop 信号)。
通用:
HAL_I2C_ErrorCallback(): 发生错误时调用 (例如 NACK, Bus Error)。
HAL_I2C_AbortCpltCallback(): 主动中止传输完成时调用。
(DMA 模式下) HAL_I2C_TxHalfCpltCallback(), HAL_I2C_RxHalfCpltCallback() 等 DMA 半传输回调。
注意: DMA 模式下的传输完成主要通过 DMA 中断触发这些回调,而不是 I2C 的 Event Interrupt。
中断策略:
轮询模式 (不推荐): 不启用任何中断,代码中循环检查状态标志位。效率低下,易阻塞。
中断模式: 启用 Event 和 Error 中断。在回调函数中处理数据收发和状态转换。适用于较低速率或数据量不大的场景。
DMA + 中断模式 (推荐): 启用 Error 中断和对应 DMA 通道中断。使用 DMA 函数启动传输,在 TxCplt/RxCplt 回调中处理完成事件,在 ErrorCallback 中处理异常。效率最高。
7,I2C: GPIO 配置
正确配置 I2C 通信所使用的 SCL (时钟) 和 SDA (数据) 引脚的 GPIO 功能是 I2C 正常工作的基础。
1,引脚选择 (Pin Selection)
在 CubeMX 的 Pinout 视图中,找到要使用的 I2C 外设 (如 I2C1),点击其 SCL 和 SDA 功能,然后在右侧的芯片引脚图中选择具体的物理引脚 (例如 PB6 作为 I2C1_SCL, PB7 作为 I2C1_SDA)。
一个 I2C 功能通常可以映射到多个不同的 GPIO 引脚上,根据 PCB 布局选择合适的引脚。
2,GPIO 配置 (GPIO Settings Tab)
在 CubeMX 的 I2C 配置页面下,切换到 "GPIO Settings" 标签页,可以查看和微调已选定引脚的配置:
1,GPIO Output level: 无需配置 对于 I2C 通常无效,由外设控制。
2,GPIO mode: Alternate Function Open Drain
这是 I2C 协议要求的核心配置。
Alternate Function: 将引脚功能配置为连接到 I2C 外设,而不是通用输入输出。
Open Drain (开漏): 允许多个设备连接到同一总线。设备只能将线拉低,不能主动推高。高电平由外部上拉电阻提供。
3,GPIO Pull-up/Pull-down: Pull-up 或 No pull-up and no pull-down
I2C 协议要求 SCL 和 SDA 必须有上拉电阻。
选项:
Pull-up: 启用 STM32 内部自带的弱上拉电阻 (通常 30kΩ - 50kΩ)。仅适用于低速 (<=100kHz) 且总线负载很小 (设备少、线短) 的情况。
No pull-up and no pull-down: 推荐 禁用内部上拉。此时必须在 PCB 上为 SCL 和 SDA 各添加一个外部上拉电阻。 这是最可靠的做法,允许根据总线速度和电容选择合适的电阻值。
外部上拉电阻选择: 典型值在 1.5kΩ 到 10kΩ 之间。常用 4.7kΩ (适用于 100kHz/400kHz,中等负载)。更高速率或更大总线电容需要更小的上拉电阻 (如 2.2kΩ, 1.8kΩ)。具体计算需参考 I2C 规范和总线电容。
4,Maximum output speed: High 或 Very High
为确保信号边沿足够陡峭以满足 I2C 时序要求(尤其是在 Fast Mode 或更高速度下),应选择较高的 GPIO 输出速度。
5,User Label: (可选) 为引脚添加自定义标签。
关键点:
模式必须是 Alternate Function Open Drain。
必须有上拉电阻! 强烈推荐使用外部上拉电阻 (并在 GPIO 配置中选择 No pull-up/pull-down)。仅在极特殊情况下考虑使用内部上拉。
GPIO 速度应设置为 High 或 Very High。
错误的 GPIO 配置(模式错误、缺少上拉)是 I2C 通信失败的最常见原因之一。