c - PIC 微 Controller 的 Modbus 功能代码 1 和 crc 检查

标签 c crc modbus crc16

我需要帮助计算功能代码 1 的 modbus CRC 检查。即读取线圈寄存器。我有功能代码 3 的 CRC 检查示例代码,即模拟输入的保持寄存器。

# Read Coil Status (FC=01)

## Request

该命令请求离散线圈#20至56的ON/OFF状态 来自地址为 17 的从设备。

11 01 0013 0025 0E84

  • 11:从地址(17 = 11 十六进制)
  • 01:功能代码(读取线圈状态)
  • 0013:要读取的第一个线圈的数据地址。 (线圈 20 - 1 = 19 = 13 十六进制)
  • 0025:请求的线圈总数。 (线圈 20 至 56 = 37 = 25 十六进制)
  • 0E84:CRC(循环冗余校验),用于错误检查。

响应

11 01 05 CD6BB20E1B 45E6

  • 11:从地址(17 = 11 十六进制)
  • 01:功能代码(读取线圈状态)
  • 05:后面的数据字节数(37 个线圈/每字节 8 位 = 5 个字节)
  • CD:线圈 27 - 20 (1100 1101)
  • 6B:线圈 35 - 28 (0110 1011)
  • B2:线圈 43 - 36 (1011 0010)
  • 0E:线圈 51 - 44 (0000 1110)
  • 1B:3 个空间支架和线圈 56 - 52 (0001 1011)
  • 45E6:CRC(循环冗余校验)。

读取保持寄存器(FC=03)

请求

该命令正在请求模拟输出保持寄存器#40108的内容 40110 来自地址为 17 的从设备。

11 03 006B 0003 7687

  • 11:从地址(17 = 11 十六进制)
  • 03:功能代码(读取模拟输出保持寄存器)
  • 006B:请求的第一个寄存器的数据地址。 (40108-40001 = 107 = 6B 十六进制)
  • 0003:请求的寄存器总数。 (读取3个寄存器40108至40110)
  • 7687:用于错误检查的 CRC(循环冗余校验)。

响应

11 03 06 AE41 5652 4340 49AD

  • 11:从地址(17 = 11 十六进制)
  • 03:功能代码(读取模拟输出保持寄存器)
  • 06:后面的数据字节数(3 个寄存器 x 每个 2 字节 = 6 字节)
  • AE41:寄存器40108的内容
  • 5652:寄存器40109的内容
  • 4340:寄存器40110的内容
  • 49AD:CRC(循环冗余校验)。

我对于获得 FC3 的回复没有问题。因为我正确发送了 2 字节地址,但我不知道如何发送单字节并修改 FC1 的 crc 函数 -> 读取线圈寄存器

Discription of read coil register

unsigned int crc_fn(unsigned char *dpacket,unsigned int len) { // CRC Function(Error calcualtion)
    unsigned int crc = 0xffff,poly = 0xa001;
    unsigned int i=0;

    for(i=0; i<len; i++) {
        crc^= dpacket[i];
        for(j=0; j<8; j++) {
            if(crc & 0x01) {
                crc >>= 1;
                crc ^= poly;
            } else
                crc >>= 1;
        }
    }
    return (crc);
}

最佳答案

CRC 通常首先附加到消息的最高有效字节。您需要交换两行代码,在低位字节之前发送 16 位 crc 的高位字节。尝试这个改变:

                Serial_1_Send_byte((unsigned char)(crc1>>8));
                Serial_1_Send_byte((unsigned char)crc1);

关于c - PIC 微 Controller 的 Modbus 功能代码 1 和 crc 检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51839991/

相关文章:

c - 拖动窗口的左边框时无法摆脱抖动

javascript - CRC具体如何使用?

c# - Modbus通讯

c# - 计算 CRC16 (Modbus) 值的函数

android - 最适合用于移植 Android 操作系统的基于 ARM 的开发套件

c - C中类型转换和按位运算的结果取决于顺序

c - 没有这样的文件或目录

c# - c#问题中的Xmodem-CRC协议(protocol)

c# - CRC 的生成速度有多快?

c 这个 while 循环完成的顺序是什么?