In Delphi, a Word
is a 16 bits unsigned variable (0..65535
).1
In Java, a char
variable is a 16‐bit Unicode character (0..65535
).2
I have the following code in Delphi:
procedure TForm1.ReadHoldRegisters(var lst: TList<byte>;
deviceaddr: byte;
RegisterAddress,
RegisterLength: word);
begin
lst.Add(deviceaddr);
lst.Add(3);
lst.Add(RegisterAddress div 256);
lst.Add(RegisterAddress 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 ((SaveLo And $1) = $1) Then
Begin
CRC16Hi := CRC16Hi Xor CH;
CRC16Lo := CRC16Lo Xor CL;
End;
End;
end;
Data.Add(CRC16Lo);
Data.Add(CRC16Hi);
end;
And it’s equivalent to Java:
public void ReadHoldRegisters(List<Byte> lst,
byte deviceaddr,
char RegisterAddress,
char RegisterLength)
{
lst.add(deviceaddr);
lst.add((byte) 3);
lst.add((byte) (RegisterAddress/256));
lst.add((byte) (RegisterAddress%256));
Add_CRC16(lst);
}
private void Add_CRC16(List<Byte> Data)
{
char SaveLo, SaveHi;
int flag;
char CRC16Lo = 0xFF;
char CRC16Hi = 0xFF;
char CL = 0x1;
char CH = 0xA0;
// beginning of do for in
for (Byte b : Data)
{
CRC16Lo = (char) ((CRC16Lo) ^ b);
for(flag=0;flag<7;flag++)
{
SaveHi = CRC16Hi;
SaveLo = CRC16Lo;
CRC16Hi = (char) (CRC16Hi/2);
CRC16Lo = (char) (CRC16Lo/2);
/*
if((SaveHi & 0x1) == 0x1 )
{
CRC16Lo = ((char) (CRC16Lo|0x80));
}
*/
if((SaveLo & 0x1) == 0x1 )
{
CRC16Hi = ((char) (CRC16Hi^CH));
CRC16Lo = ((char) (CRC16Lo^CL));
}
}
}
// end of do for in
CRC16Hi = (char) (CRC16Hi & 0xffff);
CRC16Lo = (char) (CRC16Lo & 0xffff);
Data.add((byte) CRC16Lo);
Data.add((byte) CRC16Hi);
}
Yet when I print the values by doing
for (Byte b : lst)
S = S + String.format("%1X ", b);
I get 01 03 00 20 F0
in Delphi and 1 3 0 D8 D9
in Java.
Assuming that char
and word
are equivalent variables, what’s going wrong with RegisterAddress
and RegisterLength
in my code?
As you said, a Delphi Word
is an unsigned 16 bit type. The Java char
likewise is an unsigned 16 bit type.
However, you mention Word
in the question, but it doesn't appear in the code. Well, you use Word
in ReadHoldRegisters
but nowhere in Add_CRC16
is the Word
type used. So, you aren't using Word
. You are using Byte
. So, the two variants of Add_CRC16
differ significantly because of that.
I've not looked at the rest of the code, but the mismatch between 8 bit Byte
in Delphi and 16 bit char
in Java is the most glaring issue. Start by fixing that problem, and see what comes next.
As a final aside, I recommend that you avoid the Delphi Basics website, especially for reference material. You are much better served by the official documentation. The relevant documentation for this question is Delphi Data Types.