目录
参考:
https://blog.csdn.net/spdian/article/details/71215467
https://www.cnblogs.com/jason-lu/articles/3171959.html
https://www.cnblogs.com/ruishuang208/archive/2013/06/11/3132274.html
https://blog.csdn.net/u013050857/article/details/41252789(重点)
https://blog.csdn.net/seashine_yan/article/details/71192283
第一章、简介
C#提供了SerialPort串口类,可以实现异步通信。事实上,我们对非大量数据、防止阻塞、多个事件触发等等通信方式,还是用异步通信用得比较多。
C#提供了SerialPort串口类,可以实现异步通信。事实上,我们对非大量数据、防止阻塞、多个事件触发等等通信方式,还是用异步通信用得比较多。
C#提供了SerialPort串口类,可以实现异步通信。事实上,我们对非大量数据、防止阻塞、多个事件触发等等通信方式,还是用异步通信用得比较多。
- CPU和外部通信有两种通信方式——并行通信和串行通信。
- 每个通信系统——几乎包含有并行通信和串行通信。
- 串行通信——又分为同步通信和异步通信。
- 对于C#SerialPort类通信——串口同步通信指的是在同步执行时,线程会被阻塞,函数直到执行操作完成后才返回,导致程序的执行效率下降。而在异步执行时,即使操作还未完成,调用的函数也会立即返回,费时的I/O操作在后台执行,这样线程就可以做其它的事情,从而提高了执行效率。参考https://bbs.csdn.net/topics/390616426
千万别混淆了,请看下面介绍串行通信。
第二章、并行通信
省略
第三章、串行通信
串行通信又可分为同步通信和异步通信两种方式。
3.1、同步通信
3.1.1、同步通信的原理
同步通信就是主机在进行通信前要先建立同步,即要使用相同的时钟频率,发送方的发送频率和接受方的接受频率要同步。 除了时间频率的不同外,异步通信和同步通信之间的区别还是发送数据的表示形式,异步通信一般发送单位是字符,同步通信发送单位是比特流(数据帧),但是这不是绝对的,异步通信有时也使用帧来通信。
3.1.2、同步通信的数据格式
同步串行通信的数据格式如下图所示,每帧信息,由3个部分组成:
- 2个同步字符作为一个信息帧的起始标志。
- n个连续传送的数据。
- 2个字节循环冗余校验码(CRC)。
3.1.3、同步通信特点
所谓同步通信,是指数据传送是以帧为单位,帧与帧之间、帧内部的位与位之间都同步。同步串行通信的特点可以概括为:
- 以帧为单位传送信息。
- 在一个帧内,帧与帧之间无间隔。
- 因为一次传输的数据块中包含的数据较多,所以接收时钟与发送进钟严格同步,通常要有同步时钟。
- 优点:效率高、数据量大。缺点:对时钟要求高、设备昂贵。
- 应用——通信网中,有大批量数据需要传输。
- 因为同步方法调用会导致程序流程中途等待,所以采用同步方法的情况下往往会导致程序执行的延迟。同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行。https://blog.csdn.net/u013050857/article/details/41252789
3.2、异步通信
参考:
https://blog.csdn.net/u013095415/article/details/83991859 单片机串口调试丢包验证过程记录_已解决
https://bbs.csdn.net/topics/50049422
http://bbs.21ic.com/icview-19681-1-1.html?ordertype=1
异步通信过程:
异步通信,往往需要考虑几个问题,以保证链路的信息传递的完整性:
- 握手、心跳包、定时器——必须确保上位机和硬件模块单片机的硬件联通,两者才能正常通信。联通状态就是握手成功状态。那么如何保证两者一直处于握手成功状态呢?上位机可以在线程开个定时器,一直间隔(比如定时间隔1000ms)地给硬件模块单片机发心跳包,单片收到心跳包之后,在1000ms内给上位机回复应答信号,从而确认两者一直是否处于联通状态。
- 包大小或者说帧大小——一帧往往设置为32字节或64字节。
- 粘包问题、拆包问题 —— 设定好包的帧头,帧尾,只有收到帧头、帧尾,就认为接收到了一个完整数据包,而不用管包内容的长度,因为不同的包长度可能不同。一个帧必须包含枕头、帧尾。
- 丢包问题——丢包问题可以分为两种。一种情况是,比如一帧 = 32字节,你收到了20个字节,并且收到了帧头、帧尾,那么认为这个包丢失了,需要重传。还有一种情况是,你本来应该按顺序发送图片的A帧、B帧、C帧..........,但是你发现,你只收到了A帧,C帧......,B帧丢失了,没有,就需要重传B帧,没错,这种情况极少发生,但也有可能。实际的工程应用中,一般用第一种情况,就够用了,除非特别应用。
- 误包(或误码)问题——比如某个包既收到帧头,也收到帧尾,但是包里面的内容发送了错误,采用奇偶校验、异或校验、CRC校验等方式检测出这个包有错误,那么可以重传这个包,也可以用纠错。CRC既可以找错,也可以纠错;奇偶校验等方式只能找错,不能纠错。
- 异步通信的典型帧结构是起始位、数据位、校验位、停止位。典型的帧长度是10位或11位。若你一帧是10位,发了M = 100个帧,那么一共发送了10*M = 1000位。此时你发送了8*100个数据,有效信息占了20% = 800/1000,冗余信息占了20%。
- 异步通信,帧结构远远不止3.2.2小结阐述的那样,还有如3.2.3小结所示。
- 3.2.3小结的帧结构大小,与工作环境有关系、与设备有关系等等。假如一帧太长,比如1024bit,那么一旦发生误码、丢包,我们还需要重传这个包。若是频繁的重传,那么整个信道传输有效的信息(注意是有效的信息,而不是信息)就会降低。参考http://bbs.21ic.com/icview-19681-1-1.html?ordertype=1
3.2.1、异步通信的原理
异步通信就是发送方在任意时刻都可以发送数据,前提是接收端已经做好了接受数据的准备(如果没有做好接受准备,数据肯定发送失败),也正是因为发送方的不确定性,所以接收方要时时刻刻的准备好接受数据,同时由于每次发送数据时间间隔的不确定性,所以,在每次发送数据时都要使用明确的界定符来标示数据(字符)的开始和结束位置,可以想象这种通信方式效率很低。虽然异步通信效率低,但是对设备的要求不高,通信设备简单。
3.2.2、典型异步通信的帧结构
异步串行通信的数据格式如图所示,每帧信息,由4个部分组成:
- 1位起始位,规定为低电0。——当发送设备要发送一个字符数据时,首先发出一个逻辑“0”信号,这个逻辑低电平就是起始位。起始位通过通信线传向接收设备,当接收设备检测到这个逻辑低电平后,就开始准备接收数据位信号。因此,起始位所起的作用就是表示字符传送开始。起始位往往是硬件给一个低电平,不用自己设置。https://bbs.csdn.net/topics/350103040
- 5~8位数据位,即要传送的有效信息。——当接收设备收到起始位后,紧接着就会收到数据位。数据位的个数可以是5,6,7或8位的数据。在字符数据传送过程中,数据位从最低位开始传输。
- 1位奇偶校验位。——常用的检验方位包括奇偶检验、CRC校验。 奇偶校验位用于有限差错检测,通信双方在通信时需约定一致的奇偶校验方式。就数据传送而言,奇偶校验位是冗余位,但它表示数据的一种性质,这种性质用于检错,虽有限但很容易实现。
- 1~2位停止位,规定为高电平1。——在奇偶位或数据位之后发送的是停止位,可以是1位、1.5位或2位。停止位是一个字符数据的结束标志。
(一)、10位异步通信方式
C#提供的串口类 SerialPort一般的异步通信方式:
该截图中,起始位==0,数据位==8,检验==none,停止位==1,握手方式==none,就是典型的10位异步通信方式
(二)、11位异步通信方式
加上检验位,就是11位了。关于检验的方法
数据量小:
1、check sum方式 :将所有的数据按字节加起来,得到一个校验和
2、异或方式 :将所以数据按字节异或,得到一个校验和。
3、反码相加 :将所有数据按字节求反码再相加,这也是tcp/ip协议里用的一种办法。
4、CRC :采用CRC8可以计算256字节内的数据校验,CRC既可以找错,也可以纠错。5、偶检验:如果一组给定数据位中 1 的个数是奇数,那么偶校验位就置为 1,从而使得总的 1 的个数是偶数。
6、奇检验:如果给定一组数据位中 1 的个数是偶数,那么奇校验位就置为 1,使得总的 1 的个数是奇数。
数据量大:
用CRC算法,可以是CRC16,CRC32。CRC既可以找错,也可以纠错。
3.2.3、异步通信其他的帧结构
参考https://zhidao.baidu.com/question/288947771.html?sort=11&rn=5&pn=0#wgt-answers
串行通信中,帧信息一般是根据需要自己约定而确定的。其内容一般是由多个8位单字节数据组成。这是最简单的,但大多数应用中规范的做法一帧信息都会包含:帧头 + 帧长度 + 标志信息 + 内容信息 + 校验信息+帧尾。对于不同的中断,还需要考虑中断地址:
帧头 + 帧长度 + 中断地址信息 + 标志信息 + 内容信息 + 校验信息 + 帧尾。
我在Socket/TCP通信中,串视频监控每帧的长度915000个字节,帧结构为帧头 + 帧长度 + 信息内容,这样的帧结构与本小节的帧结构类似。
3.2.4、CRC校验
参考https://baijiahao.baidu.com/s?id=1608965002019598869&wfr=spider&for=pc
(一)、什么是CRC校验?
CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
(二)、CRC校验原理
其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。
模2除法:模2除法与算术除法类似,但每一位除的结果不影响其它位,即不向上一位借位,所以实际上就是异或。在循环冗余校验码(CRC)的计算中有应用到模2除法。
(三)、CRC校验步骤
CRC校验中有两个关键点,一是
预先确定一个发送送端和接收端都用来作为除数的二进制比特串(或多项式),可以随机选择,也可以使用国际标准,但是最高位和最低位必须为1;二是把原始帧与上面计算出的除数进行模2除法运算,余数作为CRC校验码。
CRC校验码计算示例:现假设选择的CRC生成多项式为G(X) = X4 + X3 + 1,要求出二进制序列10110011的CRC校验码。
下面是具体的计算过程:
①将多项式转化为二进制序列,由G(X) = X4 + X3 + 1可知二进制一种有五位,第4位、第三位和第零位分别为1,则序列为11001
②多项式的位数位5,则在数据帧的后面加上5-1位0,数据帧变为101100110000,然后使用模2除法除以除数11001,得到余数。
③将计算出来的CRC校验码添加在原始帧的后面,真正的数据帧为101100110100,再把这个数据帧发送到接收端。
④接收端收到数据帧后,用上面选定的除数,用模2除法除去,验证余数是否为0,如果为0,则说明数据帧没有出错。
(四)、CRC的应用
参考https://wenku.baidu.com/view/1836422e66ec102de2bd960590c69ec3d5bbdbd7.html
在CRC校验中,接收端检查到有一位错误数据后,纠正的方法包括三种:
- 请求重新发送——当错误发生时请求重传这是一种非常普遍的纠错方式,它适用于任何一种编码传输。
- 删除数据——删除数据”有些让人不好理解,其实我们可以这样来看,一般的数据传输不是一个两个字节,而是一段连续的数据,如果有一个接收数据出错了,我们把它删除,系统会认为这个数据包在传输过程中已经丢失,这样系统会自动发出重传请求,从而达到纠错的目的。
- 通过余数的值由接收端自行纠正——因为CRC码是一种纠错码,把接收到的CRC码与生成多项式相除,可以确定错误位置,这时候接收端就可以。
3.2.5、异步通信特点
所谓异步通信,是指数据传送以帧为单位,帧与帧间的传送是完全异步的,位与位之间的传送基本上是同步的。异步串行通信的特点可以概括为:
- 以帧为单位传送信息。
- 相邻两帧间的间隔是任意长。
- 因为一个帧中的比特位长度有限,所以需要的接收时钟和发送时钟只要相近就可以。
- 异步方式特点简单的说就是:帧间异步,帧内部各位同步。
- 优点:对时钟要求不高、成本低、便宜且容易实现。缺点:数据量小、速率低。
- 应用——应用于在工业、实际应用中。适用于短距离、速率不高的情况下。
- 异步调用不阻塞线程,而是把调用塞到线程池中,程序主线程或UI线程可以继续执行。https://blog.csdn.net/u013050857/article/details/41252789
第四章、串口异步通信的工程应用
参考:https://zhidao.baidu.com/question/1514688239830907180.html
这一章节,我把串口异步通信的工程应用单独拿出来讲解。第三章,虽然讲述的组帧需要考虑的问题,但是,还远远到不到工程的应用。
串口的工程应用中,我把串口传输的信息分为两种类型,一种是数据信息类型,一种是控制信息类型。
- 数据信息,数据量往往比较多,甚至是海量,容错率比较高,数据信息帧与帧之间关联性不大,可允许一定的丢帧,不需要丢帧重传——比如实时温度、湿度采集等等,假如有一些帧丢掉了,那对整体影响也不大。
- 控制信息,数据量往往比较少,容错率比较低,数据信息帧与帧之间关联性大,丢帧需要重传——比如串口操作机器的指令、订单信息等等,一旦这些信息发生了丢包、误包,必须重传。
那么,如何满足工程中的波特率、误报率、实时性大小的需求?根据波特率B,测试误比特率P1后,根据P1计算你想要的误包率P2,然后计算包大小S。最后,就确定了整体的B/P1/P2/S等等,如图4-1所示。
图4-1