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; }}

总结
|
|