[STM32L4] UART2通信中数据传输完成后中断回调函数未被调用

[复制链接]
395|19
内核558 发表于 2025-9-26 02:23 | 显示全部楼层 |阅读模式
我使用STM32CubeIDE中的STM32L451RCTx。项目中需要通过usart2对接收到的请求进行响应。我能够一次性接收请求并成功响应,但在响应传输完成后,无法再次接收请求。当usart线路上收到数据时,usart2接收中断未被触发。

--> 初始化部分如下:
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
  Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
if(HAL_UART_Receive_IT(&huart2, &uart2_buffer_u8, 1))
{
Error_Handler();
}
/* USER CODE END USART2_Init 2 */
}
--> In Interrupt handler side,
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
CLEAR_BIT(huart2.Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
CLEAR_BIT(huart2.Instance->CR3, USART_CR3_EIE);
/* Rx process is completed, restore huart->RxState to Ready */
huart2.RxState = HAL_UART_STATE_READY;
/* Clear RxISR function pointer */
huart2.RxISR = NULL;
uint8_t status = 0;
status = HAL_UART_Receive_IT(&huart2, &uart2_buffer_u8, 1);
if (status || huart2.ErrorCode != 0 || huart2.ErrorCode != 34) {
/* error handler */
/* Re-Initialize to avoid missing of messages */
status = HAL_UART_Receive_IT(&huart2, &uart2_buffer_u8, 1);
if (status) {
/* error handler */
}
}
//USART_ClearITPendingBit(&huart2,USART_IT_TC);
/* USER CODE END USART2_IRQn 1 */
}
--> Interrupt Call back function
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if(huart->Instance == USART2)
{
mgmtLocalRx = uart2_buffer_u8;
if ((mgmtLocalRx == FRAMEHEAD) && (mgmtBMS_RxCounter != 0)) {
mgmtBMS_RxCounter = 0;
mgmtBMS_Rx_Buffer[mgmtBMS_RxCounter++] = mgmtLocalRx;
}

else if ((mgmtLocalRx == FRAMEHEAD) && (mgmtBMS_RxCounter == 0)) {
mgmtBMS_Rx_Buffer[mgmtBMS_RxCounter++] = mgmtLocalRx;
}
else if ((mgmtBMS_RxCounter < 5) && (mgmtBMS_RxCounter != 0)){
mgmtBMS_Rx_Buffer[mgmtBMS_RxCounter++] = mgmtLocalRx;

}
else if ((mgmtLocalRx == FRAMEEND) && (mgmtBMS_RxCounter >= 5)){
mgmtBMS_Rx_Buffer[mgmtBMS_RxCounter++] = mgmtLocalRx;
uartRxSection = true;
mgmtBMS_RxCounter = 0;
}
}
}

公羊子丹 发表于 2025-9-26 07:23 | 显示全部楼层
看代码里你在USART2_IRQHandler里面手动清了好多位,怀疑就是这里把HAL的接收流程给破坏了。
周半梅 发表于 2025-9-26 07:23 | 显示全部楼层
HAL库本来在HAL_UART_IRQHandler里会自动调用回调,你再去清CR1和CR3有点多余了。
帛灿灿 发表于 2025-9-26 07:24 | 显示全部楼层
你试过只在初始化里调用一次HAL_UART_Receive_IT,然后完全交给回调里重新启动吗?
童雨竹 发表于 2025-9-26 07:25 | 显示全部楼层
我感觉你在IRQHandler里又去调用HAL_UART_Receive_IT,这样可能会和HAL的状态机冲突。
万图 发表于 2025-9-26 07:26 | 显示全部楼层
建议用HAL_UART_Transmit_IT或者DMA方式发数据,发送完成后在TxCpltCallback里再开接收。
Wordsworth 发表于 2025-9-26 07:28 | 显示全部楼层
你把huart2.RxISR = NULL清掉,这样HAL库就再也不知道该走哪个接收函数了。
Bblythe 发表于 2025-9-26 07:29 | 显示全部楼层
简单点,别改动IRQHandler,保持Cube自动生成的默认结构,很多时候问题就没了。
Pulitzer 发表于 2025-9-26 07:30 | 显示全部楼层
也可以考虑用HAL_UARTEx_ReceiveToIdle_IT,这样不会因为帧结束收不到中断。
Uriah 发表于 2025-9-26 07:31 | 显示全部楼层
我之前在L4上也遇到过类似问题,最后发现是因为ErrorCode没有清干净,导致中断屏蔽了。
Clyde011 发表于 2025-9-26 07:32 | 显示全部楼层
建议你把接收逻辑搬到HAL_UART_RxCpltCallback里,然后里面最后一句再HAL_UART_Receive_IT,就能一直循环收数据了。
豌豆爹 发表于 2025-9-26 15:38 | 显示全部楼层
中断处理错了吧。。
classroom 发表于 2025-9-26 16:39 | 显示全部楼层
在中断处理中强制修改huart2.RxState和RxISR,干扰了HAL库的正常状态机。
cr315 发表于 2025-9-26 17:40 | 显示全部楼层
重复初始化?
duo点 发表于 2025-9-26 18:40 | 显示全部楼层
删除手动禁用中断的代码,让HAL_UART_IRQHandler()自动管理中断标志和状态
onlycook 发表于 2025-9-26 19:41 | 显示全部楼层
避免在回调中直接重新初始化接收,而是通过主循环或标志位触发。
powerantone 发表于 2025-9-26 20:42 | 显示全部楼层
在main()的主循环中,通过标志位或直接调用HAL_UART_Receive_IT()。
probedog 发表于 2025-9-26 21:44 | 显示全部楼层
不要直接操作CR1、CR3或RxState,HAL库已自动处理。
stormwind123 发表于 2025-9-26 22:44 | 显示全部楼层
估计是因为手动禁用中断和错误的状态管理导致接收中断无法重新触发。
内政奇才 发表于 2025-9-26 22:05 | 显示全部楼层
建议用双缓冲或DMA接收。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

50

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部