[其他ST产品] STM32H743 USB 通信不稳定问题

[复制链接]
 楼主| 旧年胶片 发表于 2025-7-5 18:56 | 显示全部楼层 |阅读模式
USB 通信不稳定,经常出现数据丢失和连接断开的情况,需要:

提高 USB 中断优先级
优化 USB 缓冲区管理,增加数据校验
实现 USB 断开重连机制


// USB初始化和配置USB_OTG_CORE_HANDLE USB_OTG_dev;USBD_HandleTypeDef hUsbDeviceFS;void MX_USB_DEVICE_Init(void){    // 初始化USB设备    USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);        // 注册类驱动    USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);        // 注册回调函数    USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);        // 启动设备    USBD_Start(&hUsbDeviceFS);}// USB接收缓冲区和状态#define USB_RX_BUFFER_SIZE  2048uint8_t usb_rx_buffer[USB_RX_BUFFER_SIZE];uint16_t usb_rx_count = 0;uint8_t usb_connected = 0;// USB CDC接收回调函数static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len){    // 检查接收缓冲区是否有足够空间    if(usb_rx_count + *Len <= USB_RX_BUFFER_SIZE)    {        // 将接收到的数据复制到接收缓冲区        memcpy(&usb_rx_buffer[usb_rx_count], Buf, *Len);        usb_rx_count += *Len;                // 处理接收到的数据        Process_USB_Data();    }    else    {        // 缓冲区溢出,清空缓冲区        usb_rx_count = 0;    }        // 继续接收    USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);    USBD_CDC_ReceivePacket(&hUsbDeviceFS);        return (USBD_OK);}// USB连接状态回调函数void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd){    usb_connected = 1;    printf("USB Connected\r\n");}void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd){    usb_connected = 0;    printf("USB Disconnected\r\n");        // 尝试重新连接    HAL_Delay(500);    USBD_Stop(&hUsbDeviceFS);    USBD_Start(&hUsbDeviceFS);}// USB数据处理函数void Process_USB_Data(void){    // 简单的帧处理示例,查找帧头和帧尾    uint16_t i = 0;    while(i < usb_rx_count)    {        // 查找帧头        if(usb_rx_buffer == 0xAA && i + 1 < usb_rx_count && usb_rx_buffer[i+1] == 0x55)        {            // 找到帧头,检查帧长度            if(i + 3 < usb_rx_count)            {                uint16_t frame_len = usb_rx_buffer[i+2] + (usb_rx_buffer[i+3] << 8);                                // 检查帧是否完整                if(i + 4 + frame_len <= usb_rx_count)                {                    // 提取数据                    uint8_t* frame_data = &usb_rx_buffer[i+4];                                        // 计算校验和                    uint16_t checksum = 0;                    for(uint16_t j = 0; j < frame_len; j++)                    {                        checksum += frame_data[j];                    }                                        // 验证校验和                    uint16_t received_checksum = frame_data[frame_len] + (frame_data[frame_len+1] << 8);                                        if(checksum == received_checksum)                    {                        // 校验和正确,处理数据                        Handle_Valid_Frame(frame_data, frame_len);                    }                    else                    {                        // 校验和错误                        printf("USB Frame Checksum Error\r\n");                    }                                        // 移动到下一个可能的帧                    i += 4 + frame_len + 2;                }                else                {                    // 帧不完整,等待更多数据                    break;                }            }            else            {                // 数据不足,等待更多数据                break;            }        }        else        {            // 不是帧头,继续查找            i++;        }    }        // 移除已处理的数据    if(i > 0)    {        memmove(usb_rx_buffer, &usb_rx_buffer, usb_rx_count - i);        usb_rx_count -= i;    }}











































































































总结
LOVEEVER 发表于 2025-7-29 23:52 | 显示全部楼层
有点混乱
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

29

帖子

0

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