3

编辑和解决(下)

我正在使用 Java for Android 尝试将字节 255(WriteSingleCoil 函数中的 0xFF)发送到 ModBUS 服务器设备。

设备没有运行,我不知道是因为无法解释有符号字节 -1 还是因为我错误地计算了 CRC。我不知道如何计算负字节的 CRC。

总结:我不知道如何发送函数 05 Write Single Coil with 0xFF value for switch on the coil for from Java to ModBUS server。

任何人都可以帮助我吗?

解决方案:

" iIndex = ucCRCLo ^ b: 这样的操作必须写成 iIndex = (ucCRCLo ^ b)&0xff 因为 & 会将 ucCRCLo, b 和结果转换为 int,它是 32 位,而 short 是 16,所以你会有很多额外位设置为 1"

这个答案帮助了我。非常感谢TheDayOfcondor

但我最大的问题也是Java中带有符号字节的常见问题。我的 CRC 计算函数对无符号字节是正确的,但如果我在有符号字节内传递它会出错。使用字节进行 ModBUS 通信的技巧是在整个应用程序中使用短字节作为字节,范围为 0-255,甚至计算电车和 CRC。并且仅在最后一步中,将 Trame 发送到 ModBUS 服务器时,再次将它们转换为字节。这正在运行。

希望它对将来的人有所帮助。

解释问题:

我正在尝试使用功能 05 将线圈设置为 ModBUS,这是对功能的解释:

要求

我正在尝试在地址 1 上设置线圈:

这个十六进制:0A 05 00 01 ff 00 DC 81

这个字节数组:10 5 0 1 255 0 220 129

10:从地址(10 = 0A hex)

05:功能代码(强制单线圈)

0001:线圈的数据地址。(线圈#1 = 01 十六进制)

FF00:要写入的状态(FF00 = ON,0000 = OFF)

DC81:用于错误检查的 CRC(循环冗余校验)。

问题是 Java 使用有符号字节,所以我不能将 255 放在我的字节数组上。我知道我应该输入 -1,但是我无法正确计算 CRC,因为我有几个预先计算的字节数组来获取 CRC,但函数发送一个负索引。

所以:我不知道我尝试发送-1是否正确,如果我有发送255的替代方法,也不知道如何计算-1的CRC。

这是计算CRC的函数:

public short[] GenerateCRC (byte[] pMsg) {
    short ucCRCHi = 0xFF;
    short ucCRCLo = 0xFF;
    int iIndex;

    for (byte b : pMsg)
    {
        iIndex = ucCRCLo ^ b;

        try {
            ucCRCLo = (short)(ucCRCHi ^ aucCRCHi[ ( iIndex ) ]);
            ucCRCHi = aucCRCLo[ ( iIndex ) ];
        } catch (Exception e) {
            Log.e(LOGTAG, "GenerateCRC: " + e.toString(), e);
            e.printStackTrace();
        }
    }

        short[]result= new short[2];
        result0]= ucCRCHi;
        result1]= ucCRCLo;

        return result;
}
4

1 回答 1

1

问题不是很清楚 - 但是,处理字节的最常见问题是 Java 没有无符号字节,布尔运算总是在 int 之间

处理字节的最好方法是使用整数,并且每次操作都使用 0xff。也使用 >>> 右移(它是无符号版本)

例子:

byte b= (byte)(255 & 0xff) // 给你“无符号字节”

byte b= (byte) ((b<<2)0xff ) // 左移必须被截断

如果您发布代码来计算 CRC,我可以查看一下

在不使用负数的情况下定义字节数组的最佳方法如下:

byte[]={ (byte)0xff, (byte)0xff, (byte)0xff };
于 2012-11-05T12:28:52.047 回答