一.关于I2C使用DMA传输数据,DMA已经开启,但是发送数据存在问题,回调函数进不去。


二.调试打断点,发现中断进不去


三.换用轮询就可以执行

四.原因:未启用event事件中断

以你调用的 HAL_I2C_Master_Transmit_DMA 为例,整个流程是这样的:
启动传输:你调用 HAL_I2C_Master_Transmit_DMA,这个函数会启动DMA,并触发I2C外设产生一个"起始条件已发送"的中断事件。
事件中断处理:当这个中断事件发生时,必须有一个中断服务函数(ISR)来处理它。这个ISR就是 I2C1_EV_IRQHandler(名字可能因MCU系列略有不同)。而在这个ISR内部,必须调用 HAL_I2C_EV_IRQHandler 函数。
内部状态机运转:HAL_I2C_EV_IRQHandler 内部实现了一个状态机。它会检查当前发生了什么事件(是起始条件?还是地址已发送?还是数据已发完?),然后执行对应的硬件操作(比如,将设备地址写入数据寄存器、读取状态寄存器来清除标志位等)。
最终回调:当整个传输过程结束,包括最后一个数据字节也已由DMA搬运完成,并且I2C总线的停止条件也成功发送后,I2C_EV_IRQHandler内部的状态机才会最终调用你的用户回调函数HAL_I2C_MasterTxCpltCallback。此时,你的g_I2C1_TxCplt` 标志才会被置1。

五.总结
| 传输函数 | 是否需要I2C事件中断 | 说明 |
|---|---|---|
HAL_I2C_Master_Transmit (阻塞) |
不需要 | 函数内部用循环等待标志位,CPU全程占用,不产生中断 |
HAL_I2C_Master_Transmit_IT (中断) |
必须开启 | 传输过程靠中断驱动,必须使能 I2C1_EV_IRQn |
HAL_I2C_Master_Transmit_DMA (DMA) |
必须开启 | 虽然数据由DMA搬运,但协议状态机仍靠中断驱动,必须使能 I2C1_EV_IRQn |