Android串口MUDBUS指令及CRC16校验

前言

最近开发中用RS485串口命令去控制继电器和风机调速,用到了MUDBUS指令。通过串口会发送一串’ 01 06 00 01 01 00 D9 9A '这样的命令到继电器,从而达到控制的目的。起初,对这命令感到疑惑,最后经过文档查看及分析,发现不同的位代表了不同含义:设备地址(01)、功能号(06)、数据地址(0001)、数据(0100)、CRC16校验(D99A)。

其中CRC16校验是怎么得出的,由什么的得出的让我感到困惑,文档也没有说明,经过查阅发现CRC16校验是对前面的命令,也就是’ 01 06 00 01 01 00 ‘进行了CRC16校验计算,从而得到所需要的’D9 9A’ ,再进行发送。

CRC简介

CRC即循环冗余校验码(Cyclic Redundancy Check),是数据通信领域中最常用的一种查错校验码。奇偶校验虽然简单,但是漏检率太高,而CRC则要低的多,所以大多数都是使用CRC来校验。CRC只能检错,不能纠错。如果发现错误,可根据双方协议规定要求发送方重新发送。

原理

CRC校验,本质上是模2除法求余。将发送信息M(x)当做被除数,发送方和接收方共同约定一个除数G(x),然后求余R(x),该余数R(x)即为CRC值。原始信息中某位发生变化,则CRC值发生翻天覆地的变化,因此检错比较高效。

过程

发送方根据发送报文,计算出CRC值。将原始信息和该CRC值一起发送给接收方。接收方根据原始信息,按照同样的算法,计算CRC。如果计算的CRC值不正确的话,则表明在数据传输的过程中,原始信息(或者CRC值)发生错误。

CRC 计算

方法1:

/**
 * 计算CRC16校验码
 *
 * @param bytes 需要计算的字节数组
 */
public static String getCRC(byte[] bytes) {
   
    int CRC = 0x0000ffff;
    int POLYNOMIAL = 0x0000a001;

    int i, j;
    for (i = 0; i < bytes.length; i++) {
   
        CRC ^= ((int) bytes[i] & 0x000000ff);
        for (j = 0; j < 8; j++) {
   
            if ((CRC & 0x00000001) != 0) {
   
                CRC >>= 1;
                CRC ^= POLYNOMIAL;
            } else {
   
                CRC >>= 1;
            }
        }
    }
    return Integer.toHexString(CRC);
}

方法2:

/**
 * 查表法计算CRC16校验
 *
 * @param data 需要计算的字节数组
 */
public static String getTableCRC(byte[] data) {
   
    byte[] crc16_h = {
   
            (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
            (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
            (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
            (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
            (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
            (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值