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

HAL_UART_Receive_IT仅触发一次的STM32与ESP8266串口通信问题

问题分析与解决方案

核心问题:接收缓冲区越界导致内存破坏

你代码中HAL_UART_Receive_IT(&huart1, &rx_data, 5);的rx_data应为单个字节变量(从代码传递方式推断),却要求接收5字节数据,这会直接引发内存溢出,破坏UART外设的状态结构体或其他内存区域,最终导致后续接收中断无法正常触发,因此只能接收一次数据。

具体修复步骤

1. 定义正确的接收缓冲区

在全局或具有足够生命周期的局部作用域中,定义可容纳5字节数据+1字节字符串结束符的缓冲区:

uint8_t rx_data[6] = {0}; // 预留1字节用于存储'\0',保证字符串打印正常

2. 修正接收中断的调用逻辑

初始化和回调函数中统一使用上述缓冲区:

// main函数中初始化接收中断
HAL_UART_Receive_IT(&huart1, rx_data, 5);

// 回调函数修改
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart == &huart1) {
        rx_data[5] = '\0'; // 手动添加字符串结束符,避免printf输出乱码
        printf("Received : %s \n", rx_data);

        // 重新开启下一次接收中断
        HAL_UART_Receive_IT(&huart1, rx_data, 5);
    }
}

3. 添加错误回调处理,防止中断被禁用

UART接收过程中若出现溢出、帧错误等异常,HAL库会自动禁用接收中断,需手动重新开启:

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
    if (huart == &huart1) {
        // 清除错误标志位
        __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_ORE | UART_FLAG_FE | UART_FLAG_NE);
        // 重新启动接收中断
        HAL_UART_Receive_IT(&huart1, rx_data, 5);
    }
}

4. 修正发送数据的长度(可选)

当前card_data_string第4位是'\0',strlen(card_data_string)会返回4,实际仅发送前4字节。若需发送完整5字节数据,直接指定长度为5:

HAL_UART_Transmit(&huart1, (uint8_t*)card_data_string, 5, 1000);

验证要点

  • 确认ESP8266返回的是连续5字节的'10001'(对应ASCII码0x31,0x30,0x30,0x30,0x31),无额外帧错误。
  • 检查STM32的USART1引脚连接是否正常,无虚焊或电平不匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:25:10