2016-07-22 14 views
0

Здравствуйте Я Algo для CRC16 Modbus, но я не знаю, как я буду называть его и использовать,Как Usuage Crc16 ModBus в Delphi?

CONST table: ARRAY[0..255] OF WORD = 
     ($0000,$C0C1,$C181,$0140,$C301,$03C0,$0280,$C241,$C601,$06C0,$0780, 
     $C741,$0500,$C5C1,$C481,$0440,$CC01,$0CC0,$0D80,$CD41,$0F00,$CFC1, 
     $CE81,$0E40,$0A00,$CAC1,$CB81,$0B40,$C901,$09C0,$0880,$C841,$D801, 
     $18C0,$1980,$D941,$1B00,$DBC1,$DA81,$1A40,$1E00,$DEC1,$DF81,$1F40, 
     $DD01,$1DC0,$1C80,$DC41,$1400,$D4C1,$D581,$1540,$D701,$17C0,$1680, 
     $D641,$D201,$12C0,$1380,$D341,$1100,$D1C1,$D081,$1040,$F001,$30C0, 
     $3180,$F141,$3300,$F3C1,$F281,$3240,$3600,$F6C1,$F781,$3740,$F501, 
     $35C0,$3480,$F441,$3C00,$FCC1,$FD81,$3D40,$FF01,$3FC0,$3E80,$FE41, 
     $FA01,$3AC0,$3B80,$FB41,$3900,$F9C1,$F881,$3840,$2800,$E8C1,$E981, 
     $2940,$EB01,$2BC0,$2A80,$EA41,$EE01,$2EC0,$2F80,$EF41,$2D00,$EDC1, 
     $EC81,$2C40,$E401,$24C0,$2580,$E541,$2700,$E7C1,$E681,$2640,$2200, 
     $E2C1,$E381,$2340,$E101,$21C0,$2080,$E041,$A001,$60C0,$6180,$A141, 
     $6300,$A3C1,$A281,$6240,$6600,$A6C1,$A781,$6740,$A501,$65C0,$6480, 
     $A441,$6C00,$ACC1,$AD81,$6D40,$AF01,$6FC0,$6E80,$AE41,$AA01,$6AC0, 
     $6B80,$AB41,$6900,$A9C1,$A881,$6840,$7800,$B8C1,$B981,$7940,$BB01, 
     $7BC0,$7A80,$BA41,$BE01,$7EC0,$7F80,$BF41,$7D00,$BDC1,$BC81,$7C40, 
     $B401,$74C0,$7580,$B541,$7700,$B7C1,$B681,$7640,$7200,$B2C1,$B381, 
     $7340,$B101,$71C0,$7080,$B041,$5000,$90C1,$9181,$5140,$9301,$53C0, 
     $5280,$9241,$9601,$56C0,$5780,$9741,$5500,$95C1,$9481,$5440,$9C01, 
     $5CC0,$5D80,$9D41,$5F00,$9FC1,$9E81,$5E40,$5A00,$9AC1,$9B81,$5B40, 
     $9901,$59C0,$5880,$9841,$8801,$48C0,$4980,$8941,$4B00,$8BC1,$8A81, 
     $4A40,$4E00,$8EC1,$8F81,$4F40,$8D01,$4DC0,$4C80,$8C41,$4400,$84C1, 
     $8581,$4540,$8701,$47C0,$4680,$8641,$8201,$42C0,$4380,$8341,$4100, 
     $81C1,$8081,$4040); 

PROCEDURE CalcCRC16 (p: pByte; nbyte: WORD; VAR CRCvalue: WORD); 
VAR i: WORD; 
q: pByte; 
BEGIN 
    q := p; 
    FOR i := 1 TO nBYTE DO 
    BEGIN 
     CRCvalue := Hi(CRCvalue) XOR Table[ q^ XOR Lo(CRCvalue) ]; 
     INC(q) 
    END; 
END; 

7e 00 00 00 00 74 00 5e 01 5a 20 70 02 11 15 20 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

для Эти байты должны отвечать как «79 B7»

продвигайте всех и команду Stack Overflow!

ответ

1

Есть три недостающих кусочка головоломки. Во-первых, вам необходимо знать начальное значение CRCValue, чтобы перейти к CalcCRC16. Для Modbus CRC-16 это значение равно $ FFFF, как found here и here.

Во-вторых, вам нужно знать, что вычислить CRC. Все байты в вашем сообщении? Смежное их подмножество? Какой поднабор? Для этого вам нужно будет обратиться к какой-либо документации в формате, который вы используете.

В-третьих, как хранится CRC в потоке? Большой-endian или little-endian? Так что ваш 79 b7, предположительно из потока, означает 16-битное значение 79b7 или b779? Снова вам придется обратиться к документации.

Поиск всех возможных смежных подмножеств вашего сообщения не привел ни к 16-битовому CRC. Возможно, вы неправильно указали местоположение самого CRC в сообщении.

+0

Здравствуйте, Спасибо за ответ, это мое было плохо, я извиняюсь, 7E первый префикс, так: от CRC: 00 00 00 00 74 00 5e 01 5a 20 70 02 11 15 20 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b9 79 crc –

+0

Поэтому, прежде чем это было b7. Теперь это b9. Что он? В любом случае для любого CRC в любом порядке нет соответствия ни с одним подмножеством данных. –

+0

Thaks для ответа, я нахожу решение этого, http://i.hizliresim.com/2ZB8jE.png, мой плохой с другим префиксом я пытался ... спасибо еще раз. –

0
**Original Code from Sky devil** 
------------------------------- 
function GetModbusCRC16(const HexData: string): UInt16; 
var 
Buffer: Array of Byte; //TArray<Byte>; 
CRC: UInt16; 
Mask: UInt16; 
I: Integer; 
J: Integer; 
begin 
SetLength(Buffer, Length(HexData) div 2); 
HexToBin(PChar(HexData), Buffer, Length(Buffer)); 

CRC := $FFFF; 
for I := Low(Buffer) to High(Buffer) do 
begin 
CRC := CRC xor Buffer; 
for J := 1 to 8 do 
begin 
Mask := 0; 
if ((CRC/2) <> (CRC div 2)) then 
begin 
Mask := $A001; 
end; 
CRC := (CRC div 2) and $7FFF; 
CRC := CRC xor Mask; 
end; 
end; 

//--------------------------------------------------------- Swap result 
//Result := CRC; <- comment this 
// Swap lo/hi 
Result := ((CRC and $FF) shl 8) + (CRC shr 8); 
end; 


var 
C: UInt16; 
S: string; 

begin 
C := GetModbusCRC16('01030400000060'); 
S := IntToHex(C,4); // <- $FA1B 
end; 


**VB version original from internet**: 
------------------------------------ 

Sub getCRC16_Modbus() 
    Dim x As Long 
    Dim mask, i, j, nC, Crc As Integer 
    Dim c As String 
    Dim txt As String 

    txt = "01030400000060" 

    Crc = &HFFFF ' crc mit $ffff initalisieren 

    For nC = 1 To Len(txt) Step 2 
     j = Val("&H" + Mid(txt, nC, 2)) 'im HEX-Format 
     Crc = Crc Xor j 
     For j = 1 To 8 
      mask = 0 
      If Crc/2 <> Int(Crc/2) Then mask = &HA001 
      Crc = Int(Crc/2) And &H7FFF : Crc = Crc Xor mask 
     Next j 
    Next nC 

    txt = Hex$(Crc) 'Checksumme 

    Label1.Text = txt 

End Sub 
+1

Ответы наиболее полезны, когда они дают краткое объяснение того, как и почему представленный код отвечает на вопрос. –