博客
关于我
利用Kotlin扩展函数实现MODBUS协议CRC16生成和校验
阅读量:776 次
发布时间:2019-03-23

本文共 2420 字,大约阅读时间需要 8 分钟。

Modbus协议CRC16指令

为了实现Modbus协议中的CRC16数据包校验,本文将详细介绍如何通过拼接命令、使用预定义方法生成CRC校验位,并验证计算结果。

获取CRC16校验位

在Modbus协议中,CRC16校验位是数据包的一个重要组成部分。为了获取CRC16校验位,拼接好命令后,可以将数据字节或整数值传递给crc16()方法。该方法将返回一个包含低有效八位和高有效八位的字节数组。通过将这个结果拼接到原始数据中,可以创建完整的数据包。

以下是获取CRC16校验位的步骤:

  • 创建初始化值:初始化结果值为0xFFFF
  • 迭代处理每个数据字节:对每个数据字节,更新结果值。具体方法是:将当前结果值与数据字节进行异或运算(使用FF掩码与65280进行按位与运算)。
  • 多位微程序轮回器:对每一位(从最低有效位到最高有效位),执行以下运算:
    • 如果当前结果值的最低有效位为1,则进行右移一位后进行异或POLYNOMIAL运算。
    • 否则,仅进行右移一位。
  • 生成CRC16校验位:最后,将结果值的高八位作为高有效字节,低八位作为低有效字节,拼接到原始数据中。
  • 验证CRC16校验位

    为了验证计算结果,可以使用crc16Verify()方法。该方法首先对数据包尾部的两字节进行校验:

  • 初始化结果值:设置为0xFFFF
  • 迭代处理数据包所有字节(除了最后两个校验位):更新结果值,按照与生成CRC16校验位相同的步骤。
  • 校验高低有效字节:将计算得到的高有效字节与实际数据包中的倒数第二个字节进行比较。同样,低有效字节与实际数据包中的最后一个字节进行比较。
  • 返回验证结果:如果两边完全一致,则返回true,表示校验成功。否则,返回false
  • 使用示例

    以下是一个使用示例:

    import java.lang.RuntimeExceptionconst val BITS_OF_BYTE = 8const val POLYNOMIAL = 0xA001const val INITIAL_VALUE = 0xFFFFconst val FF = 0xFFfun ByteArray.crc16(): ByteArray {    var res = INITIAL_VALUE    for (data in this) {        res = res xor (data.toInt() and FF)        for (i in 0 until BITS_OF_BYTE) {            res = if (res and 0x0001 == 1) {                res shr 1 xor POLYNOMIAL            } else {                res shr 1            }        }    }    val lowByte = (res shr 8 and FF).toByte()    val highByte = (res and FF).toByte()    return this.plus(highByte).plus(lowByte)}fun ByteArray.crc16Verify(): Boolean {    if (this.size < 3) throw RuntimeException("数组长度不合法")    var res = INITIAL_VALUE    for (index in 0..this.size - 3) {        res = res xor (this[index].toInt() and FF)        for (i in 0 until BITS_OF_BYTE) {            res = if (res and 0x0001 == 1) {                res shr 1 xor POLYNOMIAL            } else {                res shr 1            }        }    }    val lowByte = (res shr 8 and FF).toByte()    val highByte = (res and FF).toByte()    return highByte == this[this.size - 2] &&           lowByte == this[this.size - 1]}@Testfun testCPC16() {    val data: ByteArray = byteArrayOf(0x01, 0x06, 0x00, 0x47, 0x09, 0xC4.toByte())    val data2 = intArrayOf(0x01, 0x06, 0x00, 0x47, 0x09, 0xC4)    val data3 = byteArrayOf(        0x01, 0x06, 0x00, 0x47, 0x09, 0xC4.toByte(),        0x3E, 0x1C    )    println("CRC16计算结果:" + Crc16Util.byteTo16String(data.crc16()))    println("数组式计算结果:" + Crc16Util.byteTo16String(data2.crc16()))    println("完整数据校验:" + data3.crc16Verify())}

    以上代码示例展示了如何在Kotlin中实现CRC16数据包校验。通过对原始数据包进行计算并附加校验位,可以确保数据传输过程中的完整性和一致性。

    转载地址:http://zdczk.baihongyu.com/

    你可能感兴趣的文章
    MySQL集群解决方案(2):主从复制架构
    查看>>
    MySQL集群解决方案(3):MyCat中间件
    查看>>
    MySQL集群解决方案(4):负载均衡
    查看>>
    MySQL集群解决方案(5):PXC集群
    查看>>
    MySQL面试宝典
    查看>>
    WAP短信:融合传统短信和互联网的新型通信方式
    查看>>
    mysql面试题学校三表查询_mysql三表查询分组后取每组最大值,mysql面试题。
    查看>>
    Mysql面试题精选
    查看>>
    MySQL面试题集锦
    查看>>
    mysql面试题,存储引擎InnoDB和MyISAM
    查看>>
    mysql面试题:为什么MySQL单表不能超过2000W条数据?
    查看>>
    mysql面试题:创建索引时会不会锁表?
    查看>>
    mysql面试题:高度为3的B+树可以存放多少数据?
    查看>>
    mysql颠覆实战笔记(八)--mysql的自定义异常处理怎么破
    查看>>
    mysql驱动、durid、mybatis之间的关系
    查看>>
    mysql驱动支持中文_mysql 驱动包-Go语言中文社区
    查看>>
    MySQL高可用之——keepalived+互为主从
    查看>>
    MySQL高可用切换_(5.9)mysql高可用系列——正常主从切换测试
    查看>>
    MySQL高可用解决方案
    查看>>
    MySQL高可用解决方案详解
    查看>>