OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10686|回复: 34

基于STM32F103的USB CDC数据包发送速率问题

[复制链接]

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
发表于 2018-5-7 10:51:20 | 显示全部楼层 |阅读模式
10金钱
我用STM Cube生成了USB CDC做虚拟串口的程序,然后测试发现每秒最多只能发送一千个左右的数据包到PC端串口助手上,请问这是固定的吗?还是有什么方法可以提高数据包的发送速率?谢谢~
Cube配置及程序工程见附件。

Cube_Conf.pdf (126.9 KB, 下载次数: 117)

最佳答案

查看完整内容[请看2#楼]

你这速度USB达不到,你这是间隔最小时间 是250us了,你用UART 921600可以的。4K 频率 每次发21字节可以达到的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2018-5-7 10:51:21 | 显示全部楼层
本帖最后由 mygod 于 2018-5-16 11:32 编辑
旦丁中号 发表于 2018-5-16 10:24
谢谢,不过这个软件好像用不了喔。
从标志位来看就是发送间隔过快了,然后出现了 USBD_BUSY 的情况

你这速度USB达不到,你这是间隔最小时间 是250us了,你用UART 921600可以的。4K 频率 每次发21字节可以达到的
1-1
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7464
金钱
7464
注册时间
2015-1-15
在线时间
1368 小时
发表于 2018-5-7 11:45:08 | 显示全部楼层
楼主怎么测试的????????
一分耕耘一分收获。
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-7 13:19:45 | 显示全部楼层
yklstudent 发表于 2018-5-7 11:45
楼主怎么测试的????????

我是在程序里面每秒发送2000个数据包,但是在PC端只收到1000个左右。
在程序里面看是发送太快会在发送函数“CDC_Transmit_FS()”中返回“USBD_BUSY”
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-7 16:08:03 | 显示全部楼层
求助求助~~
回复

使用道具 举报

3

主题

259

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2317
金钱
2317
注册时间
2016-12-2
在线时间
354 小时
发表于 2018-5-7 16:42:07 | 显示全部楼层
看起来您在HAL_SYSTICK_Callback()这边每1ms丢1byte出去, 所以速度会慢.
如果要以最快的throughput丢资料到host, 可以在每次传完封包就再送.
host收完资料会运行USBD_CDC_DataIn() 这个函式会再运行 hcdc->TxState = 0; , 所以您在main loop那边一直监看这个值, 当为0时就再send资料, 而且每次都传送送最大封包大小, 应该就会跑很快了.

uint8_t tx[64] = {0};                                                        //测试用数据包
while (1) {
  if (hcdc->TxState == 0) {
    CDC_Transmit_FS(tx, sizeof(tx));
  }
}
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-7 17:12:32 | 显示全部楼层
sammy902583 发表于 2018-5-7 16:42
看起来您在HAL_SYSTICK_Callback()这边每1ms丢1byte出去, 所以速度会慢.
如果要以最快的throughput丢资料 ...

谢谢您的建议~
但是用轮训的方法查看 hcdc->TxState == 0 然后来进行数据发送,出来的数据包发送速率也是每秒一千个左右。我实际的应用环境是 STM32F103 以 4000Hz 的频率读取外部传感器值,然后每读到一次值就通过 USB CDC 发送到上位机,数据包大小为 21 Bytes,然后发现 USB CDC 的发送速率跟不上。
回复

使用道具 举报

3

主题

259

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2317
金钱
2317
注册时间
2016-12-2
在线时间
354 小时
发表于 2018-5-7 18:02:03 | 显示全部楼层
旦丁中号 发表于 2018-5-7 17:12
谢谢您的建议~
但是用轮训的方法查看 hcdc->TxState == 0 然后来进行数据发送,出来的数据包发送速率也 ...

CDC用Bulk transfer是很快的, 正常来讲, 再怎么差的状况, 1秒几百KByte没问题, 不太可能一秒1~2000而已, 建议您可以改用别的板子单纯丢dummy data试试看.
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-7 18:12:54 | 显示全部楼层
sammy902583 发表于 2018-5-7 18:02
CDC用Bulk transfer是很快的, 正常来讲, 再怎么差的状况, 1秒几百KByte没问题, 不太可能一秒1~2000而已,  ...

我感觉是每个数据包可以放比较大的数据量,但是我这边每个数据包只需要21个字节,主要是需要提高它的数据包发送速率,不知道可不可行
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7464
金钱
7464
注册时间
2015-1-15
在线时间
1368 小时
发表于 2018-5-7 19:37:54 | 显示全部楼层
那是你使用的问题了,跟USB没关系;
楼主为什么21个字节一发,就不能攒够1K/10K再发
一分耕耘一分收获。
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-7 22:26:49 | 显示全部楼层
yklstudent 发表于 2018-5-7 19:37
那是你使用的问题了,跟USB没关系;
楼主为什么21个字节一发,就不能攒够1K/10K再发

我需要保证传感器采样的实时性,所以需要每次采样结束(4000Hz)后及时反馈到上位机进行处理。
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-9 08:59:00 | 显示全部楼层
继续求助
回复

使用道具 举报

10

主题

196

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
390
金钱
390
注册时间
2018-3-20
在线时间
80 小时
发表于 2018-5-9 21:12:33 来自手机 | 显示全部楼层
我用的3.5库版本。endp.c里有in-pack的回调函数,那个函数判断是否发完,没法万积蓄发,根那个1ms或5ms就没关系了。速率决定于sendbuffer大小,默认的2048大约70k/s,改大速度就会继续提升。
回复

使用道具 举报

10

主题

196

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
390
金钱
390
注册时间
2018-3-20
在线时间
80 小时
发表于 2018-5-10 07:29:48 来自手机 | 显示全部楼层
旦丁中号 发表于 2018-5-7 22:26
我需要保证传感器采样的实时性,所以需要每次采样结束(4000Hz)后及时反馈到上位机进行处理。

可以试试采样后手动调用bulk的发送,就是发送或1ms函数里最后那三行,拷贝到端点buffer,设置发送字节,启动发送。这样就不用等那个1or5ms了
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-10 09:39:34 | 显示全部楼层
孟亮 发表于 2018-5-9 21:12
我用的3.5库版本。endp.c里有in-pack的回调函数,那个函数判断是否发完,没法万积蓄发,根那个1ms或5ms就没 ...

你用的是STD库么?我用的是HAL库~
回复

使用道具 举报

10

主题

196

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
390
金钱
390
注册时间
2018-3-20
在线时间
80 小时
发表于 2018-5-10 14:40:37 | 显示全部楼层
旦丁中号 发表于 2018-5-10 09:39
你用的是STD库么?我用的是HAL库~

只要找那个同步函数和回调函数,按原子例程改就行了。endp.c里和hw_config里各一个
回复

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2018-5-10 17:34:09 | 显示全部楼层
不用改了,是上位机软件问题,他不是给你返回BUSY了吗
1-1
回复

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2018-5-10 17:36:11 | 显示全部楼层
mygod 发表于 2018-5-10 17:34
不用改了,是上位机软件问题,他不是给你返回BUSY了吗

再补充一句,STM32 USB 不是想发多快,就发多快的,如果PC主机取数据太慢了,你就卡了。
1-1
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-10 18:24:09 | 显示全部楼层
mygod 发表于 2018-5-10 17:36
再补充一句,STM32 USB 不是想发多快,就发多快的,如果PC主机取数据太慢了,你就卡了。

我PC端测试用的是原子的XCOM来接受数据的,也会出现接受数据太慢的情况吗?然后返回给我的BUSY是芯片程序跑的是时候返回的也
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-10 18:27:52 | 显示全部楼层
孟亮 发表于 2018-5-10 14:40
只要找那个同步函数和回调函数,按原子例程改就行了。endp.c里和hw_config里各一个

原子例程里的虚拟串口实现和Cube里生成的实现方法好像不太一样,用的USB库函数也有些差别。试了一下原子的例程,发送数据包的速率比较快了,但是我还是比较想知道怎么调整我上面附件里面Cube生成的代码~
回复

使用道具 举报

10

主题

196

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
390
金钱
390
注册时间
2018-3-20
在线时间
80 小时
发表于 2018-5-11 08:41:33 | 显示全部楼层
USB 回调和 同步函数 都是相同的,按照思路改一下,就ok的,这一步要自己迈~~
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-14 10:43:42 | 显示全部楼层
孟亮 发表于 2018-5-11 08:41
USB 回调和 同步函数 都是相同的,按照思路改一下,就ok的,这一步要自己迈~~

不过我发现我现在用的STM32F103支持的是USB2.0全速模式,也就是USB1.1,这个协议支持的数据包发送间隔是1ms
回复

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2018-5-14 11:07:36 | 显示全部楼层
直接while(CDC_Transmit_FS() != USBD_OK  );   间隔10MS丢数据,

然后,数据接收如果你是用串口助手的话,发送'\r'这个字符,你会发现,接收速度贼快,达到400KB/S左右

原因是,串口助手接收'\r'这个字符,窗口不需要刷新字符。如果你发送'1',这些需要刷新窗口的字符就会很慢

所以,速度慢是串口助手的锅,不关你程序的事。

我试过刷新串口助手窗口最多达到40KB/S,无字符500KB/S
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-14 11:28:52 | 显示全部楼层
a3748622 发表于 2018-5-14 11:07
直接while(CDC_Transmit_FS() != USBD_OK  );   间隔10MS丢数据,

然后,数据接收如果你是用串口助手的 ...

谢谢你的提醒。不过我现在是需要一个更快的数据包传输速率,4000Hz的一个速度。
我之前是在STM32F103和PC端中间加了USB转串口芯片CP2102,看了CP2102的Datasheet,这个芯片的接口也是USB2.0全速模式的,然后STM32F103以4000Hz的速度通过UART(波特率921600)发送数据,PC端接收也竟然没有丢包
回复

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2018-5-14 11:45:28 | 显示全部楼层
旦丁中号 发表于 2018-5-14 11:28
谢谢你的提醒。不过我现在是需要一个更快的数据包传输速率,4000Hz的一个速度。
我之前是在STM32F103和P ...

数据量是多少?2000字节*4000每秒?

回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-14 13:07:46 | 显示全部楼层
a3748622 发表于 2018-5-14 11:45
数据量是多少?2000字节*4000每秒?

我的数据是外接传感器的值,一个数据包21个字节~
回复

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2018-5-14 15:07:56 | 显示全部楼层
旦丁中号 发表于 2018-5-14 13:07
我的数据是外接传感器的值,一个数据包21个字节~

那就是81KB/S,也可以试试换不同的串口助手,写得好一点的串口助手应该能不丢包。
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-14 15:22:57 | 显示全部楼层
a3748622 发表于 2018-5-14 15:07
那就是81KB/S,也可以试试换不同的串口助手,写得好一点的串口助手应该能不丢包。

现在我觉得是USB CDC的数据包发送速率过快了,导致数据发送失败,不是串口助手的问题,我也试过用LabVIEW来接受我的数据,也是同样的问题
回复

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2018-5-14 15:40:07 | 显示全部楼层
旦丁中号 发表于 2018-5-14 15:22
现在我觉得是USB CDC的数据包发送速率过快了,导致数据发送失败,不是串口助手的问题,我也试过用LabVIEW ...

你说的过快
是一次发送数据过快
还是两次发送之间的间隔时间太短?

如果是两次之间的间隔,检查了标志位吗?
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-14 16:20:34 | 显示全部楼层
a3748622 发表于 2018-5-14 15:40
你说的过快
是一次发送数据过快
还是两次发送之间的间隔时间太短?

两次数据发送之间的间隔时间太短,也检查了标志位,会在发送函数“CDC_Transmit_FS()”中返回“USBD_BUSY”
回复

使用道具 举报

64

主题

446

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1032
金钱
1032
注册时间
2017-7-26
在线时间
275 小时
发表于 2018-5-14 18:14:04 | 显示全部楼层
你试试用这个,这个C#写的测速软件来的。

你检查了标志位的话应该跟发送间隔时间无关的。

因为测速软件能检测到你发送的数据。

1122.rar

62.45 KB, 下载次数: 94

回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-16 10:24:11 | 显示全部楼层
a3748622 发表于 2018-5-14 18:14
你试试用这个,这个C#写的测速软件来的。

你检查了标志位的话应该跟发送间隔时间无关的。

谢谢,不过这个软件好像用不了喔。
从标志位来看就是发送间隔过快了,然后出现了 USBD_BUSY 的情况
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-23 17:49:44 | 显示全部楼层
mygod 发表于 2018-5-16 11:21
你这速度USB达不到,你这是间隔最小时间 是250us了,你用UART 921600可以的。4K 频率 每次发21字节可以达 ...

忙了其他东西好些天,今天重新试了一下,还是STM32F103以4000Hz每个数据包21字节通过USB CDC发送数据,然后windows上包括串口助手XCOM和我自己弄的LabVIEW程序都是只能每秒接收到1000个数据包,在Ubuntu上的串口助手就可以正常每秒接收到4000个数据包,好像真的是像你上面说的上位机的问题额。。
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2018-5-24 08:33:29 | 显示全部楼层
额,原子哥为什么帮我选了最佳答案了呢?我觉得选的这个答案也不对呀,我亲测在Ubuntu上可以达到我的这个USB传输速度的
回复

使用道具 举报

21

主题

54

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2013-4-5
在线时间
19 小时
发表于 2020-8-9 17:32:37 | 显示全部楼层
孟亮 发表于 2018-5-9 21:12
我用的3.5库版本。endp.c里有in-pack的回调函数,那个函数判断是否发完,没法万积蓄发,根那个1ms或5ms就没 ...

有个相关的项目外包,有兴趣吗 qq 732423541
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-30 14:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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