zoukankan      html  css  js  c++  java
  • STM32cubemx-HAL库串口断线问题

    STM32cubemx:version5.1

    Chip: STM32F446RE

    IDE:Keil5

    Q:小项目上写了个简单的通信包,波特率230400,数据量较大1600Byte/s,DMA的方式实现接收,量产后发现跑久了部分机器会有只能发送不能接收的问题。

    查了很久没查到。中间加了断线检测,重新初始化串口,却无法解决。最后面发现,HAL的锅。

    部分代码:

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {        
        if(huart->Instance == UART4) {
               uint8_t ret=HAL_OK;
            if(frame_in_sync) {
                if(UART_Rx_Buffer.head == 0x55 && UART_Rx_Buffer.end == 0xAA) { // TODO: check check-sum
                    UART_Rx_Data = UART_Rx_Buffer;
                    ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, sizeof(UART_Rx_Buffer));
                    uart_updata_time= HAL_GetTick();
                                
                } else { // frame not in sync, drop coming bytes until read an end(0xAA)
                    frame_in_sync = 0;
                    ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, 1);
                }
            } else {
                  if( *(uint8_t *)&UART_Rx_Buffer == 0xAA) {
                    frame_in_sync = 1;
                    ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, sizeof(UART_Rx_Buffer));
                } else {
                    ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, 1);
                }
            }
        }
    }

    上述的代码绝大多数时间都能够正常运行。但是,总会出现莫名奇妙的掉线问题。并且难以复线。查了好久,看到有类似的问题,HAL库会不处理异常的行为,要用户处理。

    在某些情况下,HAL_UART_Receive_IT 并没有成功执行,返回了busy 或者erro,这时候整个流程就背打断了。并且串口还会被莫名其妙锁上。

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {        
        if(huart->Instance == UART4) {
                    uint8_t ret=HAL_OK;
            if(frame_in_sync) {
                if(UART_Rx_Buffer.head == 0x55 && UART_Rx_Buffer.end == 0xAA) { // TODO: check check-sum
                    UART_Rx_Data = UART_Rx_Buffer;
                    ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, sizeof(UART_Rx_Buffer));
                    uart_updata_time= HAL_GetTick();
                                
                } else { // frame not in sync, drop coming bytes until read an end(0xAA)
                    frame_in_sync = 0;
                    ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, 1);
                }
            } else {
                if( *(uint8_t *)&UART_Rx_Buffer == 0xAA) {
                    frame_in_sync = 1;
                    ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, sizeof(UART_Rx_Buffer));
                } else {
                    ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, 1);
                }
            }
                    while(ret!=HAL_OK){
                         /*try to fix connection bug  20191225*/
                          printf("UART4:RECEIVE_IT:%d
    ",ret);  //for log 
                          huart->RxState = HAL_UART_STATE_READY;
                          __HAL_UNLOCK(huart);
                          ret=HAL_UART_Receive_IT(&huart4, (uint8_t *)&UART_Rx_Buffer, 1); 
                    }
        }
    }
    
    
    void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
    {
      /* Prevent unused argument(s) compilation warning */
        if(huart->ErrorCode&HAL_UART_ERROR_ORE)
        {
            __HAL_UART_CLEAR_OREFLAG(huart);
        }
      /* NOTE : This function should not be modified, when the callback is needed,
                the HAL_UART_ErrorCallback can be implemented in the user file.
       */
    }

    修改后,出现busy或者erro时强制解锁,重新接收。根据log,大约半小时会出现一次。三台经常性出现的机子更新后运行一天,没有出现这个问题。在log中查看到了对应的修正过程。

  • 相关阅读:
    【英语天天读】Places and People
    【OpenCV学习】错误处理机制
    【英语天天读】Heart of a stranger 陌生的心灵
    【英语天天读】第一场雪
    【OpenCV学习】角点检测
    【英语天天读】Life is What We Make It
    【英语天天读】培养自信
    【英语天天读】Perseverance
    【OpenCV学习】cvseqpartition序列分类
    【英语天天读】自然
  • 原文地址:https://www.cnblogs.com/CXianRen/p/12105074.html
Copyright © 2011-2022 走看看