VC MFC Mscomm控件 串口通信 如何实现奇偶校验

时间:2022-09-06 12:01:10
    在网上搜集了不少关于Mscomm串口通信的介绍,基本都是介绍如何实现串口通信,但是再往下非常重要的校验就不说了;
    我已经知道m_mscomm.put_Settings(_T("9600,N,8,1"));里边各个位的含义了,9600是波特率,n表示无校验(o表示奇校验,e表示偶校验),8表示数据位(可设置5,6,7,8),1表示停止位(可设置1,1.5,2),这些我都知道,而且无校验的串口通信我也会做了,不用各位再给我讲了;
    另外,奇偶校验的概念我也比较清楚了,比如奇校验就是在传送的8位2进制数据的后面再添加一位,若2进制数据中1的个数是偶数个,则添加的那一位就为1,若2进制数据中1的个数是偶数个,则添加的第九位为0,以保证9位整体1的个数为奇数,在接收方收到数据时,将按照奇校验的要求检测数据中“1”的个数,如果是奇数,表示传送正确,否则表示传送错误,这个时候可要求下位机重发数据或执行其他操作,这就是奇校验,也不用各位给我讲了;
    关键是后面的操作,奇偶校验。我想问的是,现在我把下位机设置成o(奇校验),上位机也设置设置成o(奇校验),仅仅这样肯定是不行的吧,下一步到底该怎么做才能真正实现奇偶校验以保证数据比较可靠的传输呢;
    若校验出错,要求下位机重发数据;
    请大神们指点迷津啊!

11 个解决方案

#1


奇偶校验设置好之后,是底层的问题,和代码没有太大关系.
如果要实现更准确的校验,可以用CRC校验,C语言的CRC算法网上一搜就有了.

#2


引用 1 楼  的回复:
奇偶校验设置好之后,是底层的问题,和代码没有太大关系.
如果要实现更准确的校验,可以用CRC校验,C语言的CRC算法网上一搜就有了.

我感觉串口通信中的奇偶校验是糊弄人的,仅仅是为了提供第九个时钟周期而已,没别的用好像

#3


引用 2 楼  的回复:
引用 1 楼 的回复:

奇偶校验设置好之后,是底层的问题,和代码没有太大关系.
如果要实现更准确的校验,可以用CRC校验,C语言的CRC算法网上一搜就有了.

我感觉串口通信中的奇偶校验是糊弄人的,仅仅是为了提供第九个时钟周期而已,没别的用好像

也不能这么说
不过不管怎么样上位编程不用管底层处理
如果你对数据不放心就自己指定校验方式和通信协议自己检测

#4


具体是怎么进行校验,那是硬件来实现的,你只需要上下位机设好校验类型就行了.收发数据不需要涉及到校验,如果数据在传输过程中出错了,串口寄存器的相关标志位会置位告诉数据有错,你只需要在读取数据前先读相关的寄存器的状态位来判断数据是否正确,再决定是否读取数据

#5


其实没有100%的校验方式,就是奇偶校验也会有错的时候,而且错的时候还判断不出来,把错误的数据当成正确的数据,比如一个8位数据里有两个位正好改变成对方的值,那这奇偶校验是判断不出来的,所以如果想再可靠些,在协议里还得自己加上校验方式

#6


引用 4 楼  的回复:
具体是怎么进行校验,那是硬件来实现的,你只需要上下位机设好校验类型就行了.收发数据不需要涉及到校验,如果数据在传输过程中出错了,串口寄存器的相关标志位会置位告诉数据有错,你只需要在读取数据前先读相关的寄存器的状态位来判断数据是否正确,再决定是否读取数据



“串口寄存器的相关标志位会置位告诉数据有错,你只需要在读取数据前先读相关的寄存器的状态位来判断数据是否正确,再决定是否读取数据”
关键就在这个地方
主要是我现在不知道mscomm控件的“相关的寄存器的状态位”在哪啊?这才是我提出这个问题的真正原因啊

#7


引用 5 楼  的回复:
其实没有100%的校验方式,就是奇偶校验也会有错的时候,而且错的时候还判断不出来,把错误的数据当成正确的数据,比如一个8位数据里有两个位正好改变成对方的值,那这奇偶校验是判断不出来的,所以如果想再可靠些,在协议里还得自己加上校验方式


这点我知道,呵呵

#8


引用 3 楼  的回复:
引用 2 楼  的回复:
引用 1 楼 的回复:

奇偶校验设置好之后,是底层的问题,和代码没有太大关系.
如果要实现更准确的校验,可以用CRC校验,C语言的CRC算法网上一搜就有了.

我感觉串口通信中的奇偶校验是糊弄人的,仅仅是为了提供第九个时钟周期而已,没别的用好像

也不能这么说
不过不管怎么样上位编程不用管底层处理
如果你对数据不放心就自己指定校验方式和通信协议自己……


嗯,比如和校验,的确,我本来是想图个省事儿,直接用串口自带的奇偶校验,结果仅仅是设置上了,但是其实根本没达到校验的目的,错误的数据还是收到了,虽然上位机可能通过奇偶校验检验出错误来了,但是我不知道它错了啊,根本没法写错误处理的程序,呵呵

#9


自己在协议里定义校验方式,最简单的方法是:每个字节的累加和,如果接收的数据累加和和你自己算出的累加和不一样就说明是错误的数据,就可以进行错误处理.
    另外,也可以用CRC校验进行判断数据是否有错.网上有CRC校验的完整代码.可以直接拿来用,上下位机都得用这个CRC校验代码才行.
    其实我就是在网络通信过程中也是用第个字节的累加和来做为数据是否正确,一般还没发现出过问题,CRC校验需要考虑下位机的内存和速度,所以只要不是特别严格的数据正确性判断就不要用

#10


引用 9 楼  的回复:
所以只要不是特别严格的数据正确性判断就不要用


其实我的数据传输要求不严格,呵呵,当时出现的问题是每传送几个数就会有一个数据是错误的,而且错误的数据比较有特点,就是每一个8位的二进制数据送过来,最高位没了,像这样,10010001,传送过来变成了00010001,最高位变成了0,然后就想用个校验,好把错误的数据忽略掉,或要求重发,不过后来我把波特率改低变成4800之后,基本就不出现传送错误的情况了,可能是硬件本身的原因,传送速率达不到9600吧,呵呵
多谢您的回答,结贴了,呵呵

#11


感谢各位的帮忙,对校验又了解了不少,呵呵

#1


奇偶校验设置好之后,是底层的问题,和代码没有太大关系.
如果要实现更准确的校验,可以用CRC校验,C语言的CRC算法网上一搜就有了.

#2


引用 1 楼  的回复:
奇偶校验设置好之后,是底层的问题,和代码没有太大关系.
如果要实现更准确的校验,可以用CRC校验,C语言的CRC算法网上一搜就有了.

我感觉串口通信中的奇偶校验是糊弄人的,仅仅是为了提供第九个时钟周期而已,没别的用好像

#3


引用 2 楼  的回复:
引用 1 楼 的回复:

奇偶校验设置好之后,是底层的问题,和代码没有太大关系.
如果要实现更准确的校验,可以用CRC校验,C语言的CRC算法网上一搜就有了.

我感觉串口通信中的奇偶校验是糊弄人的,仅仅是为了提供第九个时钟周期而已,没别的用好像

也不能这么说
不过不管怎么样上位编程不用管底层处理
如果你对数据不放心就自己指定校验方式和通信协议自己检测

#4


具体是怎么进行校验,那是硬件来实现的,你只需要上下位机设好校验类型就行了.收发数据不需要涉及到校验,如果数据在传输过程中出错了,串口寄存器的相关标志位会置位告诉数据有错,你只需要在读取数据前先读相关的寄存器的状态位来判断数据是否正确,再决定是否读取数据

#5


其实没有100%的校验方式,就是奇偶校验也会有错的时候,而且错的时候还判断不出来,把错误的数据当成正确的数据,比如一个8位数据里有两个位正好改变成对方的值,那这奇偶校验是判断不出来的,所以如果想再可靠些,在协议里还得自己加上校验方式

#6


引用 4 楼  的回复:
具体是怎么进行校验,那是硬件来实现的,你只需要上下位机设好校验类型就行了.收发数据不需要涉及到校验,如果数据在传输过程中出错了,串口寄存器的相关标志位会置位告诉数据有错,你只需要在读取数据前先读相关的寄存器的状态位来判断数据是否正确,再决定是否读取数据



“串口寄存器的相关标志位会置位告诉数据有错,你只需要在读取数据前先读相关的寄存器的状态位来判断数据是否正确,再决定是否读取数据”
关键就在这个地方
主要是我现在不知道mscomm控件的“相关的寄存器的状态位”在哪啊?这才是我提出这个问题的真正原因啊

#7


引用 5 楼  的回复:
其实没有100%的校验方式,就是奇偶校验也会有错的时候,而且错的时候还判断不出来,把错误的数据当成正确的数据,比如一个8位数据里有两个位正好改变成对方的值,那这奇偶校验是判断不出来的,所以如果想再可靠些,在协议里还得自己加上校验方式


这点我知道,呵呵

#8


引用 3 楼  的回复:
引用 2 楼  的回复:
引用 1 楼 的回复:

奇偶校验设置好之后,是底层的问题,和代码没有太大关系.
如果要实现更准确的校验,可以用CRC校验,C语言的CRC算法网上一搜就有了.

我感觉串口通信中的奇偶校验是糊弄人的,仅仅是为了提供第九个时钟周期而已,没别的用好像

也不能这么说
不过不管怎么样上位编程不用管底层处理
如果你对数据不放心就自己指定校验方式和通信协议自己……


嗯,比如和校验,的确,我本来是想图个省事儿,直接用串口自带的奇偶校验,结果仅仅是设置上了,但是其实根本没达到校验的目的,错误的数据还是收到了,虽然上位机可能通过奇偶校验检验出错误来了,但是我不知道它错了啊,根本没法写错误处理的程序,呵呵

#9


自己在协议里定义校验方式,最简单的方法是:每个字节的累加和,如果接收的数据累加和和你自己算出的累加和不一样就说明是错误的数据,就可以进行错误处理.
    另外,也可以用CRC校验进行判断数据是否有错.网上有CRC校验的完整代码.可以直接拿来用,上下位机都得用这个CRC校验代码才行.
    其实我就是在网络通信过程中也是用第个字节的累加和来做为数据是否正确,一般还没发现出过问题,CRC校验需要考虑下位机的内存和速度,所以只要不是特别严格的数据正确性判断就不要用

#10


引用 9 楼  的回复:
所以只要不是特别严格的数据正确性判断就不要用


其实我的数据传输要求不严格,呵呵,当时出现的问题是每传送几个数就会有一个数据是错误的,而且错误的数据比较有特点,就是每一个8位的二进制数据送过来,最高位没了,像这样,10010001,传送过来变成了00010001,最高位变成了0,然后就想用个校验,好把错误的数据忽略掉,或要求重发,不过后来我把波特率改低变成4800之后,基本就不出现传送错误的情况了,可能是硬件本身的原因,传送速率达不到9600吧,呵呵
多谢您的回答,结贴了,呵呵

#11


感谢各位的帮忙,对校验又了解了不少,呵呵