Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CRC 16 modbus

93 views
Skip to first unread message

werbe

unread,
Feb 16, 2012, 1:42:25 PM2/16/12
to kamil....@gmail.com
Witam,

Czy ktoś mógłby mi pomóc i wskazać błąd. Poniżej przedstawiam dwie
alternatywne metody liczące CRC 16 dla modbus: getCRC i getCRC_2.
Ogólnie wartości CRC przez nie zwracana są OK, np: dla 0103044C005641
dostaje 1333, dla 0103075C0002 dostaje 056D i są to wartości
prawidłowe.
Ale przykładowo dla 0103043E947AC0 dostaje w getCRC 2BF7, w getCRC_2
94B7 i nie są to wartości prawidłowe bo powinienem dostać: 9507.

public static byte[] getCRC(byte[] values) {
int crc = 0x0ffff;
byte lastbit;

for (int i = 0; i < values.length; i++) {
byte thisbyte = values[i];
crc = crc ^ thisbyte;
for (int shift = 1; shift <= 8; shift++) {
lastbit = (byte)(crc & 0x0001);
crc = (crc >> 1) & 0x07fff;

if (lastbit == 1) {
crc = crc ^ 0x0A001;
}
}
}

byte[] CRC = new byte[2];
CRC[0] = (byte) (crc & 0xff);
CRC[1] = (byte) ((crc >> 8) & 0xff);


return CRC;
}


public static byte[] getCRC_2(byte[] values) {
int crc;

crc = 0x0FFFF;
for (int i = 0; i < values.length; i++) {
crc = crc ^ values[i];

for (int n = 0; n < 8; n++) {
if ((crc & 0x01) != 0)
crc = (crc >> 1) ^ 0x0A001;
else
crc = crc >> 1;
}
}

byte[] CRC = new byte[2];
CRC[0] = (byte) (crc & 0x0ff);
CRC[1] = (byte) ((crc >> 8) & 0x0ff);

return CRC;
}

Co jest nie tak? Z góry wielkie dzięki za pomoc.

Pozdrawiam
Kamil

Sebastian Biały

unread,
Feb 16, 2012, 1:51:31 PM2/16/12
to
On 2012-02-16 19:42, werbe wrote:
> [ciach]

Sprawdź tą (za jakośc kodu nie odpowiadam ;):

int crc( String _bytes )
{
int crcresult=0xffff;
int size=_bytes.length();
int i=0,j;
while(0!=size--)
{
crcresult^=(int) _bytes.charAt(i++);
for(j=0;j<8;j++) {
if((crcresult&1)==1) {
crcresult=(crcresult>>1)^0xa001;
} else crcresult>>=1;
}
}
return crcresult&0xffff;
}

Bogusław Szczepanowski

unread,
Feb 16, 2012, 3:52:35 PM2/16/12
to
Dnia 16-02-2012 o 19:42:25 werbe <kamil....@gmail.com> napisał(a):

> Witam,
>
> Czy ktoś mógłby mi pomóc i wskazać błąd. Poniżej przedstawiam dwie
> alternatywne metody liczące CRC 16 dla modbus: getCRC i getCRC_2.
> Ogólnie wartości CRC przez nie zwracana są OK, np: dla 0103044C005641
> dostaje 1333, dla 0103075C0002 dostaje 056D i są to wartości
> prawidłowe.
> Ale przykładowo dla 0103043E947AC0 dostaje w getCRC 2BF7, w getCRC_2
> 94B7 i nie są to wartości prawidłowe bo powinienem dostać: 9507.

Zmienne w Javie są signed.

private static int makeUnsigned(byte b)
{
return b < 0 ? b + 256 : b;
}

public static byte[] getCRC_2(byte[] values)
{
int crc = 0x0FFFF;
for (int i = 0; i < values.length; i++) {
int val = makeUnsigned(values[i]);
crc = (crc ^ val);

for (int n = 0; n < 8; n++) {
boolean lastbit = (crc & 0x01) != 0;
crc = (crc >> 1);
if (lastbit) {
crc = (crc ^ 0x0A001);
}
}
}

byte[] CRC = new byte[2];
CRC[0] = (byte)(crc & 0x0ff);
CRC[1] = (byte)((crc >> 8) & 0x0ff);

return CRC;
}


--
Boguś

werbe

unread,
Feb 16, 2012, 4:34:21 PM2/16/12
to
On 16 Lut, 21:52, Bogusław Szczepanowski <no...@invalid.net> wrote:
No fakt! Jak miałem w values same dodatnie wartości to wszystko
działało. Jak pojawiła się jakaś ujemna wartość to się wszystko
chrzaniło.

WIELKIE dzięki za pomoc!

Kamil
0 new messages