博客
关于我
利用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/

    你可能感兴趣的文章
    PLSQL window操作
    查看>>
    plsql 存储过程 测试
    查看>>
    plsql 安装后database下拉没有东西
    查看>>
    PLSQL_Oracle PLSQL内置函数大全(概念)
    查看>>
    PLSQL_案例优化系列_体验逻辑结构如何影响SQL优化(案例3)
    查看>>
    PLSQL中INDEX BY TABLE的 DELETE操作
    查看>>
    plsql学习笔记---plsql相关概念,以及基础结构
    查看>>
    plsql数据库异常---plsql 登录后,提示数据库字符集(AL32UTF8)和客户端字符集(ZHS16GBK)不一致
    查看>>
    plsql查询乱码问题解决
    查看>>
    PLSQL的DBMS_GETLINE
    查看>>
    quartz简单demo,教你最快使用quartz
    查看>>
    PlutoSDR学习笔记(一)—函数API手册
    查看>>
    Quartz安装包中的15个example
    查看>>
    Quartz学习总结(2)——定时任务框架Quartz详解
    查看>>
    pm2 start命令中的json格式详解
    查看>>
    pm2启动报错
    查看>>
    pm2通过配置文件部署nodejs代码到服务器
    查看>>
    Unknown character set: 'utf8mb4'
    查看>>
    PML调用PDMS内核命令研究
    查看>>
    PMM安装-第一篇
    查看>>