Найти в Дзене
IOT ENTERPRISE ©

CRC для EEPROM ARDUINO

/***
Автор: Кристофер Эндрюс (Christopher Andrews).
Алгоритм CRC сгенерирован инструментом pycrc (лицензия MIT, https://github.com/tpircher/pycrc).
CRC (циклический избыточный код) — простой способ проверить, не изменились ли данные и не повредились ли они.
Этот пример вычисляет значение CRC непосредственно для данных в EEPROM.
Цель примера — показать, что объект EEPROM можно использовать как обычный массив.
***/
#include <Arduino.h> // Подключаем основную библиотеку Arduino
#include <EEPROM.h> // Подключаем библиотеку для работы с энергонезависимой памятью EEPROM
void setup() {
// Запускаем последовательный порт (для вывода данных в монитор порта)
Serial.begin(9600);
// Ждём подключения последовательного порта (актуально только для встроенных USB‑портов)
while (!Serial) {
; // Пустой цикл — ждём, пока порт станет доступен
}
// Выводим длину данных, для которых будет рассчитываться CRC
Serial.print("Длина EEPROM: ");
Serial.println(E

/***
Автор: Кристофер Эндрюс (Christopher Andrews).
Алгоритм CRC сгенерирован инструментом pycrc (лицензия MIT, https://github.com/tpircher/pycrc).

CRC (циклический избыточный код) — простой способ проверить, не изменились ли данные и не повредились ли они.
Этот пример вычисляет значение CRC непосредственно для данных в EEPROM.
Цель примера — показать, что объект EEPROM можно использовать как обычный массив.
***/

#include <Arduino.h> // Подключаем основную библиотеку Arduino
#include <EEPROM.h> // Подключаем библиотеку для работы с энергонезависимой памятью EEPROM

void setup() {
// Запускаем последовательный порт (для вывода данных в монитор порта)
Serial.begin(9600);

// Ждём подключения последовательного порта (актуально только для встроенных USB‑портов)
while (!Serial) {
; // Пустой цикл — ждём, пока порт станет доступен
}

// Выводим длину данных, для которых будет рассчитываться CRC
Serial.print("Длина EEPROM: ");
Serial.println(EEPROM.length());

// Выводим результат вызова функции eeprom_crc()
Serial.print("CRC32 данных EEPROM: 0x");
Serial.println(eeprom_crc(), HEX); // Выводим в шестнадцатеричном формате
Serial.print("\n\nГотово!");
}

void loop() {
/* Пустой цикл — после setup() программа ничего не делает */
}

// Функция для вычисления CRC32 данных в EEPROM
unsigned long eeprom_crc(void) {
// Таблица предварительно вычисленных значений для ускорения расчёта CRC
const unsigned long crc_table[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};

// Начальное значение CRC (инвертированное)
unsigned long crc = ~0L;

// Проходим по всем байтам в EEPROM
for (int index = 0; index < EEPROM.length(); ++index) {
// Первый шаг расчёта CRC: используем младший полубайт текущего байта
crc = crc_table[(crc ^ EEPROM[index]) & 0x0f] ^ (crc >> 4);

// Второй шаг расчёта CRC: используем старший полубайт текущего байта
crc = crc_table[(crc ^ (EEPROM[index] >> 4)) & 0x0f] ^ (crc >> 4);

// Инвертируем значение CRC
crc = ~crc;
}

// Возвращаем итоговое значение CRC
return crc;
}

Пояснение к коду

  1. #include <Arduino.h>
    Подключает основную библиотеку Arduino, содержащую базовые функции и определения.
  2. #include <EEPROM.h>
    Подключает библиотеку для работы с EEPROM — энергонезависимой памятью микроконтроллера.
  3. void setup()
    Функция, выполняемая один раз при запуске программы:
    Serial.begin(9600) — инициализирует последовательный порт со скоростью 9600 бод для вывода данных.
    while (!Serial) — ждёт подключения последовательного порта (важно для плат с встроенным USB).
    Serial.print("Длина EEPROM: ") и Serial.println(EEPROM.length()) — выводит длину памяти EEPROM.
    Serial.print("CRC32 данных EEPROM: 0x") и Serial.println(eeprom_crc(), HEX) — вызывает функцию eeprom_crc() и выводит результат в шестнадцатеричном формате.
    Serial.print("\n\nГотово!") — выводит сообщение о завершении работы.
  4. void loop()
    Пустой цикл, так как после setup() программа не выполняет дополнительных действий.
  5. unsigned long eeprom_crc(void)
    Функция для вычисления CRC32 данных в EEPROM:
    const unsigned long crc_table[16] — таблица предварительно вычисленных значений, ускоряющая расчёт CRC.
    unsigned long crc = ~0L — начальное значение CRC (все биты инвертированы).
    Цикл for перебирает все байты в EEPROM (index от 0 до EEPROM.length() - 1).
    Внутри цикла:
    Первый шаг: использует младший полубайт (& 0x0f) текущего байта EEPROM для выбора значения из таблицы и обновляет crc.
    Второй шаг: аналогично использует старший полубайт (сдвинутый вправо на 4 бита).
    crc = ~crc — инвертирует текущее значение CRC.
    return crc — возвращает итоговое значение CRC после обработки всех байтов.