You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F103C8用Embassy与24C16N EEPROM通信失败但stm32f1xx_hal正常

排查Embassy与24C16N EEPROM通信失败的关键点

1. 核对I2C时钟与时序配置差异

stm32f1xx_hal的阻塞I2C可能默认适配了24C16N的时序,而Embassy的默认配置可能存在偏差:

  • 24C16N支持的最高I2C时钟为100kHz(标准模式),部分场景下400kHz快速模式也可工作,但需严格匹配时序参数。
  • Embassy初始化I2C时,需显式指定时钟速率和占空比,示例:
let i2c = embassy_stm32::i2c::I2c::new(
    peripherals.I2C1,
    scl,
    sda,
    embassy_stm32::i2c::Config::default()
        .frequency(100_000.Hz())
        .duty_cycle(embassy_stm32::i2c::DutyCycle::Ratio2to1), // 标准模式常用2:1占空比
);
  • 检查HAL中I2C的时钟源(如APB1时钟频率),确认Embassy的系统时钟配置与HAL一致,外设时钟错误会直接导致通信失败。

2. 确认引脚模式配置

STM32F1的I2C引脚需配置为开漏输出+上拉(硬件上拉或内部上拉):

  • stm32f1xx_hal可能自动将引脚设置为OpenDrain模式,而Embassy需要显式指定:
let scl = peripherals.PB6.into_open_drain_output();
let sda = peripherals.PB7.into_open_drain_output();
  • 若依赖内部上拉,需在引脚配置中添加pull_up():
let scl = peripherals.PB6.into_open_drain_output().pull_up();
let sda = peripherals.PB7.into_open_drain_output().pull_up();

3. 检查设备地址的处理方式

24C16N的设备地址格式为1010 A2 A1 A0 R/W,注意不同框架的地址处理差异:

  • stm32f1xx_hal和Embassy均要求传入7位地址(不含R/W位),驱动会自动添加读写位。例如A2/A1/A0均为0时,正确的7位地址是0b1010000(十进制80),不要错误传入包含R/W位的8位地址。

4. 验证Embassy阻塞API的调度器初始化

使用Embassy的阻塞I2C API时,必须确保调度器已正确初始化:

  • 需在代码开头初始化Embassy执行器,示例:
#[embassy_executor::main]
async fn main(spawner: embassy_executor::Spawner) {
    let p = embassy_stm32::init(Default::default());
    // 后续I2C初始化与操作代码
}
  • 未初始化调度器会导致阻塞API因无法获取执行权而超时。

5. 排查Embassy STM32F1 I2C驱动的硬件初始化

部分版本的Embassy对STM32F1的I2C外设初始化可能存在遗漏:

  • 确认I2C外设时钟已开启(Embassy的I2c::new通常会自动处理,但可通过寄存器RCC->APB1ENR手动验证);
  • 尝试更新Embassy到最新稳定版,修复已知的驱动bug。

6. 抓波形对比HAL与Embassy的通信差异

用逻辑分析仪抓取两种方案下的I2C波形:

  • 对比起始信号、地址帧、ACK信号的差异;
  • 若Embassy发出起始信号后无ACK,说明设备未响应,大概率是地址或时序问题;
  • 若波形无起始信号,说明I2C外设未正确初始化。

内容的提问来源于stack exchange,提问作者MrPashaPG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:29:57