PDA

Просмотр полной версии : Расчет CRC16 по полиному 8408



приборист
16.03.2015, 23:57
Доброй ночи :)

Подскажите люди добрые, почему у меня не выходит каменный цветок :)

Есть функция на делфи:
const _CR_CCNET_CRC_POLY = $08408

function GetCRC16(InData: array of byte; DataLng: word): word;
var i,TmpCRC: word;
j: byte;
begin
result:=0;
for i:=0 to (DataLng-1) do
begin
TmpCRC:=result xor InData[i];
for j:=0 to 7 do
begin
if (TmpCRC and $0001)<>0 then
begin
TmpCRC:=TmpCRC shr 1;
TmpCRC:=TmpCRC xor _CR_CCNET_CRC_POLY;
end
else
TmpCRC:=TmpCRC shr 1;
end;
result:=TmpCRC;
end;
end;

Переводим её в ST:
FUNCTION CRC : WORD
VAR_INPUT
InData:ARRAY [0..10] OF BYTE;
DataLng:WORD;
END_VAR
VAR
i, TmpCRC:WORD;
j:BYTE;


END_VAR
CRC:=16#0;
FOR i:=0 TO (DataLng-1) DO
TmpCRC:=CRC XOR InData[i];
FOR j:=0 TO 7 DO
IF (TmpCRC AND 16#0001) <> 0 THEN
TmpCRC:=SHR(TmpCRC ,1);
TmpCRC:=TmpCRC XOR 16#08408;
ELSE
TmpCRC:=SHR(TmpCRC ,1);
END_IF
CRC:=TmpCRC;
END_FOR
END_FOR

В итоге CRC рассчитывается неправильно. Почему - понять не могу :confused:

Причем один запрос обрабатывает верно.
Пример:
Данные


02 03 06 33
CRC
DA 81

Еще один 02 03 06 30, CRC 41 B3.

Хм, наткнулся на калькулятор, считает правильно - пишет что CRC называется CRC-CCITT (Kermit).
Пойду дальше гуглить.

приборист
17.03.2015, 07:42
А все дело в том, что к вечеру мозг отказывается работать.
Все работает :D

Тему можно закрывать.

sergeykrylov
17.03.2015, 12:11
Эта функция рукописная?

приборист
17.03.2015, 12:22
В каком смысле рукописная?
Функция описана в руководстве на прибор. Я переводил её в ST чтобы наладить обмен c прибором.

lara197a
17.03.2015, 12:24
в примерах овен где-то было такое.

Project M
19.08.2016, 11:21
На всякий случай выкладываю полностью рабочую функцию подсчёта CRC для CCNET.

FUNCTION GetCRC16 : WORD
VAR_INPUT
InData: POINTER TO ARRAY[0..255] OF BYTE;
LenData: WORD;
END_VAR

VAR CONSTANT
CCNET_CRC_POLY: WORD:= 16#8408;
END_VAR

VAR
i, j: INT;
CRC: WORD;
END_VAR

CRC:= 0;
FOR i:= 0 TO (LenData-1) DO
CRC:= CRC XOR BYTE_TO_WORD( InData^[ i ]);
FOR j:=0 TO 7 DO
IF (CRC AND 16#0001) <> 0 THEN
CRC:= SHR(CRC, 1);
CRC:= CRC XOR 16#8408;
ELSE
CRC:= SHR(CRC, 1);
END_IF;
END_FOR;
END_FOR;
GetCRC16:= CRC;

Newcomer
19.08.2016, 11:36
А что такое CCNET ?

приборист
19.08.2016, 12:04
А что такое CCNET ?
https://google.gik-team.com/?q=ccnet+%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%B E%D0%BB (https://google.gik-team.com/?q=CCNET)