STM32IIC协议基础及Cube配置
STM32IIC协议基础及Cube配置
- 一,I²C协议简介
- 1,核心特点
- 2,应用场景
- 二,I²C协议基础概念
- 1,总线结构
- 2,主从架构
- 3,设备寻址
- 4,起始和停止条件
- 5,数据传输
- 6,应答机制
- 三,I²C通信流程详解
- 1. 通信准备与起始条件
- 2. 从设备寻址
- 3. 地址应答
- 4. 数据传输
- 5. 重复起始条件
- 6. 停止条件
- 四,I²C高级机制
- 1,总线仲裁
- 2,时钟同步
- 3,多字节寻址
- 4,通用调用地址
- 5,高速模式和快速模式+
- 6,安全扩展
- 五,I²C与其他通信协议对比
- 六,I²C实际应用示例
- 1,温度传感器读取
- 2,OLED显示屏控制
- 3,EEPROM数据存储
- 4,多传感器系统集成
- 七,CubeMX配置
- 1,I2C: 模式选择
- 1,模式 (Mode)
- 2,I2C 速度模式 (I2C Speed Mode)
- 2,I2C: 时钟配置
- 1,I2C 时钟速度 (I2C Clock Speed - Hz)
- 2,快速模式占空比 (Clock Duty Cycle - Fast Mode)
- 3,时序寄存器 (Timing Register - I2C_TIMINGR - 适用于高级型号)
- 3,I2C: 寻址模式
- 1,主要寻址模式 (Primary Addressing Mode - Master)
- 2,从机地址配置 (Slave Address Settings - Slave Mode)
- 4,I2C: 从机特性
- 1,本机地址 1 (Primary Slave Address)
- 2,双地址模式 (Dual Address Mode)
- 3,广播呼叫地址检测 (General Call Address Detection)
- 4,时钟延长 (Clock Stretching)
- 5,I2C: DMA 配置
- 1,添加 DMA 请求 (Add DMA Request)
- 2,DMA 通道配置 (DMA Request Settings)
- 6,I2C: 中断配置 (NVIC)
- 1,NVIC 设置 (NVIC Settings)
- 2,相关的 HAL 回调函数
- 7,I2C: GPIO 配置
- 1,引脚选择 (Pin Selection)
- 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 通信失败的最常见原因之一。
相关文章:
STM32IIC协议基础及Cube配置
STM32IIC协议基础及Cube配置 一,IC协议简介1,核心特点2,应用场景 二,IC协议基础概念1,总线结构2,主从架构3,设备寻址4,起始和停止条件5,数据传输6,应答机制 三…...
Python异常模块和包
异常 当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”, 也就是我们常说的BUG 例如:以r方式打开一个不存在的文件。 f open(‘python1.txt’,‘r’,encoding‘utf-8’) 当我们…...
每日算法刷题Day9 5.17:leetcode定长滑动窗口3道题,用时1h
9. 1652.拆炸弹(简单,学习) 1652. 拆炸弹 - 力扣(LeetCode) 思想 为了获得正确的密码,你需要替换掉每一个数字。所有数字会 同时 被替换。 如果 k > 0 ,将第 i 个数字用 接下来 k 个数字之和替换。如果 k < 0…...
题单:递归求和
宣布一个重要的事情,我的洛谷有个号叫 题目描述 给一个数组 a:a[0],a[1],...,a[n−1]a:a[0],a[1],...,a[n−1] 请用递归的方式出数组的所有数之和。 提示:递推方程 f(x)f(x−1)a[x]f(x)f(x−1)a[x]; 输入格式 第一行一个正整数 n (n≤100)n (n≤100)…...
手动实现 Transformer 模型
本文使用 Pytorch 库手动实现了传统 Transformer 模型中的多头自注意力机制、残差连接和层归一化、前馈层、编码器、解码器等子模块,进而实现了对 Transformer 模型的构建。 """ Title: 解析 Transformer Time: 2025/5/10 Author: Michael Jie &quo…...
【鸿蒙开发避坑】使用全局状态变量控制动画时,动画异常甚至动画方向与预期相反的原因分析以及解决方案
【鸿蒙开发避坑】使用全局状态变量控制动画,动画异常甚至动画方向相反的原因分析以及解决方案 一、问题复现1、问题描述2、问题示意图 二、原因深度解析1、查看文档2、调试3、原因总结:(1)第一次进入播放页面功能一切正常的原因&a…...
天拓四方锂电池卷绕机 PLC 物联网解决方案
近年来,锂电制造行业作为新能源领域的核心支柱产业,呈现出迅猛发展的态势,市场需求持续高涨。在此背景下,行业内对产品质量、生产效率以及成本控制等方面提出了更为严苛的要求。锂电制造流程涵盖混料、涂布、辊压、分切、制片、卷…...
RFID系统:技术解析与应用全景
一、技术架构与运行逻辑 RFID(Radio Frequency Identification)系统通过无线电波实现非接触式数据交互,其核心由三部分组成: 电子标签(Tag): 无源标签:依赖读写器电磁场供电&…...
hbuilderX 安装Prettier格式化代码
一、打开插件安装 搜索输入:Prettier 安装后,重启hbuilderX ,再按AltShiftF 没安装Prettier格式化: import {saveFlow,getTemplate } from "../../api/flowTemplate.js"; 安装Prettier格式化后: import …...
Python-92:最大乘积区间问题
问题描述 小R手上有一个长度为 n 的数组 (n > 0),数组中的元素分别来自集合 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]。小R想从这个数组中选取一段连续的区间,得到可能的最大乘积。 你需要帮助小R找到最大乘积的区间,并输出这…...
Compose笔记(二十三)--多点触控
这一节主要了解一下Compose中多点触控,在Jetpack Compose 中,多点触控处理需要结合Modifier和手势API来实现,一般通过组合 pointerInput、TransformableState 和 TransformModifier 来创建支持缩放、旋转和平移的组件。 一、 API 1. Pointer…...
2025.05.17淘天机考笔试真题第一题
📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 01. 魔法棋盘构造 问题描述 LYA 正在设计一款魔法棋盘游戏。游戏棋盘由 2 n 2 \times n...
python的漫画网站管理系统
目录 技术栈介绍具体实现截图系统设计研究方法:设计步骤设计流程核…...
系统架构设计(十):结构化编程
定义 结构化编程是一种遵循清晰逻辑结构、避免使用 goto 的编程方法。它强调使用有限的三种基本控制结构来组织程序,提高程序的可读性、可维护性和可测试性。 它是现代程序设计的基础,被广泛应用于命令式语言(如 C、Pascal、Java࿰…...
系统架构设计(七):数据流图
定义 数据流图(Data Flow Diagram, DFD)是一种用于表示信息系统数据流转及处理过程的图形工具。 它反映系统功能及数据之间的关系,是结构化分析与设计的重要工具。 主要符号 符号说明描述举例方框外部实体(源或终点)…...
BrepGen中的几何特征组装与文件保存详解 deepwiki occwl OCC包装库
有这种好东西我怎么不知道 AutodeskAILab/occwl: Lightweight Pythonic wrapper around pythonocc 组装几何特征以创建B-rep模型 保存为STEP和STL文件细说 Fast 快速 Searched across samxuxiang/BrepGen Ill explain how BrepGen assembles geometric features to create B-r…...
QT6 源(105)篇二:阅读与注释 QAction,给出源代码
(5)本源代码来自于头文件 qaction . h : #ifndef QACTION_H #define QACTION_H#include <QtGui/qtguiglobal.h> #if QT_CONFIG(shortcut) # include <QtGui/qkeysequence.h> #endif #include <QtGui/qicon.h> #include &…...
复旦微FMQL调试笔记:PS网口
引言 FPGA,全程现场可编程门阵列,是指一切通过软件手段更改、配置器件内部连接结构和逻辑单元,完成既定设计功能的数字集成电路。换个简单通俗的介绍方式,就好比一个全能的运动员,FPGA就是这么神奇的可以通过设定而实…...
SpringBoot启动流程深入分析
文章目录 背景启动流程listeners.starting先获取运行监听器获取SpringApplicationRunListener的实例监听器接口从spring.factories中加载数据,这里有本地缓存监听启动发布starting事件 prepareEnvironment准备环境获取或创建环境配置环境 createApplicationContext创…...
Linux - 2.系统命令
1.帮助命令 1.help [root@localhost /]# cp --help1.查看命令的信息和参数2.只能显示shell内部的命令信息3.help命令第一部分是概述,第二部分是参数详解,第三部分是说明和注意 # 使用语法 Usage: cp [OPTION]... [-T] SOURCE DESTor: cp [OPTION]... SOURCE... DIRECTORYor:…...
CSP 2024 提高级第一轮(CSP-S 2024)单选题解析
单选题解析 第 1 题 在 Linux 系统中,如果你想显示当前工作目录的路径,应该使用哪个命令?(A) A. pwd B. cd C. ls D. echo 解析:Linux 系统中,pwd命令可以显示当前工作目录的路径。pwd&#x…...
JavaScript运算符
在JavaScript开发中,运算符是编程的基础工具。它们用于执行各种操作,从简单的数学计算到复杂的逻辑判断。本文将深入探讨JavaScript中的各种运算符,包括算术运算符、比较运算符、布尔运算符、位运算符以及其他一些特殊运算符。 一、算术运算…...
无线信道的噪声与干扰
目录 1. 无线信道(wireless channel)与电磁波 2.1 电磁波的传输(无线信道传输) 2.2 视线(line of sight)传播与天线高度 2. 信道的数学模型 2.1 调制信道模型 2.1.1 加性噪声/加性干扰 2.1.2 乘性噪声/乘性干扰 2.1.3 随参信道/恒参信道 2.2 编码信道模型 2.3 小结 …...
计算机视觉与深度学习 | Python实现EMD-CNN-LSTM时间序列预测(完整源码、数据、公式)
EMD-CNN-LSTM 1. 环境准备2. 数据生成(示例数据)3. EMD分解4. 数据预处理5. CNN-LSTM模型定义6. 模型训练7. 预测与重构8. 性能评估核心公式说明1. 经验模态分解(EMD)2. CNN-LSTM混合模型参数调优建议扩展方向典型输出示例以下是使用Python实现EMD-CNN-LSTM时间序列预测的完…...
基于Yolov8+PyQT的老人摔倒识别系统源码
概述 随着人工智能技术的普及,计算机视觉在安防领域的应用日益广泛。幽络源本次分享的基于Yolov8PyQT的老人摔倒识别系统,正是针对独居老人安全监护的实用解决方案。该系统通过深度学习算法实时检测人体姿态,精准识别站立、摔倒中等…...
【网络入侵检测】基于Suricata源码分析运行模式(Runmode)
【作者主页】只道当时是寻常 【专栏介绍】Suricata入侵检测。专注网络、主机安全,欢迎关注与评论。 1. 概要 👋 在 Suricata 中抽象出线程、线程模块和队列三个概念:线程类似进程,可多线程并行执行操作;监听、解码、检…...
深入解析:java.sql.SQLException: No operations allowed after statement closed 报错
在 Java 应用程序开发过程中,尤其是涉及数据库交互时,开发者常常会遇到各种各样的异常。其中,java.sql.SQLException: No operations allowed after statement closed是一个较为常见且容易令人困惑的错误。本文将深入剖析这一报错,…...
ARM-Linux 完全入门
1.准备部分 1.1 虚拟机安装 准备VMware软件、ubuntu系统镜像安装过程 VMware安装 破解(自己百度破解码,多试几个网址,会有能用的)Ubuntu安装 配置联网 桥接 虚拟机Ubuntu系统必须能连接到外网,不然不能更新软件安装…...
前端二进制数据指南:从 ArrayBuffer 到高级流处理
前端开发中,二进制数据是处理文件、图像、音视频、网络通信等场景的基础。以下是核心概念和用途的通俗解释: 前端二进制数据介绍 1. 什么是前端二进制数据? 指计算机原始的 0 和 1 格式的数据(比如一张图片的底层代码ÿ…...
深入理解构造函数,析构函数
目录 1.引言 2.构造函数 1.概念 2.特性 3.析构函数 1.概念 2.特性 1.引言 如果一个类中什么都没有,叫作空类. class A {}; 那么我们这个类中真的是什么都没有吗?其实不是,如果我们类当中上面都不写.编译器会生成6个默认的成员函数。 默认成员函数:用户没有显…...
数值分析知识重构
数值分析知识重构 一 Question 请构造一下数值分析中的误差概念以及每一个具体数值方法的误差是如何估计的? 二 Question 已知 n 1 n1 n1个数据点 ( x i , y i ) , i 0 , 1 , ⋯ , n (x_i,y_i),i0,1,\cdots,n (xi,yi),i0,1,⋯,n,请使用多种方法建立数据之间…...
全端同步!ZKmall开源商城如何用B2B2C模板让消费者跨设备购物体验无缝衔接?
在数字化浪潮席卷下,消费者的购物行为不再局限于单一设备。早晨用手机小程序浏览商品,中午在 PC 端对比参数,晚上通过平板下单,跨设备购物已成常态。然而,设备间数据不同步、操作体验割裂等问题,严重影响购…...
Redis Sentinel如何实现高可用?
Redis Sentinel 通过以下核心机制实现高可用: 1. 监控(Monitoring) Sentinel 集群会持续监控主节点(Master)和从节点(Slave)的状态: 定期发送 PING 命令检测节点是否存活…...
环形缓冲区 ring buffer 概述
环形缓冲区 ring buffer 概述 1. 简介 环形缓冲区(ring buffer),是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流。也称作环形缓冲区(circular buffer),环形队列&…...
Spring源码之解决循环依赖 三级缓存
目录 三级缓存核心原理 循环依赖的解决过程 1. Bean A创建过程中提前曝光工厂 2. Bean B创建时发现依赖A,从缓存获取 3. Bean A继续完成初始化 三级缓存的作用总结 二级缓存为何不够解决缓存依赖? 三级缓存如何解决? 为什么不直接在…...
山东大学计算机图形学期末复习9——CG12上
CG12上 几何管线末端:顶点已组装成基本图元(Primitives,如点、线、三角形)。 主要任务: 裁剪:视锥体是一个三维空间区域(由近裁剪面、远裁剪面和侧面组成),超出该区域的图…...
关于软件测试开发的一些有趣的知识
文章目录 一、什么是测试?二、为什么要软件测试软件测试三、测试的岗位有哪些四 、软件测试和开发的区别五、走测试岗位为什么还要学开发。4、优秀的测试人员具备的素质我为什么走测试岗位 一、什么是测试? 其实这个问题说简单也不简单,说难…...
在Solana上使用 Scaled UI Amount 扩展
本指南提供 Solana Web3.js (Legacy v 1.x) 和 Solana Kit (v 2.x) 版本。选择适当的选项卡以查看你首选库的代码片段和说明: Solana Web3.js (Legacy)Solana Kit 概述 Solana Token-2022 程序 引入了强大的扩展,增强了代币功能,使其超越了…...
线性表之数组与栈详解
线性表之数组与栈详解 前言一、数组(Array)1.1 数组的基本概念1.2 数组的实现与操作1.3 数组的应用场景1.4 数组的优缺点 二、栈(Stack)2.1 栈的基本概念2.2 栈的实现方式2.3 栈的应用场景 2.4 栈的优缺点 三、数组与栈的对比总结…...
车载以太网驱动智能化:域控架构设计与开发实践
title: 车载以太网驱动专用车智能化:域控架构设计与开发实践 date: 2023-12-01 categories: 新能源汽车 tags: [车载以太网, 电子电气架构, 域控架构, 专用车智能化, SOME/IP, AUTOSAR] 引言:专用车智能化转型的挑战与机遇 专用车作为城市建设与工业运输…...
【Redis】redis用作缓存和分布式锁
文章目录 1. 缓存1.1 Redis作为缓存1.2 缓存更新、淘汰策略1.3 缓存预热、缓存穿透、缓存雪崩和缓存击穿1.3.1 缓存预热(preheating)1.3.2 缓存穿透(penetration)1.3.3 缓存雪崩(avalanche)1.3.4 缓存击穿&…...
深度学习中独热编码(One-Hot Encoding)
文章目录 独热编码独热编码的作用独热编码的优点独热编码的缺点场景选择独热编码(PyTorch实现)替代方案 实际使用分析:对对象类型使用独热编码为什么使用独热编码是合适的?📌 场景说明:📌 为什么…...
如何根据竞价数据判断竞价强度,是否抢筹等
竞价强度判断方法 价格变化幅度 观察开盘价与前一交易日收盘价的差距 :如果一只股票在开盘集合竞价阶段价格大幅高于前一交易日收盘价,说明市场对该股票的预期较为积极,可能有资金在主动抬高价格,这是一种较强的竞价强度表现。例如…...
Codex与LangChain结合的智能代理架构:重塑软件开发的未来
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言:当代码生成遇见智能决策 想象以下场景: 凌晨三点:你需要紧急修复一个遗留系统的内存泄漏漏洞,但代码注释缺失且逻辑复杂; 产品经理需求变更:要求在24小时内将现有…...
2025年PMP 学习十八 第11章 项目风险管理 (11.5~11.7)
2025年PMP 学习十八 第11章 项目风险管理 (11.5~11.7) 第11章 项目风险管理 序号过程过程组1规划风险管理规划2识别风险规划3实施定性风险分析规划4实施定量风险分析规划5规划风险应对执行6实施风险应对执行7监控风险监控 文章目录 2025年PMP 学习十八…...
2025年PMP 学习十七 第11章 项目风险管理 (11.1~11.4)
2025年PMP 学习十七 第11章 项目风险管理 (11.1~11.4) 第11章 项目风险管理 序号过程过程组1规划风险管理规划2识别风险规划3实施定性风险分析规划4实施定量风险分析规划5规划风险应对执行6实施风险应对执行7监控风险监控 文章目录 2025年PMP 学习十七…...
impala
Impala,它是 Cloudera 开发的开源 实时 SQL 查询引擎,专为 Hadoop 设计。与 Presto 类似,Impala 用于交互式分析,但架构和设计理念有所不同。以下是 Impala 的核心特点和工作原理: 一、Impala 核心架构 1. 组件组成 …...
湖北理元理律师事务所:债务优化中的双维支持实践解析
在债务压力与生活质量失衡的社会议题下,法律服务机构的功能边界正在从单一的法律咨询向复合型支持延伸。湖北理元理律师事务所通过“法律心理”双维服务模式,探索债务优化与生活保障的平衡路径,其方法论或为行业提供实践参考。 法律框架&…...
Redis设计与实现——Redis命令参考与高级特性
Redis命令参考 数据类型相关命令 SET:设置键值,支持过期时间、不存在/存在条件。GET:获取键值,若键不存在返回 nil。INCR/DECR:将键的整数值增1/减1,键不存在时初始化为0。MSET/MGET:批量设置…...
TCP/UDP协议原理和区别 笔记
从简单到难吧 区别就是TCP一般用于安全稳定的需求,UDP一般用于不那么需要完全数据的需求,比如说直播,视频等。 再然后就是TPC性能慢于UDP。 再然后我们看TCP的原理(三次握手,数据传输,四次挥手࿰…...