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

STM32L432基于HAL库的I2C DMA传输SSD1306数据失败

问题根因与修复方案

核心问题定位

你遇到的传输出截断、仅能显示约254字节内容的现象,本质是手动改写中断逻辑打断了HAL库本身的I2C-DMA同步状态机,结合STM32L4系列I2C外设的硬件特性,具体存在三个叠加故障点:

  • STM32L4的I2C外设在单次连续发送超过255字节时,硬件会自动触发TCR(传输重载)中断,此时需要重新配置后续传输长度才能继续发送。你在中断里遇到TCR就直接手动发STOP、关DMA通道,相当于第一次触发重载时就把整个传输硬掐断,刚好卡在250余字节的位置。
  • 你在DMA传输完成中断里提前手动关闭DMA通道,没有等I2C外设把TXDR寄存器里剩余的移位数据完全发送出去,导致总线状态错位,后续传输无法正常推进。
  • 你把CubeMX默认生成的HAL_I2C_EV_IRQHandler注释掉了,相当于失去了HAL层对I2C传输状态的维护,所有外设状态判断都失去了可靠依据。

具体修复步骤

1. 恢复标准中断处理逻辑

把你手动添加的寄存器操作全部从中断函数里移除,还原CubeMX生成的标准处理流程:

I2C1事件中断

删除所有手动操作寄存器的代码,取消HAL中断处理函数的注释:

void I2C1_EV_IRQHandler(void)
{
  HAL_I2C_EV_IRQHandler(&hi2c1);
}

DMA1通道6中断

删除手动关DMA、清标志位的冗余代码,只保留标准DMA回调:

void DMA1_Channel6_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_i2c1_tx);
}

2. 核对DMA配置参数

在CubeMX的I2C TX DMA配置里确认以下参数无偏差,避免传输错位:

  • 传输方向:内存指向外设
  • 内存数据宽度:字节
  • 外设数据宽度:字节
  • 内存地址增量:使能
  • 外设地址增量:关闭
  • 传输模式:普通(非循环)
  • 通道优先级:高

3. 保留原有发送逻辑即可

HAL_I2C_Mem_Write_DMA本身原生支持超过255字节的长传输:

  • HAL库已经内置了对STM32L4 I2C硬件TCR中断的处理逻辑,会自动拆分长传输块、衔接重载流程,直到1024字节全部发送完成后,才会自动触发STOP条件、释放I2C总线
  • 你原有的发送缓冲区判断逻辑while(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)完全可以正常使用,不需要额外加延时或手动做时序同步

常见踩坑提醒

  • 不要自行手动操作I2C的CR2寄存器发送STOP,HAL会根据传输进度自动发送,提前发STOP会直接截断未发送完成的缓冲区内容
  • 不要在DMA中断里手动关闭DMA通道,HAL的DMA回调流程会和I2C状态机严格同步完成通道关闭,提前关通道会导致I2C外设等待DMA送数、总线挂死
  • 不需要为I2C和DMA的中断做特殊优先级配置,只要两者的中断优先级不高于系统滴答定时器、不产生异常嵌套即可正常运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 03:45:04