Перейти к содержанию

Калькулятор CRC

Вставьте байты в шестнадцатеричном виде или текст и выберите алгоритм — калькулятор посчитает CRC, покажет порядок байтов в кадре и сгенерирует функцию на C: компактную побитовую или быструю табличную. Для своего протокола задайте параметры вручную, а в режиме «Блок CRC STM32» получите то же значение, что вернёт аппаратный блок STM32 через HAL, и код его настройки.

Исходные данные

Расчёт

Он же MODBUS

Данные

01 03 00 0A, 0x01,0x03 или 01030A

Результат

CRC-16/MODBUS
0xCDC5
52677 в десятичной записи, 6 байт данных
Байты CRC в кадре
C5 CDмладший байт первым, как требует протокол
Кадр с CRC
01 03 00 00 00 0A C5 CD
В двоичном виде
1100 1101 1100 0101
Проверка «123456789»
0x4B37совпадает с каталогом CRC RevEng
Код на C
#include <stddef.h>
#include <stdint.h>

/* CRC-16/MODBUS: width 16, poly 0x8005, init 0xFFFF, refin true, refout true, xorout 0x0000, check 0x4B37 */
uint16_t crc16_modbus(const uint8_t *data, size_t len)
{
    uint16_t crc = 0xFFFF;

    while (len--) {
        crc ^= *data++;
        for (int i = 0; i < 8; i++)
            crc = (crc & 1) ? (uint16_t)((crc >> 1) ^ 0xA001) : (uint16_t)(crc >> 1);
    }
    return (uint16_t)(crc ^ 0x0000);
}

Расчёт выполнен по формулам и данным из источников, приведённых на этой странице, и не заменяет проверку: параметры компонентов у разных производителей и даже партий различаются. Перед применением сверяйте результат с документацией на конкретные детали.

CRC (циклический избыточный код) — контрольная сумма, которую передатчик дописывает в конец кадра, а приёмник пересчитывает по принятым данным. Математически это остаток от деления сообщения как двоичного многочлена на порождающий полином. CRC обнаруживает любую одиночную ошибку и любой пакет ошибок не длиннее разрядности CRC, а если полином делится на x + 1 — ещё и все ошибки с нечётным числом искажённых битов. Двойные ошибки CRC ловит гарантированно, только пока кадр короче периода полинома, поэтому полином выбирают под длину данных.

Параметры алгоритма

Любой распространённый CRC описывается шестью параметрами модели Rocksoft (Р. Уильямс, 1993):

ПараметрЧто задаётCRC-16/MODBUS
Widthразрядность CRC, бит16
Polyпорождающий полином без старшего бита0x8005
Initначальное значение регистра0xFFFF
RefInобрабатывать ли каждый байт младшим битом вперёдда
RefOutперевернуть ли биты результатада
XorOutс чем сложить по модулю 2 результат0x0000

Полином записывают без старшего бита: 0x8005 означает x¹⁶ + x¹⁵ + x² + 1. Отражённый алгоритм работает с перевёрнутым полиномом и сдвигает регистр вправо — поэтому в коде Modbus фигурирует 0xA001, а в коде CRC-32 — 0xEDB88320.

Одного полинома мало: CRC-16/CCITT-FALSE, CRC-16/KERMIT и CRC-16/XMODEM используют один и тот же 0x1021, но дают разные результаты. Для проверки служит контрольное значение — CRC от строки «123456789»; у каждого пресета калькулятор сверяет его с каталогом CRC RevEng.

Популярные алгоритмы

АлгоритмPolyInitRefIn/RefOutXorOutCheckГде используется
CRC-8/SMBUS0700нет00F4SMBus
CRC-8/MAXIM-DOW3100да00A11-Wire, DS18B20
CRC-8/NRSC-531FFнет00F7датчики Sensirion
CRC-16/MODBUS8005FFFFда00004B37Modbus RTU
CRC-16/IBM-3740 (CCITT-FALSE)1021FFFFнет000029B1многие протоколы
CRC-16/XMODEM10210000нет000031C3XMODEM, карты SD
CRC-16/KERMIT (CCITT)10210000да00002189Kermit, Bluetooth
CRC-15/CAN45990000нет0000059Eкадр CAN 2.0
CRC-32 (ISO-HDLC)04C11DB7FFFFFFFFдаFFFFFFFFCBF43926ZIP, PNG, Ethernet
CRC-32C1EDC6F41FFFFFFFFдаFFFFFFFFE3069283iSCSI, ext4
CRC-32/MPEG-204C11DB7FFFFFFFFнет000000000376E6E7MPEG-2, блок CRC в STM32

Все значения в шестнадцатеричном виде.

Modbus RTU

В Modbus RTU CRC считают по всем байтам кадра, начиная с адреса устройства. Регистр начинается с FFFF, на каждый байт выполняется XOR и восемь сдвигов вправо с полиномом A001, результат дописывают младшим байтом вперёд. Запрос «прочитать 10 регистров хранения, начиная с нулевого, у устройства 1» выглядит так: 01 03 00 00 00 0A C5 CD.

Приёмнику не нужно сравнивать CRC отдельно: если посчитать CRC-16/MODBUS по всему кадру вместе с двумя последними байтами, при правильной передаче получится ноль. Формат кадра, функции и паузы между кадрами разобраны в статье «Modbus RTU», а собрать или разобрать кадр целиком можно в инструменте Modbus RTU.

1-Wire и датчики

У 1-Wire последний байт 64-битного ROM-кода — CRC-8 полинома X⁸ + X⁵ + X⁴ + 1 (0x31) по первым семи байтам; той же CRC защищён блокнот DS18B20. Байты обрабатываются младшим битом вперёд, поэтому в каталоге это CRC-8/MAXIM-DOW с отражением. Датчики Sensirion используют тот же полином, но без отражения и с начальным значением FF: по даташиту SHT3x CRC от байтов BE EF равна 0x92. Подробнее о шине — в статье об 1-Wire.

STM32 и порядок байтов

Аппаратный блок CRC у STM32 по умолчанию считает с полиномом 0x04C11DB7 и начальным значением 0xFFFFFFFF без отражения и финального XOR — это параметры CRC-32/MPEG-2, а не «обычного» CRC-32 из ZIP. К тому же блок принимает 32-битные слова и обрабатывает каждое старшим битом вперёд. Если записывать в него байты потока словами на little-endian процессоре, порядок байтов внутри слова окажется обратным, и результат разойдётся с расчётом по байтам. Регистры блока CRC — на страницах STM32F1 и STM32F4.

Режим «Блок CRC STM32» повторяет расчёт аппаратного блока вместе с тем, как данные в него подаёт HAL. Блок STM32F1 и STM32F4 фиксирован: CRC-32 с полиномом 0x04C11DB7 по 32-битным словам (RM0008 и RM0090, раздел 4.4). У программируемого блока, например в STM32F3 (RM0316, глава 6), задаются размер полинома — 7, 8, 16 или 32 бита, — сам полином, начальное значение, разворот битов входа REV_IN по байтам, полусловам или словам и разворот результата REV_OUT. Финального XOR у блока нет — его делают программно.

Нужный CRCРазмер и полиномНачальноеREV_INREV_OUTПосле чтения
CRC-32 (ZIP, Ethernet)32 бита, 0x04C11DB70xFFFFFFFFпо байтамдаXOR 0xFFFFFFFF
CRC-16/MODBUS16 бит, 0x80050xFFFFпо байтамда—
CRC-16/XMODEM16 бит, 0x10210x0000нетнет—
CRC-8/SMBUS8 бит, 0x070x00нетнет—

Соответствие верно при формате данных HAL «байты» (CRC_INPUTDATA_FORMAT_BYTES): HAL_CRC_Calculate складывает каждые четыре байта в слово старшим байтом вперёд, а остаток дописывает 16- и 8-битными записями, так что блок видит байты в исходном порядке. Разворот REV_IN по байтам тогда равен отражению входа, а REV_OUT — отражению результата. Калькулятор показывает, какие записи уйдут в CRC_DR, и называет алгоритм каталога, если он совпадает с настройкой блока. Модель сверена с примерами STM32CubeF1 и STM32CubeF3: CRC-32 по 114 словам, CRC-7 потока байтов с полиномом 0x65, CRC-16 с разворотом по словам и CRC-8 с полиномом 0x9B.

Какой код выбрать

  • Побитовый — восемь итераций на байт и ни одной таблицы. Подходит для коротких кадров Modbus и 1-Wire на маленьком МК.
  • Табличный — один поиск в таблице на байт. Таблица на 256 значений занимает 256 байт для CRC-8, 512 байт для CRC-16 и 1 КБ для CRC-32 во флеш-памяти.

Сгенерированный код проверен: все пресеты калькулятора в обоих вариантах собраны компилятором MSVC с предупреждениями уровня 4 как ошибками и дают контрольное значение каталога. Функция принимает указатель на данные и длину и возвращает готовую CRC — с отражением и финальным XOR, если они нужны.

Если протокол свой, полином лучше брать из таблиц Ф. Купмана: он подобрал полиномы с наибольшим расстоянием Хэмминга для каждой длины данных.

Частые вопросы

Как посчитать CRC-16 для Modbus RTU?

Выберите CRC-16/MODBUS и вставьте байты кадра без CRC, например 01 03 00 00 00 0A. Получится 0xCDC5, а в кадр байты идут младшим вперёд: 01 03 00 00 00 0A C5 CD. Начальное значение регистра — FFFF, полином в отражённом виде — A001, финального XOR нет. Если посчитать CRC по всему принятому кадру вместе с двумя байтами CRC, должен получиться ноль.

Чем CRC-16/CCITT-FALSE отличается от CRC-16/CCITT?

У обоих полином 0x1021, но остальные параметры разные. CCITT-FALSE (в каталоге — CRC-16/IBM-3740) начинается с FFFF и обрабатывает биты старшим вперёд, контрольное значение 0x29B1. CRC-16/CCITT, он же KERMIT, начинается с нуля и работает с отражёнными байтами, контрольное значение 0x2189. Есть ещё XMODEM — ноль в начале без отражения, 0x31C3. Названия в разных библиотеках путают, поэтому сверяйте контрольное значение для строки «123456789».

Что такое контрольное значение check?

Это CRC от девяти ASCII-символов «123456789» — байты 31 32 33 34 35 36 37 38 39. По нему однозначно проверяют, что реализация и параметры совпадают с эталоном: у CRC-32 это 0xCBF43926, у CRC-16/MODBUS — 0x4B37. Калькулятор показывает check для выбранных параметров и сверяет его с каталогом CRC RevEng.

Что такое отражение входа и результата?

Отражение (RefIn) означает, что каждый байт обрабатывается младшим битом вперёд — так передаёт UART, поэтому отражённые CRC естественны для последовательных протоколов. RefOut переворачивает биты готового результата. В программе отражённый алгоритм сдвигает регистр вправо и использует перевёрнутый полином: для 0x8005 это 0xA001, для CRC-32 — 0xEDB88320.

Почему CRC-32 на STM32 не совпадает с онлайн-калькулятором?

Блок CRC STM32 по умолчанию считает CRC-32/MPEG-2: без отражения битов и без финального XOR, а «обычный» CRC-32 из ZIP отражает вход и результат и инвертирует его. На STM32F1 и STM32F4 блок не настраивается, и совпадения добиваются программно. У программируемого блока (например, STM32F3) включите REV_IN по байтам и REV_OUT, подавайте данные байтами и сделайте XOR результата с 0xFFFFFFFF — для строки «123456789» получится 0xCBF43926.

Табличный или побитовый расчёт CRC — что выбрать?

Побитовый алгоритм — несколько строк без таблицы, но 8 итераций цикла на каждый байт. Табличный обрабатывает байт за одну операцию, зато таблица занимает 256 значений: 256 байт для CRC-8, 512 для CRC-16 и 1 КБ для CRC-32 во флеш-памяти. На маленьком МК с короткими кадрами Modbus хватает побитового варианта, для потоков данных и CRC-32 выгоднее таблица.

Источники

  1. Ross N. Williams. A Painless Guide to CRC Error Detection Algorithms. 1993 — модель параметров Width, Poly, Init, RefIn, RefOut, XorOut; прямой и табличный алгоритмы
  2. Greg Cook. Catalogue of parametrised CRC algorithms (CRC RevEng) — параметры, псевдонимы и контрольные значения всех пресетов калькулятора
  3. Modbus Organization. MODBUS over Serial Line: Specification and Implementation Guide V1.02 — CRC в режиме RTU: начальное значение FFFF, полином A001, младший байт первым
  4. Maxim Integrated. Application Note 27: Understanding and Using Cyclic Redundancy Checks with Maxim 1-Wire and iButton Products — CRC-8 полинома X⁸ + X⁵ + X⁴ + 1 в ROM-коде 1-Wire
  5. Sensirion. Datasheet SHT3x-DIS, version 7, 2022 — CRC-8: полином 0x31, начальное значение 0xFF, пример CRC(0xBEEF) = 0x92
  6. STMicroelectronics. AN4187: Using the CRC peripheral in the STM32 family, rev. 2, 2022 — аппаратный блок CRC: полином 0x04C11DB7, начальное значение 0xFFFFFFFF, обработка 32-битных слов
  7. STMicroelectronics. RM0316 Rev 10. Reference manual: STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC, STM32F398xE — глава 6 — программируемый блок CRC: полином 7, 8, 16 или 32 бита, CRC_INIT, запись в CRC_DR словом, полусловом и байтом, REV_IN по байтам, полусловам и словам (пример 0x1A2B3C4D), REV_OUT (пример 0x11223344 → 0x22CC4488) — эталоны тестов
  8. STMicroelectronics. STM32CubeF1 и STM32CubeF3: примеры CRC и драйвер HAL (репозитории STM32CubeF1, STM32CubeF3, stm32f3xx-hal-driver) — CRC_Example (0x379E9F06 для 114 слов у F1 и F3), CRC_Bytes_Stream_7bit_CRC, CRC_Data_Reversing_16bit_CRC, CRC_UserDefinedPolynomial — эталоны тестов; HAL_CRC_Calculate складывает байты в слова старшим байтом вперёд и дописывает остаток записями по 16 и 8 бит
  9. Philip Koopman. Best CRC Polynomials — выбор полинома по расстоянию Хэмминга для заданной длины данных

Где пригодится

Встроить калькулятор на свой сайт

Скопируйте код и вставьте его в HTML страницы, статьи или вики. Виджет бесплатный, без рекламы, счётчиков и cookie. Условие одно — ссылка на GAW под рамкой остаётся на месте. Подробнее о виджетах

<iframe src="https://gaw.ru/embed/crc/" title="Калькулятор CRC" width="100%" height="640" style="border:1px solid #e3e5e9;border-radius:8px" loading="lazy" allow="clipboard-write"></iframe>
<p style="margin:6px 0 0;font-size:14px">Калькулятор: <a href="https://gaw.ru/tools/crc/">Калькулятор CRC</a> — GAW.ru</p>
Автоподстройка высоты рамки

Если сайт разрешает скрипты, добавьте этот код один раз в любом месте страницы: рамка будет менять высоту вместе с результатом расчёта.

<script>window.addEventListener("message",function(e){if(e.origin!=="https://gaw.ru"||!e.data||e.data.type!=="gaw:embed-height")return;var f=document.querySelectorAll('iframe[src^="https://gaw.ru/embed/"]');for(var i=0;i<f.length;i++)if(f[i].contentWindow===e.source)f[i].style.height=e.data.height+"px"})</script>

Обновлено .

Нашли ошибку в расчёте?