背景技术
通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,通常称为UART),实现串、并转换,是一种广泛应用的通信设备的接口,该总线双向通信,可以实现全双工传输和接收。
在异步通信中,字符帧格式和波特率是两个重要指标,可由用户根据实际情况选定。字符帧也叫数据帧,由起始位、数据位、奇偶校验位和停止位等四部分组成,其具体格式如图1所示:
现对各部分结构和功能分述如下:
(1) 起始位:位于字符帧开头,只占一位,时钟为逻辑0低电平,用于向接收设备表示发送端开始发送一帧信息;
(2) 数据位:紧跟起始位之后,用户根据情况可取5位、6位、7位或8位,低位在前高位在后(即先发送数据的最低位);
(3) 奇偶校验位:位于数据位后,仅占一位,用于表征串行通信中采用奇校验还是偶校验,由用户根据需要决定采取何种校验方式或不采用奇偶校验;
(4) 停止位:位于字符帧末尾,为逻辑“1”高电平,通常可取1位、1.5位或2位,用于向接收端表示一帧字符信息已发送完毕,也为发送下一帧字符作准备。
在串行通信中,发送端一帧一帧发送信息,接收端一帧一帧接收信息。两相邻字符帧之间可以无空闲位,也可以有若干空闲位,这由用户根据需要决定,确切的说是发送端决定的。帧内部是没有空闲位存在的。图表1(b)中显示的是有空闲位时的字符帧格式。
波特率的定义为每秒钟传送二进制数码的位数(也称比特数),单位通常为bps(bit per second),即位/秒。波特率是串行通信的重要指标,用于表征数据传输的速度。波特率越高,数据传输速度越块,但和字符的实际传输速率不同,与字符帧格式有关。
在现有的串口通讯中,通信双方通信的波特率必须一致,否则发送方发送的数据,接收方要么接收不到,要么在接收后的解析过程中称为乱码,造成通讯故障。
针对串口通讯,通信双方的通信波特率必须一致的问题,现有的通信双方波特率配对方法有如下几种:
(1) 标准波特率穷举法
该方法为固定发送方或接收方的波特率,另一方按照一定的规律在几个备选波特率中穷举,直到匹配上。但是该方法需要匹配的一方轮询多次,浪费时间和总线资源;
(2) 码元宽度实时监测法
需要发送方和接收方之间有一个约定的同步字符,接收方监听该同步字符,确定波特率。但是,该方法需要依赖于发送方的策略;
(3) M(8/16/32)倍波特率适应法
该方法,以M为8为例,是说接收方的接收波特率是发送方波特率的8倍时,无论发任意字符,在接收方解析都只能是0x00和0x80.该方法也需要像穷举法一样,让发送方依次发送0x00~0xFF所有的字符才可以。并且如果不是该波特率,就还需要把检测的波特率再变换,然后再发一遍;但是该方法仍然需要让发送方依次穷举所有字符进行配对,如果配对不上还要对波特率进行变换,耗时较长;
(4) 检测上升沿和下降沿求最小位宽法
检测最小位宽方法不需要特征字符(串),但涉及到如果波形受到干扰,导致波形不标准时可能有的不准确问题。改进的方法可解决波形不准确问题,方法是检测两个下降沿之间的时间,除2取最小的值,不过仍然无法避免需要检测多次的问题。
发明内容
本发明的目的在于提供一种接收方只需发送方发送一帧数据帧便能准确解析出波特率、停止位长度、发送方发送的字串信息的自动配对的串口自动识别方法。
本发明提供的这种串口自动识别方法,其特征在于包括如下步骤:
S1 串口通信中,需要配对的双方约定至少包含两个字符的特征字串和数据帧中的数据位位数,约定特征字串中必须至少包含一个宽度为1位的电平,且帧中不含奇偶校验位;
S2 发送方按照通信双方的约定发送一帧数据帧,数据帧为仅包括特征字串或以特征字串开头的数据帧;
S3 接收方接收发送方发送的数据帧,识别数据帧中各段电平的时间宽度;
S4 根据识别的各段电平的时间宽度在备选波特率中选定波特率的值;
S5 确定停止位的位数;
S6 校验是否是特征字串波形;若校验完成,则串口通讯双方配对完成。
所述的串口自动识别方法还包括步骤S7:识别整个数据帧;步骤S7还能够在所述步骤S6的基础上继续识别数据帧中的除特征字串外的其他数据信息。
所述步骤S3中的识别数据帧中各段电平的时间宽度,包括如下步骤:
(1)将串口接收引脚连接与处理器的带有中断功能的通用输入/输出引脚连接;
(2)利用处理器的中断功能捕捉上升沿和下降沿,用时钟的内部寄存器值来记录中断的时间点;
(3)设定另一个时钟来检测一帧数据是否发完。
所述的识别数据帧中各段电平的时间宽度为利用处理器的时间计数器寄存器实现。
步骤S4所述选定波特率的值包括如下步骤:
(1)接收方准备好备选波特率;
(2)与S3中识别的最小的电平时间宽度进行比较;
(3)将所有备选波特率的值与(2)中的最小的电平时间宽度值的差为排序标准做升序排列,选出差值最小时所对应的波特率的值,将此值作为时间基数base。
所述的备选波特率包括串口通信常用的115200、57600、38400、19200和9600,所对应的时间宽度的列表bv为1667、833、417、278和139。
步骤S5所述确定停止位的位数包括如下步骤:
(1)计算数据帧总位数num;
(2)依据算式N1=(num+sbn)/(Q1+N2+sbn)和R=(2*(num+sbn))%(2*(Q1+N2+sbn)),以及停止位位数sbn的备选值,选取R最小时sbn对应的值作为停止位的位数,其中N1为数据帧的全部字符个数,Q1为起始位位数,N2为数据位位数,R为指示变量。
所述停止位位数sbn的备选值为1、1.5或2。
步骤S6所述校验包括如下步骤:
(1)遍历数据帧内所有的电平,求得在以时间基数为基础偏移15%范围内的最大值作为偏移标准电平宽度值;
(2)遍历数据帧内所有电平,在偏移标准电平宽度值范围内,求取奇数位电平时间基数base奇和偶数位电平时间基数base偶,
(3)接收方根据事先约定的特征字串、数据位数以及S5中确定的停止位位数自动生成数组exp[i],数组exp[i]内的各元素依次表示特征字串在数据帧中各电平所占用的位数;
(4)接收方遍历接收到的数据帧,产生相应的数组exp’[i],数组exp’[i]内的各元素依次表示接收到的发送方发送的数据在数据帧中各电平所占用的位宽度;
(5)根据奇数位电平时间基数base奇和偶数位电平时间基数base偶的大小,判断数据帧是否包含特征字串;
(6)若校验成功,就继续完成下一步骤S7;如果校验失败就进入下一帧监听状态。
所述的求取奇数位电平时间基数base奇和偶数位电平时间基数base偶,包括如下步骤:
i)用数据帧范围内的每一个电平的时间宽度除以时间基数base,分别提取出整数部分和余数部分;
ii)判断每个电平各包含多少个数据位:判断余数部分,与时间基数base的比值大于50%就认为还有一个数据位,在相对应的整数部分加1;与时间基数base的比值小于50%就认为没有数据位,相对应的整数部分不动;如果比值等于50%,则无法判断,丢弃本串数据,进入下一次监听;
iii)依据ii)中的结果,记录电平的序号值,并且记录各序号所对应的电平宽度的值:记录电平的规则为:含有奇数个“位”的电平除了第一个(或最后一个)外,其他电平的时间宽度都取时间基数base,剩下的宽度就是这个第一个(或最后一个)的电平的时间宽度;含有偶数个“位”的电平,取该电平的时间宽度的平均值;
iv)所有奇数位电平的电平时间相加,并除以奇数位电平所占的位数,得到奇数位电平时间基数base奇;所有偶数位电平的电平时间相加,并除以偶数位电平所占的位数,得到偶数位电平时间基数base偶。
所述的判断数据帧是否包含特征字串,采用以下五个算式进行判断,其中“*”表示乘法运算:
①若base奇>base偶,且exp’[i]中元素相对应的电平为偶数位电平,则判定exp’[i]是否满足:(base*(exp[i]-1)+(base-offset)*0.5)< exp’[i]<(base* exp[i]*1.3) ;
②若base奇>base偶,且exp’[i]中元素相对应的电平为奇数位电平,则判定exp’[i]是否满足:(base*( exp[i]-1)+(base+offset)*1.5)> exp’[i]> (base* exp[i]*0.7);
③若base奇<base偶,且exp’[i]中元素相对应的电平为偶数位电平,则判定exp’[i]是否满足:(base*(exp[i]-1)+(base+offset)*1.5)> exp’[i]> (base* exp[i]*0.7);
④若base奇<base偶,且exp’[i]中元素相对应的电平为奇数位电平,则判定exp’[i]是否满足:(base*(exp[i]-1)+(base-offset)*0.5)< exp’[i]< (base* exp[i]*1.3);
⑤若base奇=base偶,则无论exp’[i]中元素相对应的电平为奇数位电平或偶数位电平,均判定exp’[i]是否满足:(base*( exp[i]-0.5) )< exp’[i]< (base*( exp[i]+0.5));
所述的识别整个数据帧,包括如下步骤:
(1)采用小循环遍历目标电平;
(2)获取目标电平所占的位数;
(3)在小循环中的判断目标电平的位数的过程中,对每一位进行判断,如果出现明显错误,则丢弃该数据帧,继续监听下一帧;若无明显错误,就记录数据位,并继续辨识下一电平,直至所有电平辨识完成;
(4)方法完成,得到最终的识别到的数据帧。
所述的采用小循环遍历目标电平,包括如下步骤:
依据奇数位电平时间基数base奇和偶数位电平时间基数base偶的大小,判断目标电平的位数,其中“*”表示乘法运算:
①若base奇>base低,且目标电平为奇数位电平,则判定目标电平的时间宽度T是否满足:((base+offset)*1.5)>T>base*0.7;
②若base奇>base偶,且目标电平为偶数位电平,则判定目标电平的时间宽度T是否满足:((base-offset)*0.5)<T<base*1.3;
③若base奇<base偶,且目标电平为奇数位电平,则判定目标电平的时间宽度T是否满足:((base-offset)*0.5)<T<base*1.3;
④若base奇<base偶,且目标电平为偶数位电平,则判定目标电平的时间宽度T是否满足:((base+offset)*1.5)>T>base*0.7;
⑤若base奇=base偶,则无论目标电平为偶数位电平或奇数位电平,均判定目标电平的时间宽度T是否满足:base*0.5<T<base*1.5;
所述的获取目标电平所占的位数,包括如下步骤:
(1)目标电平的位数N初始化为0;时间宽度值M初始化为目标电平的时间宽度;
(2)依据判断目标电平的位数的公式判断时间宽度值M:
1)若判断通过,则目标电平的位数值为N+1,结束判断;
2)若判断不通过且M比相应的判断公式中的下限值小,则结束算法,进行下一次监听;
3)若判断不通过且M比相应的判断公式中的上限值大,则目标电平的位数N增加1,时间宽度值M减去时间基数base;
4)重复步骤(2)进行判断,直至判断结束;
(3)判断结束,获取目标电平的位数。
所述的数据位数为8位。
本发明提供的这种串口自动识别方法,仅需发送方发送一次特征字串或者以特征字串开头的数据帧,就能完成发送方和接收方的串口检测和识别过程,适用于所有的串口通信识别和配对,特别适用于某些具有固定帧头的串口通信协议,而且,本发明提供的这种串口自动识别方法在第一次发送数据帧识别和匹配时就能在数据帧内包含命令或其他数据信息,相比现有技术需要单纯发送一帧纯粹的识别帧而言,节约了配对和识别时间。
具体实施方式
以下结合图2~4对本发明的方法进行进一步说明。
如图2所示为本发明的方法流程示意图;以下以特征字串为“AT”、数据位为8位、无奇偶校验位为例,对本发明的方法进行详细说明:
S1 配对的双方约定至少包含两个字符的特征字串和数据帧中数据位位数,因此数据位位数N2已知;而且约定特征字串中必须至少包含一个宽度为1位的电平,特征字串必须放在数据帧的开头位置,而且帧中不含奇偶校验位;本实施例中,特征字串为“AT”,数据位位数数N2为8,不含奇偶校验位;
S2 发送方按照通信双方的约定发送一帧数据帧;特征字串为“AT”,“A”对应的ASCII码对应为65,其8位二进制代码为01000001,“T”对应的ASCII码对应为84,其8位二进制代码为01010100,数据帧起始位为低电平,停止位为1位高电平,串口数据发送特征字串时是低位优先发送,因此包含特征字串“AT”的数据帧的串口波形图如图3所示,图3中上排标注的数字是数值,下排标注的数字是对应的序号,其中序号为0和10的是“AT”两字节的起始位,9和19是“AT”两字节的停止位;
S3 取得各段电平的时间宽度
用Int表示中断,用Tmt来表示计时时钟,用Tmo来表示用于检测一帧数据是否发完的超时时钟;在Int中,记录Tmt中的寄存器当前的“计数”值。是记录的时间点的值,本部分根据时间点的值计算出时间段的值,就是用后边的时间点的值减去前边的时间点的值的绝对值,注意取模的操作,即由于时间计数器寄存器的值都是循环着的,到了0又会变成最大值再做自减操作,这里的取模操作就是取的该时间寄存器的那个最大值;
S4 在备选波特率中选定波特率值
按照时间分频值和理论波特率的关系,准备好备选波特率每一位理论的时间宽度的列表bv(即baudrate value),本实施例中所用的bv包括{139,278,417,833,1667},分别对应115200,57600,38400,19200,9600波特率的时间宽度(以计时定时器所对应的寄存器的“1”为单位)。
扫描S3中所求得的所有时间宽度,分别求出最小的宽度段min和所有宽度的总和sum。
接收方同时将备选波特率每一位理论的时间宽度列表bv[1]、bv[2]…bv[i]…bv[N],和S3中识别的时间宽度最小的电平的时间宽度min进行比较,将所有的bv[1]~bv[N]的值与min值的差为排序标准做升序排列,初步选定最接近min的值的bv[i]作为base参与以下的计算。由于Min是取得的最小的电平宽度,它一定是比理论的备选bv值小或者是等于的;如果接到的是特征字串,是一定会有一个宽度为1位的电平,若接到的不是特征字串,在经过后续步骤校验时也会被过滤掉的。
若所有备选波特率均已被排除,则丢弃本串数据帧,进入下一帧监听状态;
S5 确定停止位的位数sbn:
求得总的“位”数num;num = sum / base,四舍五入取整。
计算停止位的位数sbn(stop bit num)。这里利用如下算式计算:
由于Q1为1,N2为8,因此num=N1*(1+8+sbn)-sbn(式1),最后减去一个sbn是由于一帧数据发完后电平会维持在高电平,不会再产生中断,因此最后一个字符的停止位的宽度是检测不出来的,所以要减去;N1为发送方发送的数据帧的全部字符的个数。其中sbn有且仅有三种情况,为1、1.5或2。为了减少计算时间,不出现浮点数的运算,把数字乘2,经变换后:
N1=(2*(num+sbn))/(2*(1+8+sbn)),由于N1为发送方发送的数据帧的全部字符的个数,因此一定为整数;
将sbn取值的三种情况分别带入算式R=(2*(num+sbn))%(2*(1+8+sbn)),式中%为取余数操作,将得到三组R的值,三组R的值各自对应于sbn的三种取值;
将三组R值做升序排列,依次选取R值所对应的sbn值作为停止位的位数,进入S6中做判断;
此外,由于sbn的取值不同,可能出现N1有不同的值情况出现,具体如下所述:
当num的值一定,当sbn取值分别为1、1.5和2时,利用式1求下式的N11、N12和N13的值:
num =N11*(1+8+1)-1=N12*(1+8+1.5)-1.5= N13*(1+8+2)-2;
可以算出,仅N1在1~1000的范围内,满足上式的N11和N12的值有(1,1)、(22,21)、(43,41)、……、(988,941),以N11为22,N12为21为例,num的值是相等的,均为219,此时计算出来的N11和N12所对应的R的值R1和R2也是相等的,R1=R2=2,暂时无法判断此时停止位的位数sbn的取值。因此,将两种sbn取值情况都进入下一步S6中,利用S6中特征字串波形检验来进行判断;
S6 校验是否是特征字串波形
(1)遍历数据帧内所有的电平,求得在以时间基数base为基础偏移x范围内的最大值作为偏移标准电平宽度值offest:本实施例中x取为15%;理论上每个数据位所占的时间宽度是相等的,但是由于实际应用中,串口发送的波形并不标准,则实际上每个数据所占用的时间宽度不同,但是,位数为奇数位的数据所占的时间宽度基本一致,位数为偶数位的数据所占的时间宽度基本一致,而且相邻两位的数据位所共同占用的时间宽度基本一致,且为base*2;如图3所示即为第0位和第1位的数据所占的时间宽度不同,第1位和第2位的数据所占的时间宽度不同,但是第0位、第2位、第4位……第18位数据所占的时间宽度基本一致,第1位、第3位、第5位……第19位数据所占的时间宽度基本一致,且第0位和第1位数据共同占用的时间宽度=第1位和第2位数据共同占用的时间宽度=……=base*2;
(2)遍历数据帧内所有电平,在offest范围内,分别求取奇数位电平时间基数base奇和偶数位电平时间基数base偶,具体方法如下,仍以特征字串“AT”为例,这里假定时间基数base为10,第0位数据时间宽度为为9,第1位数据时间宽度为11,第2位数据时间宽度为为9,第3位数据时间宽度为11,以此类推直至第19位;采用如图4所示的例子,则为第0位电平时间宽度为为9,第1位电平时间宽度为11,第2位电平时间宽度为49,以此类推;
i)用数据帧范围内的每一个电平的时间宽度除以base,分别提取出整数部分和余数部分(不考虑数据帧的最后一位,因为一帧数据发完后电平会维持在高电平,最后一位停止位无法判断);则示例的特征字串“AT”的各电平的时间宽度、整数部分和余数部分如下表所示:
ii)判断每个电平各包含多少个数据位:判断余数部分,与base的比值大于50%就认为还有一个数据位,在相对应的整数部分加1;与base的比值小于50%就认为没有数据位,相对应的整数部分不动;如果比值等于50%,则无法判断,丢弃该位数据,取下一个电平值;该步骤判定完成后,每个电平包含的数据位如下表所示:
通过第ii)步骤即可计算出该电平在数据帧中所包含的数据位的位数,以及实际所处的数据位为奇数位或者为偶数位;
iii)依据ii)中的结果,记录电平的序号值,并且记录各序号所对应的电平时间宽度的值:记录电平时间宽度的规则为:含有奇数个“位”的电平除了第一个(或最后一个)外,其他电平的时间宽度都取base,剩下的宽度就是这个第一个(或最后一个)的电平的时间宽度;含有偶数个“位”的电平,取各电平的时间宽度的平均值;该步骤完成后,每个位所占的时间宽度如下表所示:
iv)所有奇数位电平的电平时间相加,并除以奇数位电平所占的位数,得到奇数位电平时间基数base奇;所有偶数位电平的电平时间相加,并除以偶数位电平所占的位数,得到偶数位电平时间基数base偶;该步骤完成后,奇数位电平时间基数base奇=(11+10+10+11+11+10+11+11+11)/9=10.67;偶数位电平时间基数base偶=(9+10+10+9+9+10+9+9+9+9)/10=9.3;
(3)接收方根据事先约定的特征字串、数据位数以及S5中确定的停止位位数自动生成数组exp[i],数组exp[i]内的各元素依次表示特征字串在数据帧中各电平所占用的位数,本实施例中,如图4所示,停止位为1位,则exp[i]为[1,1,5,1,1,1,3,1,1,1,1,1,1,1],表示:标号为0的电平,其占用1位,标号为1的电平,占用1位,标号为2的电平占用5位,标号为3的电平占用1位,以此类推;
(4)接收方遍历接收到的数据帧,产生相应的数组exp’[i],数组exp’[i]内的各元素依次表示发送方发送的数据在数据帧中各电平所占用的位宽度;
(5)根据奇数位电平时间基数base奇和偶数位电平时间基数base偶的大小,分别依据以下三个公式判断数据帧是否包含特征字串:
①若base奇>base偶,且exp’[i]中元素相对应的电平为偶数位电平,则判定exp’[i]是否满足:(base*(exp[i]-1)+(base-offset)*0.5)< exp’[i]<(base* exp[i]*1.3) ;
②若base奇>base偶,且exp’[i]中元素相对应的电平为奇数位电平,则判定exp’[i]是否满足:(base*( exp[i]-1)+(base+offset)*1.5)> exp’[i]> (base* exp[i]*0.7);
③若base奇<base偶,且exp’[i]中元素相对应的电平为偶数位电平,则判定exp’[i]是否满足:(base*( exp[i]-1)+(base+offset)*1.5)> exp’[i]> (base* exp[i]*0.7);
④若base奇<base偶,且exp’[i]中元素相对应的电平为奇数位电平,则判定exp’[i]是否满足:(base*(exp[i]-1)+(base-offset)*0.5)< exp’[i]< (base* exp[i]*1.3);
⑤若base奇=base偶,则无论exp’[i]中元素相对应的电平为奇数位电平或偶数位电平,均判定exp’[i]是否满足:(base*( exp[i]-0.5) )< exp’[i]< (base*( exp[i]+0.5))
依据示例,base奇=11>base偶=9.46;
exp’[0]对应的为偶数位电平,则有:
base*(exp[i]-1)+(base-offset)*0.5=10*(1-1)+(10-1.5)*0.5=4.25;
exp’[i]=9;
base* exp[i]*1.3=10*1*1.3=13;
式①(base*(exp[i]-1)+(base-offset)*0.5)< exp’[i]<(base* exp[i]*1.3)成立,该位电平满足特征字串要求,继续判定下一位电平;
exp’[1]对应的为奇数位电平,则有:
base*( exp[i]-1)+(base+offset)*1.5=10*(1-1)+(10+1.5)*1.5=17.25;
exp’[i]=11;
base* exp[i]*0.7=10*1*0.7=7;
式②(base*( exp[i]-1)+(base+offset)*1.5)> exp’[i]> (base* exp[i]*0.7)成立,该位电平满足特征字串要求,继续判定下一位电平;
(6)按照以上5个公式校验数据帧,如果数据帧开头的代表特征字串的所有电平均校验成功,就继续完成下一步骤;如果校验失败就返回S5选取下一个R值所对应的sbn值再进行本步骤S6的校验,如果三组R值所对应的sbn值均检验失败,则排除当前的bv[i]的值,返回S4;
S7 识别整个数据帧
采用以下步骤识别整个数据帧:
(1)采用小循环遍历目标电平:
依据S6中奇数位电平时间基数base奇和偶数位电平时间基数base偶的大小,判断目标电平的位数:
①若base奇>base低,且目标电平为奇数位电平,则判定目标电平的时间宽度T是否满足:((base+offset)*1.5)>T>base*0.7;
②若base奇>base偶,且目标电平为偶数位电平,则判定目标电平的时间宽度T是否满足:((base-offset)*0.5)<T<base*1.3;
③若base奇<base偶,且目标电平为奇数位电平,则判定目标电平的时间宽度T是否满足:((base-offset)*0.5)<T<base*1.3;
④若base奇<base偶,且目标电平为偶数位电平,则判定目标电平的时间宽度T是否满足:((base+offset)*1.5)>T>base*0.7;
⑤若base奇=base偶,则无论目标电平为偶数位电平或奇数位电平,均判定目标电平的时间宽度T是否满足:base*0.5<T<base*1.5;
(2)判断目标电平的位数;
依据以下方法判断目标电平的位数:
1)目标电平的位数N初始化为0;时间宽度值M初始化为目标电平的时间宽度;
2)依据判断目标电平的位数的公式判断时间宽度值M:
①若判断通过,则目标电平的位数N+1,结束判断;
②若判断不通过且M比相应的判断公式中的下限值小,则表明该帧数据有问题,必须结束判断,并结束本算法,进行下一轮监听;
③若判断不通过且M比相应的判断公式中的上限值大,则目标电平的位数N增加1,时间宽度值M减去时间基数base;
④重复步骤2)的判断,直至判断结束;
3)判断结束,获取目标电平的数位值;
(3)在小循环中的判断目标电平的位数的过程中,对每一位进行判断,如果出现明显错误,如起始位出现高电平或者停止位出现低电平,则丢弃该数据帧,继续监听下一帧;若无明显错误,就记录数据位,并继续辨识下一电平,直至所有电平辨识完成,进步骤(4);
(4)方法完成,得到最终的识别到的数据帧,串口通信双方已经配对。