用C#进行北斗串口编程之二:北斗2.1协议基础

上一章介绍了简短的几行C#代码,从串口读取北斗数据的方法。

这一章需要介绍一下北斗数据接口的基本协议,也就是类似下面的命令的含义。

$CCICA,0,0*4B\r\n

网上有很多比较早的代码是基于北斗4.0的协议,那个协议是一种二进制协议,编程人员需要认真准备数据中的每一个bit,如果出错,调试会极为困难。

所以后来出现了2.1协议,这个协议是文本协议,北斗终端中的芯片负责把它们转换成二进制,实际内部传输的仍是二进制,但编程起来更加容易,所以新的北斗终端都会支持2.1协议。

关于这个2.1协议,北斗官网上曾经公开过一份文档《北斗卫星导航系统用户终端通用数据接口(预)》,发布日期为2014年8月,后来这个资料被撤下了,但还能从其它地方找到,只是文档中有许多错误。

北斗指令

北斗指令以$开始(据说也可以是叹号!,但我现在还没遇到),然后是5个字符的指令代码,后面有多个参数,用逗号分隔,*表示指令结束,hh是校验码,最后是回车换行符,十六进制为0x0D和0x0A。

$CCICA,0,0*4B\r\n

指令代码为5个字符,前2个字符为发送器(信源)的标识符,后3个字符为语句标识符。

前2个字符的定义见下表:

标识符 发送器(信源)数据类型
BD 北斗导航定位系统(BDS)
GP 全球定位系统(GPS-global positioning system)
GN 全球导航卫星系统(GNSS-global navigation satellite system)
GL GLONASS系统
GA 伽利略系统
CC 计算机系统

后面3个字符的定义可参考《北斗卫星导航用户终端通用数据接口2.1协议》,不同的北斗厂商又增加了不同的自定义语句。

例如:CCICA、BDICI、BDGGA、GPGGA、GNGGA、GPGSA、CCRMO、CCTXA、BDFKI都是常用的指令。

校验码生成规则

hh校验码是$ 和*之间(不含$和*)所有字符的异或,然后用两个16进制大写字符表示,C#代码如下。

byte sum = 0;
foreach (char c in bdstr)
{
     
    if (c == '$' || c == '!') continue;
    if (c == '*') break;
    sum ^= (byte)c;
}
return sum.ToString("X2");

下面以$CCICA指令为例,说明校验码的生成过程。

用C#进行北斗串口编程之二:北斗2.1协议基础_第1张图片
根据这个规则,你可以自行验证一下,下面这行命令的校验码。

$BDICI,0925867,2204536,1934946,6,60,3,N,0*0F

实现一个小功能,发一行北斗命令,查看反馈信息

现在我们可以实现一个小功能,给串口写入一段北斗命令,立刻从串口读取一行信息,可以开展北斗命令的测试工作。

/// 
/// 这个函数不是非常严谨,由于串口通讯是异步的,
/// 你给串口写入一行命令,然后立即读串口,存在一定的概率,紧接的反馈文本行并不是你期望的结果,
/// 比如,你发送了$CCICA,可能并不能立即收到$BDICI反馈。
/// 
/// 串口
/// 北斗命令,程序自动补上校验码
/// 串口的一行反馈信息
static string SendCmd(SerialPort port, string cmd)
{
     
    cmd = cmd.Trim();
    cmd = cmd + "*" + CheckSum(cmd) + "\r\n";
    Console.Write("写串口:" + cmd);
    port.Write(cmd);
    return port.ReadLine();
}

/// 
/// 计算校验码, $和*(或行尾)之间(不含$和*)的所有字符的异或。
/// 
/// 北斗指令
/// 两个16进制数字,大写
static string CheckSum(string bdstr)
{
     
    byte sum = 0;
    foreach (char c in bdstr)
    {
     
        if (c == '$' || c == '!') continue;
        if (c == '*') break;
        sum ^= (byte)c;
    }
    return sum.ToString("X2");
}

现在主程序比较简单了,我们可以试验两条北斗命令的输出结果。SBX的反馈信息包括设备的厂商、类型、协议版本、序列号和卡号等信息。有关SBX的说明可以参看北斗2.1协议。

string result = SendCmd(port, "$CCICA,0,0");
Console.WriteLine(result);
result = SendCmd(port, "$CCRMO,SBX,2,0");
Console.WriteLine(result);

小结

1)4.0协议不好调试,常用2.1文本协议
2)$开头
3)命令有5个字符,前2个是信源,后3个是命令的含义
4)*hh是校验码,异或生成,两个16进制数
5)回车换行\r\n放末尾

你可能感兴趣的:(北斗,c#)