Структура данных в режиме RTU
В режиме RTU данные передаются младшими разрядами вперед (рис. 2.26).
По умолчанию в RTU режиме бит паритета устанавливают равным 1, если количество двоичных единиц в байте нечетное, и равным 0, если оно четное. Такой паритет называют четным (even parity) и метод контроля называют контролем четности.
Стартовый бит | 1 МЗР | Бит паритета | Стоп-бит | |||||||
Рис. 2.26. Последовательность битов в режиме RTU; МЗР – младший значащий разряд. При отсутствии бита паритета на его место записывается второй стоп-бит |
При четном количестве двоичных единиц в байте бит паритета может быть равен 1. В этом случае говорят, что паритет является нечетным (odd parity).
Контроль четности может отсутствовать вообще. В этом случае вместо бита паритета должен использоваться второй стоповый бит. Для обеспечения максимальной совместимости с другими продуктами рекомендуется использовать возможность замены бита паритета на второй стоповый бит.
Ведомые устройства могут воспринимать любой из вариантов: четный, нечетный паритет или его отсутствие.
Структура Modbus RTU сообщения
Сообщения Modbus RTU передаются в виде кадров, для каждого из которых известно начало и конец. Признаком начала кадра является пауза (тишина) продолжительностью не менее 3,5 шестнадцатеричных символов (14 бит). Кадр должен передаваться непрерывно. Если при передаче кадра обнаруживается пауза продолжительностью более 1,5 шестнадцатеричных символа (6 бит), то считается, что кадр содержит ошибку и должен быть отклонен принимающим модулем. Эти величины пауз должны строго соблюдаться при скоростях ниже 19200 бит/с, однако при более высоких скоростях рекомендуется использовать фиксированные значения паузы, 1,75 мс и 750 мкс соответственно.
Контроль ошибок
В режиме RTU имеется два уровня контроля ошибок в сообщении:
o контроль паритета для каждого байта (опционно);
o контроль кадра в целом с помощью CRC метода.
CRC метод используется независимо от проверки паритета. Значение CRC устанавливается в ведущем устройстве перед передачей. При приеме сообщения вычисляется CRC для всего сообщения и сравнивается с его значением, указанным в поле CRC кадра. Если оба значения совпадают, считается, что сообщение не содержит ошибки.
Стартовые, стоповые биты и бит паритета в вычислении CRC не участвуют.
Прикладной уровень
Прикладной уровень Modbus RTU обеспечивает коммуникацию между устройствами типа "ведущий/ведомый". Прикладной уровень является независимым от физического и канального, в частности, он может использовать протоколы Ethernet TCP/IP (Modbus TCP/IP), Modbus Plus (многомастерная сеть с передачей маркера), интерфейсы RS-232, RS-422, RS-485, оптоволоконные, радиоканалы и другие физические среды для передачи сигналов.
Прикладной уровень Modbus основан на запросах с помощью кодов функций. Код функции указывает ведомому устройству, какую операцию оно должно выполнить.
При использовании протокола прикладного уровня с различными протоколами транспортного и канального уровня сохраняется неизменным основной блок Modbus-сообщения, включающий код функции и данные (этот блок называется PDU - "Protocol Data Unit" - "элемент данных протокола"). К блоку PDU могут добавляться дополнительные поля при использовании его в различных промышленных сетях и тогда он называется "ADU" - "Application Data Unit" - "элемент данных приложения".
Коды функций
Стандартом Modbus предусмотрены три категории кодов функций: установленные стандартом, задаваемые пользователем и зарезервированные.
Коды функций являются числами в диапазоне от 1 до 127. Коды в диапазоне от 65 до 72 и от 100 до 110 относятся к задаваемым пользователем функциям, в диапазоне от 128 до 255 зарезервированы для пересылки кодов ошибок в ответном сообщении. Код «0» не используется.
Коды ошибок используются ведомым устройством, чтобы определить, какое действие предпринять для их обработки. Значения кодов и их смысл описаны в стандарте на Modbus RTU .
Поле данных (рис. 2.25) в сообщении, посланном от ведущего устройства ведомому, содержит дополнительную информацию, которую ведомое использует, чтобы выполнить функцию, указанную в поле «код функции». Поле данных может содержать значения состояний дискретных входов/выходов, адреса регистров, из которых надо считывать (записывать) данные, количество байт данных, ссылки на переменные, количество переменных, код подфункций и т. п.
Если ведомый нормально выполнил принятую от ведущего функцию, то в ответе поле «код функции» содержит ту же информацию, что и в запросе. В противном случае ведомый выдает код ошибки. В случае ошибки код функции в ответе равен коду функции в запросе, увеличенному на 128.
Содержание поля данных
В сообщении ведущего устройства ведомому поле данных содержит дополнительную информацию, необходимую для выполнения указанной функции. Например, если код функции указывает, что необходимо считать данные из группы регистров устройства ввода (код функции 03 hex), то поле данных содержит адрес начального регистра и количество регистров. Если ведущее устройство посылает команду записи данных в группу регистров (код функции 10 hex), то поле данных должно содержать адрес начального регистра, количество регистров, количество байтов данных и данные для записи в регистр.
Конкретное содержание поля данных устанавливается стандартом для каждой функции отдельно.
В некоторых сообщениях поле данных может иметь нулевую длину.
Список кодов Modbus
В табл. 2.13 приведен пример кодов Modbus RTU для модуля дискретного ввода и вывода типа RealLab! NL-16DI (фирмы НИЛ АП). Для чтения логических состояний входов модуля через интерфейс RS-485 необходимо послать команду в формате, показанном на рис. 2.25, где в полях "Адрес", "Код" указываются значения из соответствующих граф табл. 2.13. Подробный список команд можно посмотреть в формате pdfпо этой ссылке.
Табл. 2.13. Пример кодов протокола Modbus RTU для модуля RealLab! типа NL-16DI (pdf, 920 кб) | |||||
Обозначение регистра | HEX адрес регистра | Что читается или записывается | Код функции чтения регистра | Код функции записи в регистр | Примечание |
00h 00 h | Дискр. выход 0 | 1 или 0 | |||
00h 01 h | Дискр. выход 1 | 1 или 0 | |||
00h 00 h | Дискр. вход 0 | - | 1 или 0 | ||
00h 01 h | Дискр. вход 1 | - | 1 или 0 | ||
00h 02h | Дискр. вход 2 | - | 1 или 0 | ||
00h 03h | Дискр. вход 3 | - | 1 или 0 | ||
00h 04h | Дискр. вход 4 | - | 1 или 0 | ||
00h 05h | Дискр. вход 5 | - | 1 или 0 | ||
00h 06h | Дискр. вход 6 | - | 1 или 0 | ||
00h 07h | Дискр. вход 7 | - | 1 или 0 | ||
00h 08h | Дискр. вход 8 | - | 1 или 0 | ||
00h 09h | Дискр. вход 9 | - | 1 или 0 | ||
00h 0Ah | Дискр. вход 10 | - | 1 или 0 | ||
00h 0Bh | Дискр. вход 11 | - | 1 или 0 | ||
00h 0Ch | Дискр. вход 12 | - | 1 или 0 | ||
00h 0Dh | Дискр. вход 13 | - | 1 или 0 | ||
00h 0Eh | Дискр. вход 14 | - | 1 или 0 | ||
00h 0Fh | Дискр. вход 15 | - | 1 или 0 | ||
00h C8 h | Имя модуля | ||||
00 h D4h | Версия программы | - | |||
02h 00 h | Адрес модуля | 0001h-00 F7h (Допустимый диапазон значений) | |||
02h 01 h | Скорость UART | 0003h-000 Ah (Допустимый диапазон значений) | |||
02h 05 h | Протокол | 0000h– ASCII, 0001h - RTU | |||
03h 00 h | Значение на выходе после включения питания модуля Power On Value0 | 0000h-0003 h (Допустимый диапазон значений) |