博客
关于我
利用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事务与锁机制
    查看>>
    MTTR、MTBF、MTTF的大白话理解
    查看>>
    mt_rand
    查看>>
    mysql -存储过程
    查看>>
    mysql /*! 50100 ... */ 条件编译
    查看>>
    mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
    查看>>
    mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
    查看>>
    mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
    查看>>
    mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
    查看>>
    MySQL 8.0 恢复孤立文件每表ibd文件
    查看>>
    MySQL 8.0开始Group by不再排序
    查看>>
    mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
    查看>>
    multi swiper bug solution
    查看>>
    MySQL Binlog 日志监听与 Spring 集成实战
    查看>>
    MySQL binlog三种模式
    查看>>
    multi-angle cosine and sines
    查看>>
    Mysql Can't connect to MySQL server
    查看>>
    mysql case when 乱码_Mysql CASE WHEN 用法
    查看>>
    Multicast1
    查看>>
    mysql client library_MySQL数据库之zabbix3.x安装出现“configure: error: Not found mysqlclient library”的解决办法...
    查看>>