RTCM

RTCM数据协议介绍

1. 一帧数据组成

2.数据接收

/*(1) synchronize frame */if (rtcm.nbyte == 0) {if (data != RTCM3PREAMB)//RTCM3PREAMB:同步码return 0;rtcm.buff[rtcm.nbyte++] = data; return 0;}//(2)添加一Byte数据 rtcm.buff[rtcm.nbyte++] = data; // (3)当Byte数量为3时,读取数据长度(一帧RTCM数据除去CRC的数据的Byte数)if (rtcm.nbyte == 3) { //getbitu(rtcm.buff, 14, 10)得到rtcm.buff第14个字节之后的10个字节信息。// ,+3表示前三个byte(同步码、保留位、数据长度) rtcm.len = (int)rtcmcmn.getbitu(rtcm.buff, 14, 10) + 3; /* length without parity */ }//(4)读取完成nbyte数重置 if (rtcm.nbyte < 3 || rtcm.nbyte < rtcm.len + 3) //+3表示比数据长度多接收3个Byte,其为为校验位return 0; rtcm.nbyte = 0;

实时数据传输进来经过(1)(2)(3)(4)四个步骤存储到buff中。

注:byte[] buff。每次接收1Byte(字节)数据对应8bit(位)

  • 位(bit):比特,指二进制中的一位,是二进制的最小信息单位。 bit也被称作小b,用b表示。(所以byte是大B),一个二进制数据0或1,是1bit。
  • 字节byte:1byte有8位 最大值为255 最小值是0 2^8-1=255
/*目的获取buff(byte数组)从pos位起始后len位表示的信息。 */ public static uint getbitu(byte[] buff, int pos, int len) { uint bits = 0; int i; try{for (i = pos; i < pos + len; i++) { //[i / 8] 取整,i % 8取余 bits = (bits << 1) + ((uint)(buff[i / 8] >> (7 - i % 8)) & 1u); } }return bits;}

注:[i / 8]:当前位i所在的buff索引,buff[i / 8] :包含当前位信息的字节(Byte),(buff[i / 8] >> (7 – i % 8):截取字节中i位的信息。(bits << 1) :将上一次循环计算得到的高位信息左移来保留高位信息。

3. CRC校验

再通过(4)判定之后,接受完一帧数据通过CRC校验保证数据的完整性。

//(5)校验位,校验数据是否完整if (rtcmcmn.crc24q(rtcm.buff, rtcm.len) != rtcmcmn.getbitu(rtcm.buff, rtcm.len * 8, 24)) {//trace(2, "rtcm3 parity error: len=%d\n", rtcm.len);return 0; }

CRC检校原理
模2除法
RTKLIB中CRC-24Q检校代码:

  crc = ((crc << 8) & 0xFFFFFF) ^ tbl_CRC24Q[(crc >> 16) ^ buff[i]];
  • crc << 8表示将32位的crc左移8位,低位补0。(crc <> 16表示将crc右移16位。
  • (crc >> 16) ^ buff[i] 表示对移位后的数据与buff[i]中的八位进行按位异或运算得到n
  • 最后根据计算结果n选取tbl_CRC24Q数组中的第n个数在与(crc << 8) & 0xFFFFFF进行按位异或运算。
    注:tbl_CRC24Q数组为八位二进制数组(即0-255的二进制表示),表示原始数据除以相应校验多项式后的余数表。

注:

<<:左移运算,a<<m,将a按二进制位向左移动m位,高位移除后,低位补0>>:右移运算,a>>m,将a按二进制位向右移动m位,低位移除后,高位补0^:按位异或运算,二进制逐位非或,从最小(及最右)的位开始,对操作位数逐位操作,相同 为0,不同为1。例如:X:0000 1011 1111 Y:1111 0101 1111 X^Y:1111 1110 00000xFFFFFF0x表示16进制,FFFFFFFF 一个F代表4位的1111

crc表介绍

常用数据类型