博客
关于我
利用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数据库表增添字段,删除字段、修改字段的排列等操作,还不快来
    查看>>
    MySQL数据库设计与开发规范
    查看>>
    MYSQL数据库进阶操作
    查看>>
    MySQL数据库配置文件调优详解
    查看>>
    MySQL数据库面试题(2021最新版)
    查看>>
    MySQL数据库高并发优化配置
    查看>>
    mysql数据恢复
    查看>>
    MySQL数据的主从复制、半同步复制和主主复制详解
    查看>>
    mysql数据碎片整理
    查看>>
    MySQL数据类型
    查看>>
    MySQL数据类型字节长度
    查看>>
    mysql数据被误删的恢复方案
    查看>>
    MySQL数据读写分离(MaxScale)上干货!!!
    查看>>
    mysql整库导入、导出
    查看>>
    mysql文本函数和数字函数
    查看>>
    Mysql新建用户和数据库并授权
    查看>>
    mysql日志文件
    查看>>
    mysql日志管理学习笔记
    查看>>
    mysql日志问题定位实用命令
    查看>>
    MySQL日期时间函数大全
    查看>>