Ответы пользователя по тегу Modbus
  • Как исправить ошибку?

    Collin
    @Collin
    message, который заправляем в класс для расчёта CRC

    byte[] message = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, 0x00 }; // Последние 2 байта под CRC, заполняем нолями 
    byte[] CRC = (new byte[2]);
    
    GetCRC data = new GetCRC();
    data._GetCRC(message, ref CRC); // для этого примера CRC будет равно 0xDDBA, т.е. BA DD
    
    byte[] message_out = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, CRC[0], CRC[1] };


    Рассчитать CRC

    class GetCRC
        {
            // -----------------------------------------------------------------------------
            //Возвращает двухбайтовую контрольную сумму. + Алгоритм расчета CRC
            // -----------------------------------------------------------------------------
            public void _GetCRC(byte[] message, ref byte[] CRC)              // входные данные функции : byte[] message(см. строчку где message.Length)- это данные которые пришли в функцию,
                                                                             // входные данные функции: ref byte[] CRC - эти данные мы получаем внутри этой функции и потом выводим в тело
                                                                             // программы откуда мы вызвали эту ффункцию
            {
                ushort CRCFull = 0xFFFF;                                     // 16-ти битовый регистр загружается числом FF hex (все 1), и используется далее как регистр CRC
                char CRCLSB;                                                 // переменная определения значения младшего бита в цикле
                for (int i = 0; i < (message.Length) - 2; i++)               //Повторяются шаги для следующего сообщения(1). Это повторяется до тех пор пока все байты сообщения не будут обработаны.  
                {
                    CRCFull = (ushort)(CRCFull ^ message[i]);                // Первый байт сообщения (- 2 это отсекаем место под CRC) складывается по ИСКЛЮЧАЮЩЕМУ ИЛИ
                                                                             // с содержимым регистра CRC. Результат помещается в регистр CRC
                    for (int j = 0; j < 8; j++)                              // цикл повторяется 8 раз
                    {
                        CRCLSB = (char)(CRCFull & 0x0001);                   // Если младший бит 0. Повторяется сдвиг (следующая строка).
                        CRCFull = (ushort)((CRCFull >> 1) & 0x7FFF);         // Регистр CRC сдвигается вправо(в направлении младшего бита) на 1 бит, старший бит заполняется 0
                        if (CRCLSB == 1)                                     // Если младший бит 1
                            CRCFull = (ushort)(CRCFull ^ 0xA001);            // Делается операция ИСКЛЮЧАЮЩЕЕ ИЛИ регистра CRC и полиномиального числа A001 hex
                    }
                }
                CRC[1] = (byte)((CRCFull >> 8) & 0xFF);                      // определяем получившийся старший байт 
                CRC[0] = (byte)(CRCFull & 0xFF);                             // определяем получившийся младший байт 
            }
    
        }


    По теме:
    Калькулятор CRC
    Как посчитать контрольную сумму CRC (32, 16, 8)
    Статья о расчете CRC на хабре
    Ответ написан
    2 комментария