找回密码
 立即注册
查看: 631|回复: 5

Windows下USB虚拟串口通讯有一定几率延迟数据

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-17 21:48:25

4

主题

7

回帖

134

积分

注册会员

积分
134
发表于 2024-9-26 20:52:50 | 显示全部楼层 |阅读模式
Windows下USB虚拟串口通讯有一定几率延迟数据

在使用MCU发送64 、128、 256字节的这种整包的数据时候(发送以后等待),
Windows在接收以后不会立即交给串口助手,会缓存起来,这个时候需要
在MCU端触发,比如发送一个空包或者一个字节的包,Windows才会把数据
给到串口助手,Mac下没这个问题,Windows下偶然发现的

send_bulk(buf, 64);
调小BULK_SIZE小于64不再出现,比如63
  1. void send_bulk(char* buf, u16 count)
  2. {
  3.         uart_send("Bulk Send Start:");
  4.         while (count > 0) {
  5.                 if (count>BULK_SIZE) {
  6.                         USB_BULK_SendData(buf, BULK_SIZE);
  7.                         buf += BULK_SIZE;
  8.                         count -= BULK_SIZE;
  9.                 } else {
  10.                         USB_BULK_SendData(buf, count);
  11.                         count=0;
  12.                 }
  13.         }
  14.         uart_send("Bulk Send End:");
  15. }
复制代码
  1. void USB_BULK_SendData(BYTE* dat, BYTE size)
  2. {
  3.         uart_send("Send Start:");
  4.         uart_send_char(size);
  5.         while(UsbInBusy);
  6.         IE2 &= ~0x80;   //EUSB = 0;
  7.         usb_write_reg(INDEX, 1);
  8.         for (i=0; i< size; i++)
  9.         {
  10.                 usb_write_reg(FIFO1, dat[i]);
  11.         }
  12.         UsbInBusy = 1;
  13.         usb_write_reg(INCSR1, INIPRDY);
  14.         IE2 |= 0x80;    //EUSB = 1;
  15.         uart_send("Send DONE");
  16. }
复制代码
使用USBTrace抓包与表象一致,下个包到以后,前一个包会和下一个包一起被处理, 似乎与确认回传机制有关
(UART是调试用的,打印数据正常,显示已经发送完毕了)



回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2024-9-27 18:11:01 | 显示全部楼层
USB Endp0~Endp3端点缓冲区是64字节,
使用CDC串口发送时,如果传输的数据长度是64整数倍字节,
传输完成数据后是要继续发一个空包触发完成数据传输。
官方封装的usb cdc lib文件也有进行相关处理,

所以不管发送多少字节数据,都能正常通信。
烧录屠龙刀例程包里面的例子“23-通过USB CDC协议虚拟串口收发数据”到芯片里,
通过串口助手发送数据跟MCU进行收发测试:

截图202409271747323551.jpg

点评

最近刚好遇到这个问题,请教下这里说的“相关处理”是不是如下处理,发送空包? [attachimg]79403[/attachimg]  详情 回复 发表于 2025-1-7 11:53
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:49
  • 最近打卡:2025-04-17 21:48:25

4

主题

7

回帖

134

积分

注册会员

积分
134
发表于 2024-9-27 20:55:36 | 显示全部楼层
乘风*** 发表于 2024-9-27 18:11
USB Endp0~Endp3端点缓冲区是64字节,
使用CDC串口发送时,如果传输的数据长度是64整数倍字节,
传输完成数 ...

感谢解答
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-1-7 11:53:58 | 显示全部楼层
乘风*** 发表于 2024-9-27 18:11
USB Endp0~Endp3端点缓冲区是64字节,
使用CDC串口发送时,如果传输的数据长度是64整数倍字节,
传输完成数 ...

最近刚好遇到这个问题,请教下这里说的“相关处理”是不是如下处理,发送空包?

截图202501071153363099.jpg
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2025-1-7 14:38:32 | 显示全部楼层
erci*** 发表于 2025-1-7 11:53
最近刚好遇到这个问题,请教下这里说的“相关处理”是不是如下处理,发送空包?

超过64字节需要分包发送,类似这样:
  1. void USB_SendData(BYTE *dat, int size)
  2. {
  3.     BYTE cnt;
  4.     int addr;
  5.    
  6.     IE2 &= ~0x80;   //EUSB = 0;
  7.     usb_write_reg(INDEX, 1);
  8.    
  9.     addr = 0;
  10.     do
  11.     {
  12.         cnt = size > 64 ? 64 : size;
  13.         while (usb_read_reg(INCSR1) & INIPRDY);
  14.         usb_bulk_intr_in(&dat[addr], cnt, 1);
  15.         addr += cnt;
  16.         size -= cnt;
  17.     } while (cnt >= 64);
  18.    
  19.     IE2 |= 0x80;    //EUSB = 1;
  20. }
复制代码

点评

好的,还要考虑分包,多谢  详情 回复 发表于 2025-1-7 14:47
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-1-7 14:47:33 | 显示全部楼层
乘风*** 发表于 2025-1-7 14:38
超过64字节需要分包发送,类似这样:

好的,还要考虑分包,多谢
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 02:21 , Processed in 0.136916 second(s), 86 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表