串口通讯中数据的接收和处理问题

gaoxing_1985007 2014-12-08 09:26:23
目前在做一个手柄的测试程序,用的串口通讯,遇到了两个问题,搞了一天,头大了,没有好的思路!!!

通讯的指令格式是这样的:

1-4字节:CommandClass_t (固定的:69 74 61 7A)
5字节:Command_t (也是固定的:02)
6字节:Packet Length
后面是Data
最后一字节是Check Sum (公式:Check Sum=~(Data之和&0xFF)+0x01)

一、第一个问题是不同长度数据的接收和处理:
需要测试手柄的按键功能,测试时按键的顺序不固定。一共有10多个按键,有些按键通过串口返回的字节长度不固定,但是都会遵守相同的指令格式,
比如:
UP键: 69 74 61 7A 02 0B A1 07 00 00 00 80 80 80 80 00 00 58
DOWN键: 69 74 61 7A 02 0B A1 07 00 00 04 80 80 80 80 00 00 54
LEFT键: 69 74 61 7A 02 0B A1 07 00 00 06 80 80 80 80 00 00 52
RIGHT键: 69 74 61 7A 02 0B A1 07 00 00 02 80 80 80 80 00 00 56
S3键: 69 74 61 7A 02 0A A1 01 00 00 29 00 00 00 00 00 35
S4键: 69 74 61 7A 02 04 A1 0A 40 00 15

上面的情况应该如何接收数据并判断是哪个按键呢?

二、第二个问题是固定长度下数据的接收和处理:

要测试Trigger按键的功能,数据长度是固定的,格式如下:

69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 XX CS (其中XX表示一个字节,大小为由0x00 到 0xFF,CS为check Sum)

按键只要稍微按动一点,就会丢出如下的数据出来:

69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 00 47 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 01 46 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 02 45 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 03 44 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 04 43 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 07 40 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 0F 38...........后面省略

我该如何接收这一堆数据并从里面把XX的值取出来呢?

...全文
296 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
mjp1234airen4385 2014-12-09
  • 打赏
  • 举报
回复
这一堆数组,如果接收数据正确的话,你每次读取18个字节,然后判断最后的两个字节是否符合你的规则。 如果符合,那就去出前16个字节,就是你的数据。
那城 2014-12-09
  • 打赏
  • 举报
回复
定义一个缓存来存储,判断接收到的数据是否是完整的数据,1-4字节:CommandClass_t (固定的:69 74 61 7A) 5字节:Command_t (也是固定的:02) 6字节:Packet Length 后面是Data 最后一字节是Check Sum 算出Check Sum ==最后一字节 等于说明是
於黾 2014-12-09
  • 打赏
  • 举报
回复
第二个问题其实一样 按键按的频繁,或者按下了不松手,那么必然是会一直发送数据过来 你只要先都丢到缓存里,然后从头到尾的去解析就好了,而不要考虑里面到底有几组数据 总之就是只要缓存里还有数据就一直处理,一直处理到没有数据了,就留给下一次接收到数据再处理
於黾 2014-12-09
  • 打赏
  • 举报
回复
错了,应该是判断list的长度是否大于包长度+6 因为现在还不知道这个设备会不会把两个连续的按键无时间间隔的发送给你 原则上就是,先缓存,然后从缓存里解析数据,解析后的数据移出缓存
於黾 2014-12-09
  • 打赏
  • 举报
回复
不要循环处理 你用VS自带的SerialPort,有DataRecieved事件,在事件中处理即可 唯一需要注意的就是,事件调用时,并不代表收到完整的一条数据,可能被分成多次收到, 自己定义个List<byte>先把收到的数据都放里面 然后可以每次收到后判断里面是否含有前面5个固定字节的头部,如果中间有,那么就可以把之前的不完整的数据remove掉 然后继续判断,第六位不是包的长度吗,判断一下整个list的长度是否等于包长度+6(头部5个字节,尾部1字节校验) 如果长度相等,那么继续校验sum,都通过就认为是一个正确的包,不通过数据丢弃
gaoxing_1985007 2014-12-09
  • 打赏
  • 举报
回复
关键是用什么方法循环读取和处理呢?
足球中国 2014-12-08
  • 打赏
  • 举报
回复
69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 00 47 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 01 46 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 02 45 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 03 44 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 04 43 69 74 61 7A 02 0B A1 01 00 01 0F 80 80 80 80 00 07 40 分隔成这样的就可以了。 69 74 61 7A 02 这个固定的读五位就可以了。 然后再读一位 0b是十六进制也就是长度是11位 然后继续读十一位数据也就是A1 01 00 01 0F 80 80 80 80 00 00 这个就是数据了。 然后再读一位是校验码 也就是47

110,568

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧