OpenEdv-开源电子网

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

无法及时接收来自USB的数据

[复制链接]

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
发表于 2022-4-26 13:56:51 | 显示全部楼层 |阅读模式
1金钱
最近在做一个USB热敏打印的项目,从USB接收数据放在缓冲区(打印前预存200*216Bytes),然后通过用定时器1ms取缓冲区数据给SPI,通过DMA把数据给打印头,现在调试的情况下,发现打印过程中缓冲区有时候没有数据了,也就是有些时候不能及时接收到来自USB的数据,想请问一下这个怎么让缓冲区一直接收数据不断,而且同时继续取数据,求各位大佬帮忙指点一下,谢谢!

最佳答案

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

问题找到了,上位机的USB来数据不均匀造成的,导致我下位机把缓冲区取完后还没有数据来,改为由我控制上位机发数据,即缓冲区数据不满199帧时下位机让上位机发一帧数据过来,满足了1ms1帧的要求,问题是解决了,但是有点没想明白的是USB来数据为什么会不均匀我用逻辑分析仪看了一下,有时候USB来数据隔了五六百毫秒才来
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-26 13:56:52 | 显示全部楼层
夏天的123 发表于 2022-4-30 08:51
对呀,你试一下,直接在1ms中断里面调用模拟数据给SPI,看打印是否OK,如果OK ,那就是前面有问题,如果不 ...

问题找到了,上位机的USB来数据不均匀造成的,导致我下位机把缓冲区取完后还没有数据来,改为由我控制上位机发数据,即缓冲区数据不满199帧时下位机让上位机发一帧数据过来,满足了1ms1帧的要求,问题是解决了,但是有点没想明白的是USB来数据为什么会不均匀我用逻辑分析仪看了一下,有时候USB来数据隔了五六百毫秒才来
回复

使用道具 举报

21

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
521
金钱
521
注册时间
2017-11-2
在线时间
122 小时
发表于 2022-4-26 15:51:26 | 显示全部楼层
试试把定时器1ms改成500ms,看看缓冲区接收数据情况有没有好一点
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-26 20:49:00 | 显示全部楼层
夏天的123 发表于 2022-4-26 15:51
试试把定时器1ms改成500ms,看看缓冲区接收数据情况有没有好一点

500ms太长了,导致我打出来的数据被拉宽太多,缓冲区接收数据的情况也没有很好
回复

使用道具 举报

21

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
521
金钱
521
注册时间
2017-11-2
在线时间
122 小时
发表于 2022-4-27 09:49:12 | 显示全部楼层
弈者 发表于 2022-4-26 20:49
500ms太长了,导致我打出来的数据被拉宽太多,缓冲区接收数据的情况也没有很好

你先看下是哪种情况?
1.打印过程中缓冲区有时候数据没有了,可能是1ms定时器频率太高把数据取完了,下一次再取就没有数据了,这个时候可以适当延长定时器时间,比如10ms,20ms,50ms,看看有无改善,500ms也是试一试;
2.打印过程中数据丢失,可能是FIFO满了,没有空余空间,原因是定时器读取速度太慢了,跟不上USB传输导致,也可能是缓冲区太小(可以设置为(USB最大数据包/4 + 1)*2,USB最大数据包要弄清);
3.不知道你的主函数运行一个周期要多久时间,如果主函数运行一个周期时间短的话,可以不用定时器,直接在主函数里面判断,如果USB接收到数据,就立马发送给SPI,即收即发;
最终是要达到  USB传输速度和打印机打印速度匹配  ,所以要两边调节file:///C:/Users/rd175/Desktop/3.PNG;
回复

使用道具 举报

0

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2022-4-21
在线时间
19 小时
发表于 2022-4-27 09:59:02 来自手机 | 显示全部楼层
加大缓冲区
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-27 15:20:22 | 显示全部楼层
夏天的123 发表于 2022-4-27 09:49
你先看下是哪种情况?
1.打印过程中缓冲区有时候数据没有了,可能是1ms定时器频率太高把数据取完了,下 ...

十分感谢你的回复
1.调试过程中发现是缓冲区无数据了
2.
(1)目前上位机通过USB将数据发给下位机,上位机大概是每毫秒216Bytes往下发,而下位机的USB是全速模式,
只能每次接收最大64Bytes往我的缓冲区里填(USB我不太了解接收机制,据网上说是超过64Bytes的会被拆分发,
实测也是这样),而我取数据则是每毫秒216Bytes通过SPI往打印头发数据,这就有可能是你说的数据取太快造成缓冲区枯竭,这是第一个问题;
(2)第二个问题是我读数据的过程中USB也会继续接收数据去写缓冲区,造成读的时候缓冲区数据混乱,我想向您请教下怎么保证读的过程中继续写但又不影响我读数据
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-27 15:23:02 | 显示全部楼层

RAM有限,不能加太大了,230*216Bytes是极限了,但是也没有用
回复

使用道具 举报

21

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
521
金钱
521
注册时间
2017-11-2
在线时间
122 小时
发表于 2022-4-28 12:16:04 | 显示全部楼层
弈者 发表于 2022-4-27 15:20
十分感谢你的回复
1.调试过程中发现是缓冲区无数据了
2.


你用的哪一款MCU?
回复

使用道具 举报

21

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
521
金钱
521
注册时间
2017-11-2
在线时间
122 小时
发表于 2022-4-28 12:31:30 | 显示全部楼层
弈者 发表于 2022-4-27 15:20
十分感谢你的回复
1.调试过程中发现是缓冲区无数据了
2.

1.如果下位机接收4包数据的时间大于1ms,第一个216Bytes还没接收完,第二个216Bytes又发送过来了,这时可能会覆盖掉第一个216bytes的部分数据,存在FIFO里的数据可能就混乱了;
2.如果下位机接收4包数据的时间小于1ms,那USB的发送速度和你的读取速度基本一致,应该没问题。但你说  造成读的时候缓冲区数据混乱,是你仿真看到缓冲区数据混乱还是看到打印出来的数据混乱?
分包发送次数计算:
216Bytes分包发送,每包64Bytes,需要发送四次;
Sendcnt=(TotalNum +(PackNum-1))/PackNum;
回复

使用道具 举报

0

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2022-4-21
在线时间
19 小时
发表于 2022-4-28 12:36:58 来自手机 | 显示全部楼层
既然是每ms216字节,上位机就一次发送64*216数据,下位机给个回应,然后处理数据,上位机收到回应信号又再发64*216,如此循环下去。然后缓冲区设成128*216。
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-29 09:12:12 | 显示全部楼层

STM32F405RG
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-29 09:21:09 | 显示全部楼层
夏天的123 发表于 2022-4-28 12:31
1.如果下位机接收4包数据的时间大于1ms,第一个216Bytes还没接收完,第二个216Bytes又发送过来了,这时可 ...

1.关于说的FIFO混乱的问题,我昨天已经解决,问题在于我的FIFO是可能同时读和写的,这就有一个问题,读的时候还在写数据,导致我读的数据会错乱,因此昨天更换了缓冲的方案,改为二维数组进行存储,这样我读的上一帧的时候,USB在写下一帧到另一个缓冲,就不会造成数据混乱(打印纸界面脏脏的)
2.更换缓冲方案后,仍然存在有打印报告拉宽或空白的情况,我现在就是有点怕下位机USB接收四包数据的时间大于1ms,导致出现上述情况,但是不知道怎么验证USB的接收时长
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-29 09:25:39 | 显示全部楼层
13760162819 发表于 2022-4-28 12:36
既然是每ms216字节,上位机就一次发送64*216数据,下位机给个回应,然后处理数据,上位机收到回应信号又再 ...

如果的是这样的话,那我下位机还会走纸,你发64*216Byte,也就是64ms,按照这样循环的话,我打印纸上应该会出现一些空白的情况,那这样就不行了
回复

使用道具 举报

0

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2022-4-21
在线时间
19 小时
发表于 2022-4-29 10:29:46 来自手机 | 显示全部楼层
是一次发送,不是每ms发送,控制打印头的是用的什么电机呢,不能停顿吗?
回复

使用道具 举报

0

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2022-4-21
在线时间
19 小时
发表于 2022-4-29 10:32:14 来自手机 | 显示全部楼层
你这个是要求实时传输,而且速度不能低于216KB
回复

使用道具 举报

21

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
521
金钱
521
注册时间
2017-11-2
在线时间
122 小时
发表于 2022-4-29 12:23:56 | 显示全部楼层
弈者 发表于 2022-4-29 09:21
1.关于说的FIFO混乱的问题,我昨天已经解决,问题在于我的FIFO是可能同时读和写的,这就有一个问题,读的 ...

根据你的描述,
1.USB写缓冲区用的是轮询还是中断?中断的话优先级要大于1ms定时器,轮询的话写缓冲区时屏蔽所有中断,写完之后再使能所有中断,避免没有将数据正确写入到缓冲区,然后可以用2个全局变量分别记录写数据的位置和读数据的位置,读的时候判断位置就行;
2.下位机USB接收四包数据的时间大于1ms  导致的情况应该是打印出来的数据丢失,不是拉宽,所以打印出来的数据没有丢失的话那USB接收四包数据的时间是小于1ms的,不用验证。
3.你这个打印机是实时打印的话,纸按固定速度出来,有的数据是正常的间距,有的数据之间拉宽,要么是USB发送中间有停顿,要么是SPI发送有问题,某个时刻有中断或者什么干扰了SPI导致打印有拉宽,可以用固定数据模拟缓冲区通过spi发送,看打印是否正常,如果不正常,那就是1ms定时器受到干扰了,或者SPI有问题;
4.还有你说的空白是丢失了数据  还是  没丢失只是间距很长呢?
5.如果有数据丢失要判断是 写入 还是 读出 还是 SPI 出问题,确定了位置就很好改;
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-29 15:10:28 | 显示全部楼层
夏天的123 发表于 2022-4-29 12:23
根据你的描述,
1.USB写缓冲区用的是轮询还是中断?中断的话优先级要大于1ms定时器,轮询的话写缓冲区时 ...

1.USB写缓冲区的时候用的是中断,在CDC_Receive_FS里去写,根据网上的解释,此函数是不需要我调用,只要有数据它就会被USB中断调用。
2.打印过程中,拉宽和丢数据的两种情况均会在报告中出现,所以仍不能排除下位机USB接收四包的数据大于1ms
3.中间打印过程中,我曾用示波器量过信号,因为目前加热信号和发送数据是绑在一起(一个函数)的,期间加热信号一直没断过,那是不是可以排除中断打断的情况呢?而且我用SEGGER_RTT_printf打印出没有数据的情况。模拟数据我可以在USB接收端尝试一下,之前一直是在发送端直接塞模拟数据到SPI打,没有出现数据丢失或拉宽的现象。
4.空白有数据丢失和间距很长的情况
5.根据第三点,我认为SPI没有出问题
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
383
金钱
383
注册时间
2018-6-26
在线时间
68 小时
 楼主| 发表于 2022-4-29 15:12:08 | 显示全部楼层
13760162819 发表于 2022-4-29 10:29
是一次发送,不是每ms发送,控制打印头的是用的什么电机呢,不能停顿吗?

控制打印头的电机我不知道是什么类型,电机停顿我今天早上试了,一卡一卡的,打出来的效果很不好
回复

使用道具 举报

21

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
521
金钱
521
注册时间
2017-11-2
在线时间
122 小时
发表于 2022-4-30 08:51:35 | 显示全部楼层
弈者 发表于 2022-4-29 15:10
1.USB写缓冲区的时候用的是中断,在CDC_Receive_FS里去写,根据网上的解释,此函数是不需要我调用,只要 ...

对呀,你试一下,直接在1ms中断里面调用模拟数据给SPI,看打印是否OK,如果OK ,那就是前面有问题,如果不OK,那可能是1ms中断有问题,或者你1ms中断里面不能调用SPI,用模块化调试,看看是哪个模块的问题;还有就是你的时钟用的是MCU的内部时钟吗?这个时钟精度准不准,之前有无相似的案例 用过你现在用的时钟;
不断去试,就能找出问题的位置;
回复

使用道具 举报

17

主题

78

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
456
金钱
456
注册时间
2021-9-6
在线时间
59 小时
发表于 2022-8-29 16:58:19 | 显示全部楼层
楼主分享一下吗,我现在用ch32v307只能中断传输,我想批量传输应该怎么办
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-8 19:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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