单片机与PC串口16位数据通信的自定协议问题

功能:51单片机向PC应用程序发送外部脉冲计数,串口通信
设置:串口:2400 n 8 1,T0的TH0、TL0作为16位计数器存储外部脉冲数

51单片机向PC传输16位有效数据(TH0+TL0),PC上有delphi开发的应用程序进行接收显示计数值,因串口通信数据位是8位,为了使PC应用程序界面显示16位数据,自定通信协议为:每次通信时,51向PC首先发送0XFA(作为数据开始标志),然后发送TL0中的计数值,发送TH0的计数值, PC端应用程序首先判断数据开始标志0XFA,若是则取后面的两个字节数据作为输出显示

请问这样定义通信协议可以吗? 要不要再加一个字节作为校验?
或者还有其他更好更合适的解决办法?

敬请指点,谢谢!

1、你要考虑计数器数据中也遇到0xFA时不要造成混乱。
2、如果通信距离在两三米内,且数据错误不会产生严重后果的话,可以不用校验。
3、不知你发送数据的频度有多高,如果不高的话,可以用ASCII码发送,非ASCII码则作为帧头。
4、如果线路比较繁忙,你可以用0xFX作为帧头,把后面两个字节的最高位移到帧头的低两位上去,这样上述问题1的情况就会避免,但运算略有麻烦。追问

谢谢你详细的回答!
如下:

1. 通信距离为50m
2. 发送数据的频率: 每隔一秒取数据、发数据
3. 用ASCII码发送是什么意思? 不都是发送0x04之类的吗?

追答

1、50米太长了,RS232原则上不支持,建议使用RS485,RS232可能会出错,需要校验;
2/3、数据量很少,建议使用ASCII格式,就不存在问题了。所谓ASCII格式,就是二进制0x54用两个字节0x35和0x34表示,数据的范围在0x30~0x46之间,其它数据你就可以用来表示帧头帧尾了。建议你参照MODBUS协议

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-11-20
简单协议自己规定就好了。
问题 : 如果你DE TH0 TL0 中的一个刚好等于0xFA的时候怎么办? 加校验也不行的。
收到的是 0xFA 0xFA 0xXX 或 0xFA 0xXX 0xFA的情况就乱了
解决:简单点就取不会出现在TH0 和TL0中的数字做标记 比如00
复杂的就不说了 比如连续发N个0xFA 来表示存在的特殊情况等等手段可以自己找
第2个回答  2011-11-20
起始标志太过简单,容易导致数据中如果出现同样数据时候,PC错误判断。
最好启用多字节开始及结束标志,以英文ASCii码做标志的话,PC端也好认,51端其实就是程序里多写几个字节而已。供参考。追问

请问结束标志怎么弄?
还有如何以英文ASCii码做标志?用单片机给串口发数据时不都是SBUF=XXX吗?

请指点下菜鸟我啊谢谢谢~~

追答

ASCii码也是有16进制构成的,详细的可查ASCii码表。
当然,如果你发送的数据结构简单、整齐,为提高通讯效率也可以以简单的起始符号来开始,不过尽量要想方法不让起始标志与正常数据混淆就可以了。
方法有很多。例如,单片机发送的数据不可能出现的数值,单片机发送的最高位只能是0的话,就可以以0X80H之后的数字来做起始标志等等。
结束标志可以用校验和数值。比如发送的所有数据之和的低8位。PC端也进行校验和,一致了说明传输正确。当然也可以重复发送进行比较只是效率不高。
单片机SBUF=0X61H,在PC端可显示出“a”。

第3个回答  2011-11-20
可以
加一个字节作为校验,可以防止误码。