串口通信,用的太多了,然而一直没有深入研究过。从刚开始入门单片机,就学习了如何用电脑和单片机通信,但是一旦通信成功后,就再也没有仔细去深入研究过了。这次在使用嵌入式Linux开发板的过程中,被一个问题卡了很久很久,使得我重新认识了串口通信。
问题初现
JZ2440开发板带有1个USB-COM口,三个普通的COM口。电脑通过一条USB线,插到板子的USB-COM口,与板子相连,用来发送控制命令。现在我想使用普通的COM口来和电脑通信,笔记本电脑不带COM口,所以常规的做法就是接一条USB转串口线来实现。接好之后,开发板串口测试程序也写好了,于是,我打开了电脑上的串口调试助手,开始调试。结果发现,从开发板发过来的数据,跟调试助手显示的不一致。我从开发板发送“ttttt”,电脑收到的十六进制是D1 D1 D1 D1 11。从ascii表上,查到't'应该是74,完全对不上。从此,我陷入到了维持几乎两周的困境。
噩梦开始
1.怀疑COM2口本身坏了,换成旁边的COM3,依旧如此,更换了USB转串口线,还是如此。
2.仔细检查程序是否存在bug,并没有。
3.检查串口参数设置是否一致。波特率、数据位、校验位、停止位、流控,全部都一致。
4.接下来,我开始从发送和接收的数据上来推算,某些规律。
下面是一些测试:
发送一个0x01
电脑串口助手发送 0000 0001
开发板收到的 是 0111 1111
感觉上是位的位置对调,然后全部取反了。电脑和开发板的取位顺序不一致?
发送两个0x01
电脑串口助手发送 0000 0001 0000 0001
开发板收到的是 0111 1111 0111 1111
是一样的。
发送一个0x02
电脑串口助手发送 0000 0010
开发板收到的 是 0011 1111
这个已经不符合上面的推测了
发送两个个0x02
电脑串口助手发送 0000 0010 0000 0010
开发板收到的 是 1011 1111 0011 1111
跟上面发送一个0x02相比,很奇怪,感觉错位了。
我凌乱了。。。
不得不重新来认识一下串行数据的格式,以下内容来自网上一篇文章,也不知道作者是谁,感谢作者。
————————————————— 引用 ————————————————
异步串行数据的一般格式是:起始位+数据位+停止位,其中起始位1 位,数据位可以是5、6、7、8位,停止位可以是1、1.5、2位。起始位是一个值为0的位,所以对于正逻辑的TTL电平,起始位是一位时间的低电平;停止位是值为1的位,所以对于正逻辑的TTL电平,停止位是高电平。对于负逻辑(如RS-232电平)则相反。
例如,对于16进制数据0x55aa,当采用8位数据位、1位停止位传输时,它在信号线上的波形如图1(TTL电平)和图2(RS-232电平)所示。 (先传第一个字节55,再传第二个字节aa,每个字节都是从低位向高位逐位传输)
————————————————————————————————————里面我要重点强调“每个字节都是从低位向高位逐位传输”这一点,如0001这个,示波器图形表现为1000。
另外,终于明白了数据格式的真正的具体形式:起始位+数据位+停止位,从上面的图中就能很清晰看出。
当时着急寻找答案,忘了拍波形图,从网上down来一张,仅供演示:
回到前面我说图形跟数据对不上,实际是自己压根就不懂,瞎猜的。图像跟我所发的数据完全一致。同样的,我测试了开发板串口发出的数据,图形也是吻合的。那就奇怪了,因为示波器是同一个,开发板和电脑给示波器发同一个指令,得到的是一样的图形。这就没问题啊,为什么两者一连通就出现问题了呢?
答案初现
偶然间,我瞥见开发板发数据的图形上面,电压是3.4V。但是,在测试电脑发数据的时候,印象中是10V。回来验证了一下,果真是10V。两边电压不对等啊!连忙去看了开发板的原理图,惊呆了,COM2接口是直接从arm芯片引脚出来的,没有任何转变。常规都是通过一个MAX232芯片来转换一下才接出来。因为arm芯片引脚出来的是TTL电平,差不多3.3-5V,而RS-232电平在10-15v左右,所以不能直连,需要像MAX232这种芯片来转换一下。原来如此,问题就出在这里了,COM2是TTL电平3.4V,而USB转串口线这边是RS-232电平10V。直接连在一起就大错特错了。
新的疑问
前面说过,板子自带一个USB-COM口,于是我去研究了一下,它其实是arm芯片引脚出来接了一个PL2303芯片,这个芯片直接将串口信号转化成了USB信号。再来看我另买的USB转串口线,刚好线材是透明的,我能看到里面有个芯片也是PL2303。这就奇怪了,为什么同样都是PL2303,板子的可以直接连到芯片引脚上,而USB转串口线的必须通过一个MAX232芯片来转换呢?
终极答案
我又仔细看了板子的PL2303芯片,全称是PL2303TA,USB转串口线里面的全称是PL2303RA,一个字母之差会有什么区别呢?在网上找到了PL2303TA和PL2303RA的技术手册,终于真相大白了。虽然同为PL2302芯片,PL2303TA直接在TTL电平下将串口信号转换成USB信号。而PL2303RA会将电平拉高,信号转换的同时电平也变化了。
解决方案
针对COM2口,可以有两种选择:
- 买一个带PL2303TA的USB接头,直接插到电脑上
- 买一个带MAX232的9针串口,插到USB转串口线上,再插到电脑上