Qt qextserialport类 发送数据大于127 发生错误既最高位置零的问题

    近日项目使用Qt用到串口,使用了第三方库qextserialport,开始进行一切顺利,后来调试时出现问题,发送串口数据时,大于127的数接收会发生错误。

例如:发送0xe1,接收到的却是0x61,接收值和发送值之间正好相差了127.发送的方法是按照第三方库例程里的方式使用了QByteArray。

在网上查找资料,发现众多网友都碰到了这种问题,而回答基本有三种:

①无解,求解中……

②将发送数据转换成字符串进行发送。

③原因是数据类型的问题,既signed 和 unsigned 的问题。这点说得很模糊,没有给出具体的操作方法。按照此种说法,尝试了各种强制转换,例如:

QByteArray qbaSend;
……
/*串口发送*/

unsigned char test  =(unsigned char)qbaRev[i];

结果是失败的,需要注意的是QByteArray类中的at()函数式只读的,是不能赋值的。

继续搜素,终于在一个外国论坛上看到了一个贴子,说QByteArray的类型就是存放char型的,范围在-128~127,而unsigned char 型的范围是0~255,自然就不可能发送unsigned char型的数据了。看了这个,我仿佛眼前一亮,问题的症结找到了,破解指日可待,于是我开始寻求其他的类型,如此贴推荐的使用QList替代QByteArray,但由于qextserialport 类的参数类型只有QByteArray和char* 两种,其他类型的使用非常的不方便。问题又陷入困境,后来才被证明此贴的毒害之深令人发指,国庆的美好假期就毁在它手上了。

问题不能就这么僵下去,我开始考虑换第三方库,首先想到的是,Windows下比较出名的Moxa公司开发的串口库PCOMM,和Qt结合的实例在网上没有发现现成的代码,但有迹象表明有网友对此进行了尝试,并且解决了一些问题。于是我开始尝试将PCOMM封装成一个类,方便调用,不得不说Moxa公司给出的参考手册真的是很清楚明白,非常容易上手。简单的读写功能很快就完成了,但是关于事件驱动这块就比较头疼,由于PCOMM是纯C的代码,事件驱动使用的是回调函数。手册上说建议将回电函数设置成全局函数,一试验果然只有全局函数才能编译通过,这就导致了无法再回调函数中触发信号,连接槽。有资料显示可以利用在回调函数里创建对象,让后触发,但是串口重复创建貌似不太好,而且一个串口号是排他的。这种不良事件的持续发生导致了我的心情沮丧。

正当我一筹莫展的时候,一个自从看完了外国贴后刻意被我刻意忽视的事实飘了过来。当我给QByteArray赋值后发送先我调试时发现QByteArray 中有值为225,大于127。QByteArray是能够存储大于127的数值的。其实不论char 和unsigned char型在二进制码都是一样的八位,只不过是对其解释不同罢了。我的心中又重新燃起了希望,我再次开始测试。给发送数据的某一位赋值为无符号数0xe1,即225,(1110 0001)B,发送时查看数据显示值为-31,按照char型,最高位为1,确实是-31的补码,但接收端接收到的值为97(0110 0001)B,最高位置零了!

结合操作过程中一个有意思的现象,当打开串口助手等调试时,接收到的数值确实是正确的,而且打开串口助手后,数据接收一切正常。这种情况实体串口可以一直持续到串口拔出,虚拟串口直到重新启动。结合另一个外国贴中的问题说他忘记了默认设置数据位是7位而最高位总是置零的错误。我猜测,这个qextserialport第三方库在某个设置上是有问题的。这就解释了为什么打开串口助手等工具后就一切正常了,因为串口助手等工具完成了正确设置串口的任务,把该库无效的功能补上了。

这是硬伤啊!只用换底层库了,似乎绕了一圈又回到了原点,又有一帖表示和Qt结合的串口库有很多,什么Qserialport啦,Qserialportdriver啦,等等等等。还有在Qt的5.1版本中加入了QSerialPort类,真是喜大普奔呐!

于是将Qt升级到了5.1,问题就这样解决了。值得一提的是,据说Qt的这个类是在qextserialport类的基础上来的,可以说基本没有变化,除了设置的时候用了一个辅助类(当然也可以不用)外,基本就是换了个类名,其他照抄~没有安装5.1版本也没有关系,Qt提供了该类对Qt4版本的支持。

结论:网上对于为什么qextserialport类处理大于127的数据时发生问题的解释,诸如类型设置的问题、char和unsigned char的矛盾疑似是错误的(本人菜,不敢妄下结论),真正的原因或许是该类本身的问题,当然也不排除该类使用时设置不正确。

解决方法:换一个类。。。推荐使用Qt5.1中自带的在qextserialport基础上来的QSerialPort类,改造方便,同时支持Qt4.

启发:没钱没时间出去看人山人海在实验室加班真是一件快乐的事啊!


你可能感兴趣的:(Programming)