1

ГЕНЕРАЦИЯ LRC/CRC в сообщении ModBUS

ГЕНЕРАЦИЯ LRC/CRC

Генерация LRC

Longitudinal Redundancy Check(LRC) это один байт. LRC вычисляется передающим устройством и добавляется к концу сообщения. Принимающее устройство также вычисляет LRC в процессе приема и сравнивает вычисленную величину с полем контрольной суммы пришедшего сообщения. Если суммы не совпали — то имеет место ошибка.

LRC вычисляется сложением последовательности байтов сообщения, отбрасывая все переносы, и затем двойным дополнением результата. LRC — это 8-ми битовое поле, где каждое новое прибавление символа, приводящее к результату более чем 255, приводит к простому перескакиванию через 0. Так как это поле не является 9-ти битовым, перенос отбрасывается автоматически.

Алгоритм генерации LRC:

1. Сложить все байты сообщения, исключая стартовый символ ‘:’ и конечные CRLF, складывая их так, чтобы перенос отбрасывался.

2. Отнять получившееся значение от числа FF(Hex) — это является первым дополнением.

3. Прибавить к получившемуся значению 1 — это второе дополнение.

РАЗМЕЩЕНИЕ LRC В СООБЩЕНИИ

Когда 8-ми битовое поле LRC (2 ASCII символа) передается в сообщении, то старший символ будет передан первым, а за ним — младший. Например, если значение LRC 61 hex(0110 0001):

 

‘:’ Адрес Функ ция Сч-к байт Байт Байт Байт Байт LRC Ст. LRC Мл. CR LF
6 1

 

Пример функции на языке C реализующей генерацию LRC приведен ниже. Функция принимает два аргумента:

unsigned char *auchMsg; Указатель на буфер данных

unsigned short usDataLen; Количество байт в буфере

Функция возвращает LRC как тип unsigned char.

ПРИМЕР

static unsigned char LRC(auchMsg, usDataLen)

unsigned char *auchMsg;/* Сообщение над которым */

/* вычисляется LRC */

unsigned char usDataLen; /* Количество байт в сообщении */

{

unsigned char uchLRC=0; /* Инициализация LRC */

while(usDataLen)

uchLRC+=*auchMsg++;

return((unsigned char)(-((char uchLRC)));

}

Генерация CRC

CRC это 16-ти разрядная величина т.е. два байта. CRC вычисляется передающим устройством и добавляется к сообщению.Принимающее устройство также вычисляет CRC в процессе приема и сравнивает вычисленную величину с полем контрольной суммы пришедшего сообщения. Если суммы не совпали — то имеет место ошибка.

16-ти битовый регистр CRC предварительно загружается числом FF hex. Процесс начинается с добавления байтов сообщения к текущему содержимому регистра. Для генерации CRC используются только 8 бит данных. Старт и стоп биты, бит паритета, если он используется, не учитываются в CRC.

В процессе генерации CRC, каждый 8-ми битовый символ складывается по ИСКЛЮЧАЮЩЕМУ ИЛИ с содержимым регистра. Результата сдвигается в направлении младшего бита, с заполнением 0 старшего бита. Младший бит извлекается и проверяется. Если младший бит равен 1, то содержимое регистра складывается с определенной ранее, фиксированной величиной, по ИСКЛЮЧАЮЩЕМУ ИЛИ. Если младший бит равен 0, то ИСКЛЮЧАЮЩЕЕ ИЛИ не делается.

Этот процесс повторяется пока не будет сделано 8 сдвигов. После последнего (восьмого) сдвига, следующий байт складывается с содержимым регистра и процесс повторяется снова. Финальное содержание регистра, после обработки всех байтов сообщения и есть контрольная сумма CRC.

Алгоритм генерации CRC:

1. 16-ти битовый регистр загружается числом FF hex (все 1), и используется далее как регистр CRC.

2. Первый байт сообщения складывается по ИСКЛЮЧАЮЩЕМУ ИЛИ с содержимым регистра CRC. Результат помещается в регистр CRC.

3. Регистр CRC сдвигается вправо(в направлении младшего бита) на 1 бит, старший бит заполняется 0.

4. (Если младший бит 0): Повторяется шаг 3 (сдвиг)

(Если младший бит 1): Делается операция ИСКЛЮЧАЮЩЕЕ ИЛИ регистра CRC и полиномиального числа A001 hex.

5. Шаги 3 и 4 повторяются восемь раз.

6. Повторяются шаги со 2 по 5 для следующего сообщения. Это повторяется до тех пор пока все байты сообщения не будут обработаны.

7. Финальное содержание регистра CRC и есть контрольная сумма.

РАЗМЕЩЕНИЕ CRC В СООБЩЕНИИ

При передаче 16 бит контрольной суммы CRC в сообщении, сначала передается младший байт, затем старший. Например, если CRC равна 1241 hex :

 

Адрес Функция Счетчикк байт Данные Данные Данные Данные CRC Ст. CRC Мл.
41 12

ПРИМЕР

Пример функции на языке C реализующей генерацию CRC приведен ниже. Все возможные величины CRC загружены в два массива. Один массив содержит все 256 возможных комбинаций CRC для старшего байта поля CRC, другой массив содержит данные для младшего байта. Идексация CRC в этом случая обеспечивает быстрое выполнение вычислений новой величины CRC для каждого нового байта из буфера сообщения.

Функция принимает два аргумента:

unsigned char *puchMsg; /* Указатель на буфер */

unsigned short usDataLen; /* Количество байтов в буфере */

Функция возвращает CRC как тип unsigned short.

static unsigned char auchCRCHi[] = { 0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×01,0xC0,0×80,0×41,0×00, 0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40,0×00,0xC1, 0×81,0×40,0×01,0xC0,0×80,0×41,0×01,0xC0,0×80,0×41,0×00,0xC1,0×81, 0×40,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40, 0×01,0xC0,0×80,0×41,0×01,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40,0×01, 0xC0,0×80,0×41,0×00,0xC1,0×81,0×40,0×00,0xC1,0×81,0×40,0×01,0xC0, 0×80,0×41,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×01,0xC0,0×80, 0×22,0×00,0xC1,0×81,0×40,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41, 0×01,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×00, 0xC1,0×81,0×40,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×01,0xC0, 0×80,0×41,0×00,0xC1,0×81,0×40,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80, 0×41,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×01,0xC0,0×80,0×41, 0×00,0xC1,0×81,0×40,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×01, 0xC0,0×80,0×41,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×00,0xC1, 0×81,0×40,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80,0×41,0×00,0xC1,0×81, 0×40,0×01,0xC0,0×80,0×41,0×00,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40, 0×01,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40,0×00,0xC1,0×81,0×40,0×01, 0xC0,0×80,0×41,0×01,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40,0×00,0xC1, 0×81,0×40,0×01,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40,0×01,0xC0,0×80, 0×41,0×01,0xC0,0×80,0×41,0×00,0xC1,0×81,0×40

}

static char auchCRCLo[] = { 0×00,0xC0,0xC1,0×01,0xC3,0×03,0×02,0xC2,0xC6,0×06,0×07,0xC7,0×05, 0xC5,0xC4,0×04,0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA, 0xCB,0x0B,0xC9,0×09,0×08,0xC8,0xD8,0×18,0×19,0xD9,0x1B,0xDB,0xDA, 0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,0×14,0xD4,0xD5,0×15, 0xD7,0×17,0×16,0xD6,0xD2,0×12,0×13,0xD3,0×11,0xD1,0xD0,0×10,0xF0, 0×30,0×31,0xF1,0×33,0xF3,0xF2,0×32,0×36,0xF6,0xF7,0×37,0xF5,0×35, 0×34,0xF4,0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,0x3B, 0xFB,0×39,0xF9,0xF8,0×38,0×28,0xE8,0xE9,0×29,0xEB,0x2B,0x2A,0xEA, 0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,0xE4,0×24,0×25,0xE5,0×27, 0xE7,0xE6,0×26,0×22,0xE2,0xE3,0×23,0xE1,0×21,0×20,0xE0,0xA0,0×60, 0×61,0xA1,0×63,0xA3,0xA2,0×62,0×66,0xA6,0xA7,0×67,0xA5,0×65,0×64, 0xA4,0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,0xAA,0x6A,0x6B,0xAB, 0×69,0xA9,0xA8,0×68,0×78,0xB8,0xB9,0×79,0xBB,0x7B,0x7A,0xBA,0xBE, 0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,0xB4,0×74,0×75,0xB5,0×77,0xB7, 0xB6,0×76,0×72,0xB2,0xB3,0×73,0xB1,0×71,0×70,0xB0,0×50,0×90,0×91, 0×51,0×93,0×53,0×52,0×92,0×96,0×56,0×57,0×97,0×55,0×95,0×94,0×54, 0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0×99, 0×59,0×58,0×98,0×88,0×48,0×49,0×89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E, 0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,0×44,0×84,0×85,0×45,0×87,0×47,0×46, 0×86,0×82,0×42,0×43,0×83,0×41,0×81,0×80,0×40

}

unsigned short CRC16(puchMsg, usDataLen)

unsigned char *puchMsg;

unsigned short usDataLen;

{

unsigned char uchCRCHi = 0xFF;

unsigned char uchCRCLo = 0xFF;

while (usDataLen—)

{

uIndex = uchCRCHi

*puchMsg++;

uchCRCHi = uchCRCLo

auchCRCHi[uIndex];

uchCRCLo = auchCRCLo[uIndex];

}

return (uchCRCHi << 8 | uchCRCLo);

}

 

    Раздел: modbus Метки: 

    1 комметарий к "ГЕНЕРАЦИЯ LRC/CRC в сообщении ModBUS"

    1. Eugene:

      в строке while(usDataLen) должно быть while(usDataLen—).

    Оставить комментарий

    Отправить сообщение

    CoDeSys GSM/GPRS модем Lectus OPC MasterSCADA Modbus MX110 Omron OPC-сервер owen OWEN Easy Logic owen logic PLC Configuration PROFIBUS s-200 SCADA scada системы siemens siemens plc SIMATIC Simplight SMS step7 TRACE MODE Динамизация ИП-320 ОВЕН ОВЕН ПЛК ОВЕН ПЧВ ПЛК ПЛК ОВЕН ПР 110 Панель оператора Программируемое реле Частотный преобразователь библиотека в CoDeSys визуализация диспетчеризация конфигурация панели программирование ПЛК серия NS сименс плк частотник частотное управление язык CFC язык ST
    .