带有 DMA 的 STM32 I2C 传输已完成,但 DMA 中断程序不工作
Posted
技术标签:
【中文标题】带有 DMA 的 STM32 I2C 传输已完成,但 DMA 中断程序不工作【英文标题】:STM32 I2C Transfer with DMA completed but DMA interrupt routine is not work 【发布时间】:2021-10-31 18:30:15 【问题描述】:我使用 HAL 库处理带有 DMA 的基本 i2c 示例。当我在调试部分观察到数据读取正确但 DMA 没有上升标志 TCIF(传输完成标志)时。可能是什么原因?
// INTERRUPT ROUTINE
void DMA1_Channel1_IRQHandler(void)
if(__HAL_DMA_GET_FLAG(&hdma_i2c2_rx,DMA_FLAG_TC1))
HAL_GPIO_TogglePin(LED_COM_BLUE_GPIO_Port, LED_COM_BLUE_Pin);
sprintf(prnt, "Id:%.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\r", Id[7], Id[6],
Id[5], Id[4], Id[3], Id[2], Id[1], Id[0]);
HAL_UART_Transmit(&huart1, (uint8_t*) prnt, strlen(prnt), 1000);
__HAL_DMA_CLEAR_FLAG(&hdma_i2c2_rx,DMA_FLAG_TC1);
【问题讨论】:
【参考方案1】:如果你想使用 HAL,你应该让 HAL 处理 IRQ 并且只使用预定义的回调。
在 'stm32fyxx_hal_i2c.h' 中寻找它们:
/******* I2C IRQHandler and Callbacks used in non blocking modes
(Interrupt and DMA) */
void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c);
void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode);
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
如果你不使用 CubeMX,一定要检查 'stm32fyxx_it.c',你应该有类似的东西:
void I2Cx_EV_IRQHandler(void)
HAL_I2C_EV_IRQHandler(&I2cHandle);
/**
* @brief This function handles I2C error interrupt request.
* @param None
* @retval None
* @Note This function is redefined in "main.h" and related to I2C error
*/
void I2Cx_ER_IRQHandler(void)
HAL_I2C_ER_IRQHandler(&I2cHandle);
/**
* @brief This function handles DMA interrupt request.
* @param None
* @retval None
* @Note This function is redefined in "main.h" and related to DMA stream
* used for I2C data transmission
*/
void I2Cx_DMA_RX_IRQHandler(void)
HAL_DMA_IRQHandler(I2cHandle.hdmarx);
/**
* @brief This function handles DMA interrupt request.
* @param None
* @retval None
* @Note This function is redefined in "main.h" and related to DMA stream
* used for I2C data reception
*/
void I2Cx_DMA_TX_IRQHandler(void)
HAL_DMA_IRQHandler(I2cHandle.hdmatx);
如果不这样做,请检查 CubeMX 中针对 I2C 和 DMA 的所有 NVIC 选项,它将创建这些行,然后回调函数应该可以工作。
如果您想使用这些“低级”标志,我建议您不要使用 HAL 以确保完全控制它们。
您也可以使用 LL(低级)库。
【讨论】:
以上是关于带有 DMA 的 STM32 I2C 传输已完成,但 DMA 中断程序不工作的主要内容,如果未能解决你的问题,请参考以下文章