3、上位机接收和数据处理
根据表2的回送通信协议,上位机解析所接受的数据,并进行必要的处理。一般而言从下位机发送上来的数据都是有一定的帧长度。特别是对于一些固化好的智能仪表。所以最好的方法是按照通信回送的帧长度,在上位机程序中分别开辟两个同样长度的数组。一个作为接受数组,用来一次性接收串口缓冲区中的数据;另一个为安全数组,用来复制接收数组中的数据并进行解析。这样可以提高整个系统的容错能力。
LoopUntil frmcontrol.MSComm.InBufferCount = 9
InByte = frmcontrol.MSComm.Input
For i = 0 To (count - 1)
InSafeArray(i) = InByte(i)
Next i
其代码中的inbyte()就是接收数组,而InSafeArray()就是我们再开辟的安全数组。
4、CRC校验的实现方法
按照Modbus规约的校验方式,RTU模式的校验方式为CRC校验方式;而ASCII模式为LRC校验。一般的智能仪表多采用RTU的CRC校验方式。根据生成多项式的不同,CRC校验通常有以下几种:CRC-12 (传6bit);CRC-16(美国标准,传8bit);CRC-CCITT(欧洲标准,传8bit);CRC-32(point-to-point同步传输中使用) 。目前仪表类比较普遍的是CRC-16的校验码。其生成多项式为X16+X15+X2+1。在算法实现上,我们可以先预置一个16位的寄存器FFFF(全1),然后把8位的2进制数据(一个字节)与16位的CRC寄存器低8位异或,并把结果放回CRC寄存器同时寄存器内容右移,MSB补0,并检查移出的LSB。如果LSB为0则继续右移动,为1则CRC寄存器与多项式异或。重复上面操作到一个8bit字节完成,再继续对下一个数据进行相同处理,直到所有数据结束。这个时候CRC寄存器中的数据就是我们所要的CRC码了。实现代码如下:
CRC16Lo = &HFF ‘CRC16Lo为CRC寄存器低8位
CRC16Hi = &HFF ‘CRC16Hi为CRC寄存器高8位
CL = &H1
CH = &HA0 ‘A001 H 是CRC-16多项式代码
For i = 0 To UBound(Data)
CRC16Lo = CRC16Lo Xor Data(i) ‘每一个数据与CRC寄存器异或
For index = 0 To 7
UseHi = CRC16Hi
UseLo = CRC16Lo
CRC16Hi = CRC16Hi \ 2
CRC16Lo = CRC16Lo \ 2 ‘右移一位
If ((UseHi And &H1) = &H1) Then ‘如果高位字节最后一位是1的话
CRC16Lo = CRC16Lo Or &H80 ‘低位字节右移后前面补1
End If
If ((UseLo And &H1) = &H1) Then ‘'如果LSB 为1,则与多项式进行异或
CRC16Hi = CRC16Hi Xor CH
CRC16Lo = CRC16Lo Xor CL
End If
Next index
Next i