ST意法半导体
直播中

张浩

7年用户 1103经验值
私信 关注
[问答]

如果TX未完成时RX,HAL_UART_Transmit() 和 HAL_UART_Receive_IT() 失败怎么处理?

我曾经使用 HAL_UART_Transmit() 将 AT 命令发送到模块:
  • void send_uart(char * buffer)
  • {
  •         uint16_t buffer_size = strlen(buffer);
  •         uint8_t CRLFbuff[] = "rn";
  •         HAL_UART_Transmit(&hlpuart1, CRLFbuff, 2, 0xFF); // ok
  •         HAL_UART_Transmit(&hlpuart1, (uint8_t *)buffer, buffer_size, 0xFF); // ok
  •         HAL_UART_Transmit(&hlpuart1, CRLFbuff, 2, 0xFF); // ok
  • }
并以 HAL_UART_Receive_IT() 字节每字节接收应答:
  • HAL_UART_Receive_IT(&hlpuart1, &Rx_data, 1);
  • void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  • {
  •         if (huart->Instance == LPUART1){ // Current UART
  •                 if (Rx_indx + 1 > rx_buffer_size){
  •                         Rx_indx = 0;
  •                 }
  •                 if (Rx_data != 0x0A){ // If received data different from LF
  •                         Rx_Buffer[Rx_indx++] = Rx_data;    // Add data to Rx_Buffer
  •                 }
  •                 else {
  •                         Rx_indx = 0;
  •                         Transfer_cplt++;//transfer complete, data is ready to read
  •                 }
  •                 HAL_UART_Receive_IT(&hlpuart1, &Rx_data, 1);   //activate UART receive interrupt every time
  •         }
  • }
这在标称 TX/RX 中在 9600 时运行良好。但是,如果我向模块发送错误数据,它会立即发送“错误:解析错误”,而我的 STM32L031 仍在传输。这是杀死我的 RX 中断的效果。UART->RxState 不再是 HAL_UART_STATE_BUSY_RX,而是切换到 HAL_UART_STATE_READY 并且永远不会触发 RX 中断(发送部分仍然工作正常)。
我将我的传输代码更改为 HAL_UART_Transmit_IT(几乎没有返工)并且没有观察到这种行为(效果很好)。
这是正常的吗?






回帖(1)

陈鲜孰

2022-12-2 16:06:13
(1) snprintf() 的第二个参数不正确,可能会溢出 msg[] 数组。除非你能保证缓冲区总是包含一个“tx_buffer_size”字节或更少的字符串。同样,您在 HAL_UART_Transmit_IT() 中的大小参数不必要地复杂。为什么不在格式字符串中包含 CR/LF?更好的是:


  • void send_uart(char * buffer)
  • {
  •    char msg[2+tx_buffer_size+2+1] = "";        // 'CR' 'LF' "data" 'CR' 'LF' ''
  •    // The "-1" here guarantees that there is room for snprintf() to append
  •    // the trailing NULL
  •    snprintf(msg, sizeof(msg)-1, "rn%srn", buffer);
  •    HAL_UART_Transmit_IT(&hlpuart1, (uint8_t *)msg, strlen(msg)); // No need to transmit the null terminator
  • }

(2) 要知道传输何时实际完成,您需要实现 HAL_UART_TxCpltCallback() 函数(从 UART 中断处理程序调用)并设置一个标志,告诉您的主代码循环 TX 已完成。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分