-1

我知道java byte 是一个 8 位有符号变量,要获得无符号(字节)值,我将不得不在0xff任何地方进行屏蔽。

Java 文档还说我可以通过前面提到的过程使用 int 生成无符号位。

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

但是,无论是否使用掩码,它都会返回相同的结果。

我正在尝试将short更改为 int 但没有成功。

德尔福代码

 procedure TForm1.ReadHoldRegisters(var lst: TList<byte>; deviceaddr: byte;
  RegisterAddress, RegisterLength: word);
begin

  lst.Add(deviceaddr);
  lst.Add(6);
  lst.Add(RegisterAddress div 256);
  lst.Add(RegisterAddress mod 256);
  lst.Add(RegisterLength div 256);
  lst.Add(RegisterLength mod 256);
    Add_CRC16(lst);
end;

 procedure TForm1.Add_CRC16(var Data: TList<byte>);
var
  CRC16Lo, CRC16Hi, CL, CH, SaveHi, SaveLo: byte;
  Flag: Integer;
  b: byte;
begin
  CRC16Lo := $FF;
  CRC16Hi := $FF;
  CL := $1;
  CH := $A0;

  for b in Data do
  begin
    CRC16Lo := CRC16Lo Xor b;

    For Flag := 0 To 7 Do
    Begin
      SaveHi := CRC16Hi;
      SaveLo := CRC16Lo;
      CRC16Hi := CRC16Hi Div 2;
      CRC16Lo := CRC16Lo Div 2;

      If ((SaveHi And $1) = $1) Then
      begin
           CRC16Lo := CRC16Lo Or $80;

      end;


      If ((SaveLo And $1) = $1) Then
      Begin
        CRC16Hi :=  CRC16Hi Xor CH;
        CRC16Lo := CRC16Lo Xor CL;

      End;

    End;


  end;

  Data.Add(CRC16Lo);
  Data.Add(CRC16Hi);

end;

Java 代码

public void ReadHoldRegisters(List<Short> lst, byte deviceaddr, char RegisterAddress, char RegisterLength)
{
    lst.add((short) (deviceaddr & 0xff));
    lst.add((short) ((byte) 6 & 0xff));
    lst.add((short) ((RegisterAddress / 256 & 0xff)));
    lst.add((RegisterAddress%256));
    lst.add((RegisterLength/256));
    lst.add(((RegisterLength%256)));
    Add_CRC16(lst);
}

private void Add_CRC16(List<Short> Data)
{
    //Cyclic Redundancy Check 16

    short  SaveLo, SaveHi;
    int flag;

    short CRC16Lo = ((short) 0xFF & 0xff);
    short CRC16Hi = ((short) 0xFF & 0xff);
    short CL      = (short) 0x1 & 0xff;
    short CH      = (short) (0xA0) & 0xff;

    short andop = ((short) 0x80 & 0xff);
    short andop2 = (short) 0x1 & 0xff;

    // início do for in
    for (Short b : Data)
    {
        CRC16Lo ^= b & 0xff;

        for(flag=0;flag<7;flag++)
        {
            SaveHi = (short) ((CRC16Hi) & 0xff);
            SaveLo = (short) ((CRC16Lo) & 0xff);

            CRC16Hi = (short) ((CRC16Hi/2) & 0xff);
            CRC16Lo = (short) ((CRC16Lo/2) & 0xff);

            if((SaveHi & andop2) == andop2 )
                CRC16Lo |= andop & 0xff;

                if(((SaveLo) & (andop2)) == (andop2))
                {
                    CRC16Hi ^= CH & 0xff;
                    CRC16Lo ^= CL & 0xff;
                }
            }

        }

        Data.add((short) (CRC16Lo & 0xff));
        Data.add((short) (CRC16Hi & 0xff));
    }

在这种情况下要显示的正确结果是“01 06 00 01 00 0A 58 0D”

有什么想法吗?有什么帮助吗?

4

1 回答 1

2

最明显的区别在这里:

for(flag=0;flag<7;flag++)

这个循环比 Delphi 版本少运行一次。你的意思是:

for(flag=0;flag<8;flag++)

最重要的是,Java 代码是不必要的复杂。它可以大大简化。该程序提供与 Delphi 代码相同的输出:

import java.util.*;

public class test 
{

    public static void ReadHoldRegisters(List<Integer> lst, int deviceaddr, int RegisterAddress, int RegisterLength)
    {
        lst.add(deviceaddr & 0xff);
        lst.add(6);
            lst.add((RegisterAddress >> 8) & 0xff);
            lst.add(RegisterAddress & 0xff);
            lst.add((RegisterLength >> 8) & 0xff);
            lst.add(RegisterLength & 0xff);
        Add_CRC16(lst);
    }

    private static void Add_CRC16(List<Integer> Data)
    {
        int SaveLo, SaveHi;
        int CRC16Lo = 0xFF;
        int CRC16Hi = 0xff;
        int CL      = 0x1;
        int CH      = 0xA0;

        for (int b : Data)
        {
            CRC16Lo ^= b;

            for (int flag=0; flag<8; flag++)
            {
                SaveHi = CRC16Hi;
                SaveLo = CRC16Lo;

                CRC16Hi = CRC16Hi/2;
                CRC16Lo = CRC16Lo/2;

                if((SaveHi & 0x01) == 0x01)
                    CRC16Lo |= 0x80;

                if((SaveLo & 0x01) == 0x01)
                {
                    CRC16Hi ^= CH;
                    CRC16Lo ^= CL;
                }
            }

        }

        Data.add(CRC16Lo & 0xff);
        Data.add(CRC16Hi & 0xff);
    }

    public static void main(String[] args) 
    {
        List<Integer> lst = new ArrayList<Integer>();
        ReadHoldRegisters(lst, 1, 1, 10);
        for (int value: lst)
        {
            System.out.print(String.format("%02x", value));
            System.out.print(" ");
        }
    }

}
于 2015-01-29T15:28:01.940 回答