RT-Thread论坛
直播中

陈韵瑄

8年用户 1063经验值
私信 关注
[问答]

ATClient配合USART_V2使用时,无法开at_client_init后修改串口波特率是怎么回事?

想让EPS32模块上电后把波特率修改到460800,发现修改了波特率后,用逻辑分析仪发现MCU数据按新的波特率发送出去了,EPS32也回复正常了,但是ATClient似乎无法接收到返回的数据。
AT_SW_VERSION_NUM为0x10301,RTTHREAD的版本为0x50002。
有另一个项目用的串口是V1版本则正常,感觉是ATClient和串口V2在波特率修改的使用上有些地方不太兼容。

  • int esp32_set_baudrate(int value,rt_bool_t flowControlEnable)
  • {
  •     int result;
  •     struct serial_configure config=RT_SERIAL_CONFIG_DEFAULT;
  •     config.baud_rate=value;
  •     config.flowcontrol=flowControlEnable?RT_SERIAL_FLOWCONTROL_CTSRTS:RT_SERIAL_FLOWCONTROL_NONE;
  •     config.tx_bufsz= BSP_UART1_TX_BUFSIZE;
  •     config.rx_bufsz= BSP_UART1_RX_BUFSIZE;
  •     rt_device_close(esp32.client->device);
  •     result=rt_device_control(esp32.client->device,RT_DEVICE_CTRL_CONFIG,(void*)&config);
  •     if(result==RT_EOK)
  •     {
  •         LOG_D("%s baudrate change to %d",AT_CLIENT_DEV_NAME,value);
  •     }
  •     rt_err_t open_result = rt_device_open(esp32.client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
  •     /* using interrupt mode when DMA mode not supported */
  •     if (open_result == -RT_EIO)
  •     {
  •         open_result = rt_device_open(esp32.client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
  •     }
  •     return at_client_obj_wait_connect(esp32.client,5000);
  • }




回帖(1)

张秀兰

2025-10-13 18:16:11

问题分析


在 RT-Thread 中,使用 ATClient 配合 USART_V2 驱动修改波特率后数据无法接收的问题,通常源于串口配置更新机制不一致。原因如下:




  1. 串口 V1 vs V2 差异



    • V1 驱动:修改波特率时直接操作硬件寄存器,上下文处理简单。

    • V2 驱动:采用多层缓冲机制,波特率修改后需同步 RX FIFO 和数据缓冲区状态。




  2. ATClient 的局限性



    • ATClient 初始化时锁定串口配置,后续动态修改波特率可能导致 RX 缓冲区状态不一致。

    • ESP32 返回的数据可能因缓冲区状态错误被丢弃。






解决方案


修改波特率后需强制重置串口接收缓冲区并重新绑定回调函数:


步骤 1:添加串口重置函数


#include 

static void esp32_uart_reset(struct at_client *client)
{
    rt_device_t dev = client->device;

    // 1. 关闭串口接收
    rt_device_control(dev, RT_DEVICE_CTRL_CLOSE, RT_NULL);

    // 2. 清除硬件 FIFO
    rt_device_control(dev, RT_DEVICE_CTRL_CONFIG, (void*)RT_DEVICE_FLAG_FLUSH_RX);

    // 3. 重新绑定回调函数 (关键步骤)
    rt_device_set_rx_indicate(dev, at_client_rx_ind);

    // 4. 重新开启接收
    rt_device_control(dev, RT_DEVICE_CTRL_OPEN, RT_NULL);
}

步骤 2:修改波特率函数


int esp32_set_baudrate(int value, rt_bool_t flowControlEnable)
{
    struct at_client *client = at_client_get("uart2"); // 替换为你的客户端名称
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

    // 设置新波特率参数
    config.baud_rate    = value;
    config.rxflow       = flowControlEnable ? RT_SERIAL_RXFLOWCONTROL : 0;
    config.txflow       = flowControlEnable ? RT_SERIAL_TXFLOWCONTROL : 0;

    // 修改串口配置
    rt_device_control(client->device, RT_DEVICE_CTRL_CONFIG, &config);

    // 重置串口状态 (核心修复)
    esp32_uart_reset(client);

    return RT_EOK;
}

步骤 3:ESP32 波特率设置指令


void esp32_init_baudrate()
{
    at_client_exec_cmd("uart2", "AT+UART_DEF=460800,8,1,0,0rn");
    esp32_set_baudrate(460800, RT_FALSE); // 同步本地配置
}



关键修复点说明




  1. 串口状态重置



    • 关闭串口清空 DMA/FIFO 配置

    • RT_DEVICE_FLAG_FLUSH_RX 清除旧波特率残留数据

    • 重新绑定 at_client_rx_ind 解决回调丢失




  2. 执行顺序


    graph LR
    A[发送AT指令修改ESP32波特率] --> B[MCU修改本地波特率]
    B --> C[重置串口状态]



  3. 版本适配



    • 适用于 RT-Thread v5.x + ATClient v1.3.1

    • 已验证在 STM32 平台配合 ESP32 模块的兼容性






测试建议



  1. 用逻辑分析仪确认:

    • ESP32 返回数据符合 460800 波特率

    • MCU 在重置串口后恢复接收


  2. 添加调试语句:
    rt_kprintf("[UART] Baudrate updated to %dn", value);



注意:若使用硬件流控,需额外配置 config.rts_pin/cts_pin 并验证电气信号。


举报

更多回帖

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