Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 20

Тема: Modbus RTU CRC16 полином A001h

  1. #1

    По умолчанию Modbus RTU CRC16 полином A001h

    Доброе время суток!
    Помогите разобраться с контрольной суммой. Я планирую использовать библиотеку UNM. Для того чтобы послать запрос с контрольной суммой нужно ее сначала вычислить . В документации есть пример на Си:

    CRC – код циклического контроля
    Контрольная сумма (CRC16) представляет собой циклический проверочный код на основе полинома A001h. Передающее устройство формирует контрольную сумму для всех байт передаваемого сообщения. Принимающее устройство аналогичным образом формирует контрольную сумму для всех байт принятого сообщения и сравнивает ее с контрольной суммой, принятой от передающего устройства. При несовпадении сформированной и принятой контрольных сумм генерируется сообщение об ошибке.
    Поле контрольной суммы занимает два байта. Контрольная сумма в сообщении передается младшим байтом вперед.
    Контрольная сумма формируется по следующему алгоритму:
    1) загрузка CRC регистра (16 бит) единицами (FFFFh);
    2) исключающее ИЛИ с первыми 8 битами байта сообщения и содержимым CRC регистра;
    3) сдвиг результата на один бит вправо;
    4) если сдвигаемый бит = 1, исключающее ИЛИ содержимого регистра со значением A001h;
    5) если сдвигаемый бит = 0, повторить шаг 3;
    6) повторять шаги 3, 4, 5, пока не будут выполнены 8 сдвигов;
    7) исключающее ИЛИ со следующими 8 битами байта сообщения и содержимым CRC регистра;
    8) повторять шаги 3 – 7, пока все байты сообщения не будут обработаны;
    9) конечное содержимое регистра будет содержать контрольную сумму.

    Пример программы CRC генерации кода с использованием языка С. Функция берет
    два аргумента:
    Unsigned char* data <- a pointer to the message buffer
    Unsigned char length <- the quantity of bytes in the message buffer

    The function returns the CRC value as a type of unsigned integer.
    Unsigned int crc_chk(unsigned char* data, unsigned char length)
    {int j;
    unsigned int reg_crc=0xFFFF;
    while(length--)
    {
    reg_crc ^= *data++;
    for(j=0;j<8;j++)
    {
    if(reg_crc & 0х01) reg_crc=(reg_crc>>1) ^ 0xA001; // LSB(b0)=1
    else reg_crc=reg_crc>>1;
    }
    }
    return reg_crc;
    }

    Может у кого есть пример вычисления СRC16 на ST ?

  2. #2

    По умолчанию

    FUNCTION_BLOCK CRC
    (*Процедура подсчета CRC*)
    (*
    (C) by Jeck 2009
    *)


    VAR_INPUT
    INPUT:ARRAY [0..1023] OF BYTE; (*входной буфер*)
    sz: DWORD;(*длина буфера*)
    END_VAR
    VAR_OUTPUT
    CRC16: WORD;
    END_VAR
    VAR
    B: INT;
    N: INT;
    C: BOOL;
    END_VAR

    ________________________________


    CRC16:=16#FFFF;
    B:=0;
    N:=0;
    REPEAT
    CRC16:= CRC16 XOR BYTE_TO_WORD(INPUT[B]);
    N:=0;
    REPEAT
    C:=CRC16.0;
    CRC16:=SHR(CRC16,1);
    IF C THEN
    CRC16:= CRC16 XOR 16#A001;
    END_IF
    N:=N+1;
    UNTIL
    N>7
    END_REPEAT
    B:=B+1;
    UNTIL
    B>sz
    END_REPEAT

  3. #3

    По умолчанию

    Спасибо всем за помощь! В первом примере удалось немного понять нюансы между Си и ST но полностю работоспособность этого примера я так и не проверил. А второй пример Jecka мне кажется проще и практически работает без проблем, вычисленная контрольная сума совпадает с примерами посылок в тех.док. Правда CRC16 выводится в виде десятичного значения и я калькуляторм перевел в шестнадцатиричный, а фактически мне нужно выделить младший и старший байт и прикрепить в конце посылки младшим байтом вперед. Пока есть другое задание и не хватает времени, но завершить эту задачу обязательно надо.

  4. #4

    По умолчанию

    Crc16_l.0:=crc16.0;
    Crc16_l.1:=crc16.1;
    Crc16_l.2:=crc16.2;
    Crc16_l.3:=crc16.3;
    Crc16_l.4:=crc16.4;
    Crc16_l.5:=crc16.5;
    Crc16_l.6:=crc16.6;
    Crc16_l.7:=crc16.7;

    Crc16_h.0:=crc16.8;
    Crc16_h.1:=crc16.9;
    Crc16_h.2:=crc16.10;
    Crc16_h.3:=crc16.11;
    Crc16_h.4:=crc16.12;
    Crc16_h.5:=crc16.13;
    Crc16_h.6:=crc16.14;
    Crc16_h.7:=crc16.15;


    Для какого протокола считаете?

  5. #5

    По умолчанию

    Спасибо! Ход мысли понял. Так я получаю двоичный код, который уже проще обработать.
    <Для какого протокола считаете?>
    Протокол Modbus RTU или я не правильно понял вопрос?

  6. #6

    По умолчанию

    а зачем тогда Unm? стандартный модуль чем не устроил?

  7. #7

    По умолчанию

    < а зачем тогда Unm? стандартный модуль чем не устроил?>
    Честно говоря, я просто еще и не пробовал, а подходящих примеров пока не нашел. А через UNM у меня есть небольшой опыт подключения вессового индикатора СAS CI-5010A к ПЛК-150IM по протоколу Modbus Ascii, хотя думаю, что это не единственный способ, но связь у меня получилась и не плохо работает.
    Последний раз редактировалось vojt; 24.01.2010 в 20:23.

  8. #8

    По умолчанию

    vojt, примеров валом. в полезностях.

  9. #9

    По умолчанию

    А какой стандартный модуль можно применить? И как там вычислять контрольную суму?

  10. #10

    По умолчанию

    Сформулирую по другому вопрос. В стандартном протоколе Modbus RTU контрольная сума CRC16 вычисляется по такому же алгоритму и с таким же полиномом А001h?

Страница 1 из 2 12 ПоследняяПоследняя

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •