扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

STM32L452 I2C 时钟延展关闭:通信异常解决与 Combined 模式应用

01/27 15:43
542
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

在 STM32L452 作为 I2C 从机的开发场景中,常出现 “与部分主机(如 FPGA)通信异常,与标准设备(如交换机)通信正常” 的问题。核心原因是 I2C 时钟延展功能的兼容性差异 —— 部分主机不支持该功能,导致 SCL 时序采样错误。本文基于 ST 官方 LAT1323 应用笔记,从问题根源、时钟延展关闭配置、OVR 错误解决到实操要点,系统拆解解决方案,助力快速实现稳定通信。

1. 核心问题:时钟延展功能的兼容性冲突

1.1 问题场景与现象

  • 硬件配置:STM32L452 作为 I2C 从机,连接两种主机 —— 交换机(正常通信)、FPGA 测试机(通信异常);
  • 关键现象:FPGA 作为主机时,I2C 波形的第 9 个 SCL 时钟脉宽变窄,且低电平时长变长(周期不变),导致主机固定频率采样 SDA 数据时出错;
  • 初步排查:调整 I2C 的 Data setup time 和 Data hold time,仅能改变整体脉宽,无法解决通信异常。

1.2 根源分析:时钟延展功能的适配差异

  • 时钟延展功能本质:I2C 从机可通过拉低 SCL 信号,请求主机延长时钟周期,为从机处理数据争取时间(默认开启);
  • 冲突核心:FPGA 主机不支持时钟延展功能,未检测 SCL 被拉低的实际电平,仍按固定频率采样,导致数据读取错误;
  • 解决方向:主机端无法修改,需让 STM32L452 从机关闭时钟延展功能,确保 SCL 时序不被主动拉低。

2. 第一步:关闭时钟延展功能的配置方法

关闭时钟延展功能仅需在 I2C 初始化阶段启用 “No Stretch Mode”,操作简洁,步骤如下:

2.1 核心配置逻辑

通过 I2C_CR1 寄存器的 NOSTRETCH 位控制,设置为 1 即可关闭时钟延展(默认 0 为开启)。

2.2 代码配置示例(STM32Cube 库)

// I2C初始化结构体配置
I2C_HandleTypeDef hi2c1;

void MX_I2C1_Init(void) {
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00707CBB; // 按实际需求配置时序
  hi2c1.Init.OwnAddress1 = 0x08;  // 从机地址
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE; // 关闭时钟延展功能
  hi2c1.Init.DigitalFilter = 0;
  hi2c1.Init.AnalogFilter = I2C_ANALOGFILTER_ENABLE;
  
  if (HAL_I2C_Init(&hi2c1) != HAL_OK) {
    Error_Handler();
  }
}

2.3 配置验证

  • 时序变化:SCL 信号不再被从机主动拉低,脉宽稳定,与主机时序匹配;
  • 注意事项:配置后需重新测试通信,若出现多发送 0xFF 的现象,需进一步解决 OVR 错误。

3. 关键问题:关闭时钟延展后的 OVR 错误与解决

关闭时钟延展(NOSTRETCH=1)后,部分场景会出现 “多发送 0xFF” 的异常,本质是Overrun/Underrun(OVR)错误,需针对性解决。

3.1 OVR 错误成因

根据 STM32L452 参考手册,NOSTRETCH=1 时,从机无时钟延展缓冲时间,以下情况会触发 OVR 错误:
  • 接收阶段:新字节接收时,RXDR 寄存器未被读取,新数据丢失,自动返回 NACK;
  • 发送阶段:
    1. STOPF 标志未清除时启动首次数据发送,若 TXDR 寄存器为空则发送 0xFF;
    2. 新字节需发送时,TXDR 寄存器未提前写入数据,触发欠载错误,发送 0xFF。
核心矛盾:从机无法在发送阶段第一个 SCL 脉冲前,提前获知需发送的数据,导致 TXDR 寄存器为空。

3.2 解决方案:Combined 模式提前填充数据

Combined 模式(I2C 组合格式)的核心是 “主机先写命令→从机提前准备数据”,流程如下:

(1)Combined 模式原理

  • 主机通信流程:先发送 “从机地址 + 写命令”(传递数据请求)→ 发送 Repeat Start→ 再发送 “从机地址 + 读命令”→ 接收从机数据;
  • 从机优势:在主机发送 Repeat Start 前(写命令阶段),即可根据接收的命令内容,提前填充 TXDR 寄存器的第一个发送数据,避免发送阶段 TXDR 为空。

(2)实操流程示例(3 字节数据发送)

阶段 主机操作 从机操作
1 发送从机地址 + 写命令(传递数据请求) 接收命令,填充第一个发送数据到 TXDR
2 发送 Repeat Start -
3 发送从机地址 + 读命令 检测到读请求,启动数据发送
4 接收第一个数据(TXDR 中预存) 触发 TXIS 中断,填充第二个数据
5 接收第二个数据 触发 TXIS 中断,填充第三个数据
6 接收第三个数据,发送 NACK+STOP 清除 STOPF 标志,准备下一次通信

(3)关键代码要点

  • 使能 I2C 中断(TXIS、STOPF),在中断中处理数据填充;
  • 写命令阶段接收主机指令后,立即填充首个发送数据;
  • 发送阶段通过 TXIS 中断依次填充后续数据,确保 TXDR 非空。

4. 核心总结:关闭时钟延展的完整落地流程

  1. 配置关闭时钟延展:I2C 初始化时设置NoStretchMode = I2C_NOSTRETCH_ENABLE
  2. 启用 Combined 模式:主机采用 “写命令 + 读数据” 的组合格式,从机提前准备首个数据;
  3. 中断处理优化:使能 TXIS、STOPF 中断,确保发送阶段 TXDR 寄存器持续有有效数据;
  4. 验证时序:通过示波器确认 SCL 脉宽稳定,无异常拉低,数据收发无 0xFF 冗余字节。

5. 避坑关键要点

  • 时钟延展关闭后,从机无缓冲时间,必须提前准备数据,否则必触发 OVR 错误;
  • Combined 模式是解决 OVR 错误的核心,不可直接关闭时钟延展后不调整通信格式;
  • 若主机不支持 Combined 模式,需协调主机端适配,或更换支持时钟延展的主机设备;
  • 中断优先级需合理配置,避免数据填充不及时导致的错误。
STM32L452 I2C 时钟延展功能的关闭,核心是 “配置关闭 + 通信格式适配” 的组合操作。通过本文方案,可解决与不支持时钟延展主机(如 FPGA)的通信兼容性问题,同时避免 OVR 错误导致的异常数据发送,适用于光模块工业传感器等需稳定 I2C 通信的场景。

相关推荐