Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кармин Новиелло - Освоение STM32.pdf
Скачиваний:
2751
Добавлен:
23.09.2021
Размер:
47.68 Mб
Скачать

Циклический контроль избыточности

453

предназначенный для работы на микроконтроллерах STM32F1/F2/F4/L1, будет работать на микроконтроллерах STM32F0/F3/F7/L0/L4 без каких-либо изменений.

16.2. Модуль HAL_CRC

CubeHAL предоставляет специальный модуль для управления регистрами периферийного устройства CRC: HAL_CRC. На периферийное устройство CRC ссылаются с помощью экземпляра структуры CRC_HandleTypeDef. В микроконтроллерах STM32F1/F2/F4/L1, предоставляющих простейшее периферийное устройство CRC, данная структура определена следующим образом:

typedef struct {

 

 

 

 

CRC_TypeDef

*Instance;

/* Базовый адрес регистров CRC

*/

HAL_LockTypeDef

Lock;

/*

Блокировка объекта CRC

*/

__IO HAL_CRC_StateTypeDef

State;

/*

Состояние работы CRC

*/

} CRC_HandleTypeDef;

 

 

 

 

Единственное важное поле – поле Instance, являющееся указателем на дескриптор периферийного устройства CRC (базовый адрес которого определяется макросом CRC).

Напротив, в микроконтроллерах STM32F0/F3/F7/L0/L4 структура CRC_HandleTypeDef определена следующим образом:

typedef struct {

 

 

 

CRC_TypeDef

*Instance;

/* Базовый адрес регистров CRC

*/

CRC_InitTypeDef

Init;

/* Параметры конфигурации CRC

*/

HAL_LockTypeDef

Lock;

/* Блокировка объекта CRC

*/

__IO HAL_CRC_StateTypeDef

State;

/* Состояние работы CRC

*/

uint32_t

InputDataFormat;

/* Задает формат входных данных

*/

} CRC_HandleTypeDef;

 

 

 

Единственное существенное отличие – наличие поля Init, используемого для конфигурации периферийного устройства CRC, как мы увидим через некоторое время, и поля InputDataFormat, задающего размер входных данных: оно может принимать значение из

таблицы 2.

Таблица 2: Форматы входных данных для периферийного устройства CRC

Формат данных

Описание

 

 

CRC_INPUTDATA_FORMAT_BYTES

Входными данными является поток байтов

 

(8-разрядные данные)

CRC_INPUTDATA_FORMAT_HALFWORDS

Входными данными является поток полуслов (16-разрядные данные)

CRC_INPUTDATA_FORMAT_WORDS

Входными данными является поток слов (32-разрядные данные)

Для конфигурации периферийного устройства CRC в данных микроконтроллерах мы используем экземпляр структуры CRC_InitTypeDef, которая определена следующим образом:

Циклический контроль избыточности

 

454

typedef struct {

 

 

uint8_t

DefaultPolynomialUse;

/* Указывает, используется ли полином

 

 

 

по умолчанию (default polynomial)

*/

uint8_t

DefaultInitValueUse;

/* Указывает, используется ли значение

 

 

 

инициализации по умолчанию (default init

 

 

 

value)

*/

uint32_t GeneratingPolynomial;

/* Устанавливает генераторный полином CRC

*/

uint32_t CRCLength;

/* Задает длину CRC

*/

uint32_t InitValue;

/* Устанавливает начальное значение для запуска

 

 

вычисления CRC

*/

uint32_t InputDataInversionMode;

/* Задает режим инверсии входных данных

*/

uint32_t OutputDataInversionMode;

/* Задает режим инверсии выходных данных

 

 

 

(т.е. CRC)

*/

} CRC_InitTypeDef;

 

 

Давайте проанализируем поля данной структуры:

DefaultPolynomialUse: это поле указывает, используется ли полином по умолча-

нию (то есть CRC-32) или пользовательский. Может принимать значения

DEFAULT_POLYNOMIAL_ENABLE или DEFAULT_POLYNOMIAL_DISABLE. В последнем случае должны быть установлены поля GeneratingPolynomial и CRCLength.

DefaultInitValueUse: это поле указывает, используется ли значение инициализа-

ции CRC по умолчанию (то есть 0xFFFF FFFF) или пользовательское. Может при-

нимать значения DEFAULT_INIT_VALUE_ENABLE или DEFAULT_INIT_VALUE_DISABLE. В по-

следнем случае должно быть установлено поле InitValue.

GeneratingPolynomial: устанавливает генераторный полином CRC. Это значения

длиной 7, 8, 16 или 32 бита для степени полинома, равной 7, 8, 16 или 32. Данное поле записывается в нормальном представлении, т.е., например, для полинома степени 7: X7 + X6 + X5 + X2 + 1 – записывается значение 0x65.

CRCLength: это поле указывает длину CRC, и оно может принимать значение из

таблицы 3.

InitValue: устанавливает пользовательское начальное значение для запуска вы-

числения CRC.

InputDataInversionMode: определяет, должны ли входные данные быть инвертиро-

ваны или нет. Может принимать значение из таблицы 4.

OutputDataInversionMode: определяет, должны ли выходные данные (вычислен-

ный CRC) быть инвертированными или нет. Может принимать значения CRC_OUT-

PUTDATA_INVERSION_DISABLE и CRC_OUTPUTDATA_INVERSION_ENABLE. В последнем случае

операция выполняется на уровне битов: например, выходные данные 0x1122 3344 преобразуются в 0x22CC 4488.

 

Таблица 3: Длина CRC

Длина CRC

Описание

 

 

CRC_POLYLENGTH_32B

32-разрядный CRC

CRC_POLYLENGTH_16B

16-разрядный CRC

CRC_POLYLENGTH_8B

8-разрядный CRC

CRC_POLYLENGTH_7B

7-разрядный CRC

Циклический контроль избыточности

455

Таблица 4: Режимы инверсии входных данных

Режим инверсии

Описание

 

 

CRC_INPUTDATA_INVERSION_NONE

Инверсия входных данных отсутствует

CRC_INPUTDATA_INVERSION_BYTE

Побайтовая инверсия: 0x1A2B 3C4D становится 0x58D4 3CB2

CRC_INPUTDATA_INVERSION_HALFWORD

Полусловная инверсия: 0x1A2B 3C4D становится 0xD458 B23C

CRC_INPUTDATA_INVERSION_WORD

Пословная инверсия: 0x1A2B 3C4D становится 0xB23C D458

Как только экземпляр структуры CRC_InitTypeDef определен, и его поля заполнены правильно, мы конфигурируем периферийное устройство CRC, вызывая функцию:

HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc);

Для вычисления контрольной суммы CRC буфера данных, мы используем функцию:

uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);

которая принимает указатель на массив типа uint32_t и его размер. Данная функция устанавливает исходное значение CRC по умолчанию 0xFFFF FFFF или указанное значение, если мы работаем с микроконтроллером STM32F0/F3/F7/L0/L4. Если вместо этого нам нужно вычислить CRC, начиная с предыдущего вычисленного CRC в качестве начального значения, то мы можем использовать функцию:

uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);

Это особенно полезно, когда мы вычисляем контрольную сумму CRC для большого блока данных, используя временный буфер, размер которого меньше размера исходного блока.