Главная » Руководства » Реализация сервера Modbus TCP на S7‑1200: полное руководство

Siemens 6ES7215-1HG31-0XB0 Центральный процессор CPU 1215C для SIMATIC S7-1200. Характеристики: DC/DC/Relay, 14 DI, 10 DO, 2 AI, 2 AO, 2 PROFINET, память 100 КБ, IP20.

Реализация сервера Modbus TCP на S7‑1200: полное руководство

Применяемое ПО: TIA Portal V19 (подойдут V13–V20)
Оборудование: S7‑1200 (прошивка ≥4.2), S7‑1500 (прошивка ≥2.5)


Содержание

  1. Введение: что такое сервер Modbus TCP и зачем он нужен
    • Отличие сервера (Slave) от клиента (Master)
    • Преимущества использования встроенных библиотек Siemens
  2. Терминология и структура данных Modbus
    • Объекты данных: катушки, дискретные входы, входные регистры, регистры хранения
    • Как эти объекты отображаются в S7‑1200/1500
  3. Подготовка проекта в TIA Portal
    • Требования к версиям ПО и прошивкам
    • Создание блока данных с неоптимизированным доступом для регистров хранения
  4. Пошаговая настройка блока MB_SERVER
    • 4.1. Добавление блока и настройка интерфейса
    • 4.2. Создание структуры TCON_IP_v4 для соединения
    • 4.3. Присвоение идентификатора интерфейса (InterfaceId)
    • 4.4. Подача области регистров хранения на MB_HOLD_REG
  5. Ограничение доступа к катушкам и дискретным входам
    • Зачем это нужно
    • Установка QB_Count, QB_Read_Count, IB_Count = 0
  6. Проверка работоспособности
    • Использование стороннего Modbus-клиента
    • Контроль порядка байт (Endianness)
    • Чтение и запись регистров хранения
  7. Особенности работы с разными типами данных
    • Использование массивов WORD в оптимизированных DB
    • Эксперименты: что работает, а что нет
    • Рекомендации по выбору области памяти
  8. Типичные ошибки и способы их устранения
    • Ошибка 8187 (некорректный указатель на MB_HOLD_REG)
    • Неправильный идентификатор интерфейса
    • Соединение не устанавливается (STATUS 7002)
    • Путаница с порядком байт
    • Неверный порт (502 vs 503)
  9. Заключение и дальнейшие шаги
    • Когда использовать сервер, а когда клиент
    • Переход к реализации клиента Modbus TCP

1. Введение: что такое сервер Modbus TCP и зачем он нужен

Протокол Modbus TCP — это промышленный стандарт обмена данными, работающий поверх TCP/IP. В паре «клиент-сервер» сервер (ранее называвшийся slave) ожидает входящих запросов и отвечает на них. Сервер никогда сам не инициирует передачу.

В контроллерах Siemens S7‑1200 поддержка сервера Modbus TCP реализована через встроенный функциональный блок MB_SERVER (находится в библиотеке Communication → Others → MODBUS TCP). Это бесплатное решение, не требующее дополнительных лицензий, в отличие от S7‑300/400.

функциональный блок MB_SERVER

Типичные задачи для сервера Modbus TCP:

  • Предоставление данных из ПЛК системам верхнего уровня (SCADA, BMS, диспетчерские).
  • Интеграция с устройствами, которые могут работать только как клиенты (например, некоторые HMI или контроллеры сторонних производителей).
  • Организация точки доступа для диагностики и мониторинга.

2. Терминология и структура данных Modbus

Modbus оперирует четырьмя основными типами объектов. В традиционной реализации они привязаны к определённым областям памяти контроллера.

Объект ModbusТип доступаТрадиционное отображение в SiemensНазначение
Катушки (Coils)Чтение / Запись%Q (выходные биты)Дискретные управляющие сигналы
Дискретные входы (Discrete Inputs)Только чтение%I (входные биты)Дискретные сигналы от датчиков
Входные регистры (Input Registers)Только чтение%IW (входные слова)Аналоговые значения (16 бит)
Регистры хранения (Holding Registers)Чтение / ЗаписьПроизвольная область (DB, M)Числовые параметры, уставки, результаты

В версиях библиотеки Modbus TCP до V5.0 доступ к катушкам, дискретным входам и входным регистрам был жёстко привязан к процессным образам I и Q. Начиная с V5.0 (S7‑1200 прошивка ≥4.2, S7‑1500 ≥2.5) появилась возможность переназначать эти объекты на любые битовые или словные области (например, в DB). Это даёт большую гибкость и безопасность.


3. Подготовка проекта в TIA Portal

3.1. Требования к версиям

КонтроллерМинимальная прошивкаВерсия библиотеки Modbus TCP
S7‑12004.2V5.0 (встроена в TIA Portal)
S7‑15002.5V5.0 (встроена в TIA Portal)

Если у вас более старые версии, функциональность может быть ограничена (например, отсутствие возможности переназначать объекты). Рекомендуется обновить проект до актуальных версий.

3.2. Создание блока данных для регистров хранения

Регистры хранения – это самый важный объект, так как через них обычно передаются все числовые данные (REAL, INT, WORD и т.д.). Для их хранения создадим глобальный блок данных с неоптимизированным доступом.

глобальный блок данных с неоптимизированным доступом

Почему неоптимизированный?
Блоки с оптимизированным доступом хранят переменные не по фиксированным адресам, а в произвольном порядке. Блок MB_SERVER ожидает, что область памяти будет непрерывной и с известными смещениями. При использовании оптимизированного DB возможна ошибка 8187 (см. раздел «Типичные ошибки»).

Шаги:

  1. Добавить новый блок данных (Add new block → Data block). Назвать, например, DB_Modbus_Holding.
  2. Отключить оптимизированный доступ:
    • Открыть свойства DB (правой кнопкой → Properties).
    • На вкладке Attributes снять флажок Optimized block access.
    • Подтвердить (система предупредит о возможной несовместимости, нажмите OK).
  3. Создать структуру внутри DB. Например, структуру HoldingRegs, содержащую нужные переменные:textHoldingRegs : STRUCT Speed : REAL; // 2 регистра (4 байта) Current : REAL; // ещё 2 регистра StatusWord : WORD; // 1 регистр (2 байта) Setpoint : REAL; // 2 регистра // … и т.д. END_STRUCT;Или массив ARRAY[0..99] OF WORD, если удобнее работать со словами.
  4. Откомпилировать DB.

Важно: Порядок переменных в структуре определяет соответствие регистрам Modbus. Первая переменная будет занимать регистры с адреса 1 (если начинать с 1). Для REAL понадобится два регистра.


4. Пошаговая настройка блока MB_SERVER

4.1. Добавление блока и настройка интерфейса

  1. В OB1 (или другом циклическом блоке) добавьте вызов MB_SERVER из библиотеки.
  2. Создайте экземпляр (Instance DB) – можно оставить имя по умолчанию.
  3. Настройте входные параметры:
    • CONNECT: ссылка на структуру соединения (создадим позже).
    • MB_HOLD_REG: указатель на область регистров хранения (нашу структуру).

4.2. Создание структуры TCON_IP_v4

Для конфигурации TCP-соединения используем системный тип TCON_IP_v4. Объявим его в статической области экземпляра или в отдельном DB.

Поля структуры:

ПолеЗначениеПояснение
InterfaceIdHW_ANYИдентификатор сетевого интерфейса (будет присвоен позже)
IDWORDУникальный идентификатор соединения (1…4096)
ConnectionTypeBYTE11 (B#16#0B) – TCP
ActiveEstablishedBOOLFALSE – сервер, не инициирует соединение
RemoteAddressARRAY[1..4] of BYTEIP-адрес клиента (если нужно ограничить). Оставить 0 – любой
RemotePortUINT0 – любой порт клиента
LocalPortUINT502 – стандартный порт Modbus TCP

Создание в коде (например, в статическом DB):

scl

CONNECT_Struct : TCON_IP_v4 := (
    InterfaceId := 0,          // временно
    ID := 1,
    ConnectionType := B#16#0B,
    ActiveEstablished := FALSE,
    RemoteAddress := [0,0,0,0],
    RemotePort := 0,
    LocalPort := 502
);

4.3. Присвоение идентификатора интерфейса (InterfaceId)

Перед вызовом MB_SERVER необходимо записать в CONNECT_Struct.InterfaceId правильный идентификатор сетевого интерфейса, через который будет работать сервер. Это может быть:

  • встроенный PROFINET-порт (X1, X2),
  • или CM/CP.

Способ 1: через системные константы (рекомендуется):

  1. Откройте аппаратную конфигурацию.
  2. Выделите нужный порт (например, PROFINET-интерфейс X1).
  3. Во вкладке System constants найдите переменную, начинающуюся с Local~PROFINET_interface или Local~PN/IE. Скопируйте её имя.
  4. В коде используйте эту константу.

Способ 2: прямая константа (для X1 у многих CPU это 64, но лучше не полагаться на это).
Пример присвоения в SCL:

scl

#CONNECT_Struct.InterfaceId := "Local~PROFINET_interface_1";  // имя из системных констант

4.4. Подача области регистров хранения

На вход MB_HOLD_REG подаём указатель на созданную структуру. Если в DB_Modbus_Holding есть структура HoldingRegs, то в SCL:

scl

MB_SERVER_DB(
    CONNECT := #CONNECT_Struct,
    MB_HOLD_REG := "DB_Modbus_Holding".HoldingRegs
);

В LAD/FBD можно просто перетащить переменную.


5. Ограничение доступа к катушкам и дискретным входам

По умолчанию MB_SERVER позволяет клиенту:

  • читать и записывать катушки (биты %Q),
  • читать дискретные входы (биты %I),
  • читать входные регистры (слова %IW).

Это может быть нежелательно, так как сторонняя система получит прямой доступ к управлению выходами. Чтобы запретить доступ к этим объектам, установите соответствующие параметры экземпляра MB_SERVER в 0.

Где задавать:
Откройте экземпляр DB блока MB_SERVER (например, MB_SERVER_DB). В статических переменных найдите:

  • QB_Count – количество байт выходной области (катушек), доступных для записи.
  • QB_Read_Count – количество байт выходной области, доступных для чтения.
  • IB_Count – количество байт входной области (дискретных входов и входных регистров).

Установите их в 0. Можно сделать это прямо в коде перед вызовом:

scl

#MB_SERVER_DB.QB_Count := 0;
#MB_SERVER_DB.QB_Read_Count := 0;
#MB_SERVER_DB.IB_Count := 0;

После этого клиент при попытке обратиться к катушкам или входам получит ответ Illegal Data Address (код ошибки 0x02). Регистры хранения продолжат работать.


6. Проверка работоспособности

6.1. Загрузка и онлайн-мониторинг

Загрузите проект в контроллер. В онлайн-режиме откройте экземпляр MB_SERVER. Поле STATUS должно показывать 7002 – это не ошибка, а индикация того, что соединение установлено (ожидается подключение). Как только подключится клиент, статус изменится на 0 (без ошибок) или другой код.

6.2. Использование стороннего Modbus-клиента

Возьмите любой Modbus TCP клиент (например, ModScan, Simple Modbus TCP Client, или даже утилиту командной строки). Настройте:

  • IP-адрес контроллера,
  • порт 502,
  • функцию: Read Holding Registers (чтение регистров хранения).

Если вы создали структуру из 5 регистров (как в примере), запросите 5 регистров, начиная с адреса 1. Проверьте, что значения соответствуют тем, которые вы записали в контроллере.

6.3. Порядок байт (Endianness)

Важный момент: в контроллерах Siemens используется little-endian (младший байт слова хранится по младшему адресу). Многие Modbus-клиенты по умолчанию ожидают big-endian. Поэтому при отображении значений может получиться «перевёрнутая» картина. Например, если в регистре хранения записано 16#1234, клиент может показать 16#3412.

Решения:

  • Настроить клиент на «swap words» или «little-endian» режим.
  • В самом контроллере поменять порядок байт перед записью в регистры (например, использовать функцию SWAP).

В примере на скриншоте из оригинальной статьи клиент настроен на Float (Word Swap), что позволяет корректно отображать REAL.


7. Особенности работы с разными типами данных

7.1. Использование массивов WORD в оптимизированных DB

Интересный эксперимент: если в качестве MB_HOLD_REG подать массив ARRAY[0..9] OF WORD, объявленный в оптимизированном блоке данных, то это работает. Почему?
Потому что массив слов в оптимизированном DB всё равно располагается в непрерывной области памяти (оптимизация касается расположения отдельных элементов, но не внутренней структуры массива). Блок MB_SERVER, ожидая непрерывную область, может корректно с ней работать.

Однако для структур (особенно содержащих разнородные типы) оптимизированный доступ приводит к нарушению непрерывности и ошибке 8187.

Рекомендация: для надёжности используйте неоптимизированный DB со структурой. Так вы точно знаете, какому регистру соответствует каждая переменная.

7.2. Доступ к регистрам хранения в формате REAL

Для работы с REAL (32-битное число с плавающей точкой) выделите два последовательных регистра. При чтении/записи клиент должен интерпретировать пару регистров как одно число с плавающей точкой (32‑bit float). В структуре DB это будет выглядеть как одна переменная типа REAL.

7.3. Меркерная область (M-память)

В качестве MB_HOLD_REG можно использовать меркерные слова, например MW0. Это тоже непрерывная область, и она работает. Но для больших объёмов данных удобнее DB.


8. Типичные ошибки и способы их устранения

8.1. Ошибка 8187: «Invalid pointer. Data area is too small»

Симптом: В поле STATUS блока MB_SERVER появляется код 8187.
Причина: Указатель на MB_HOLD_REG указывает на область, которая не является непрерывной (например, структура в оптимизированном DB).
Решение: Используйте неоптимизированный DB или массив слов в оптимизированном DB. Убедитесь, что размер области достаточен для запросов клиента.

8.2. Неправильный идентификатор интерфейса

Симптом: STATUS = 7002 (соединение не устанавливается) или 7004.
Причина: InterfaceId не соответствует действительности или не назначен.
Решение: Проверьте, что в CONNECT_Struct.InterfaceId записана корректная константа из системных констант. Для X1 большинства CPU это Local~PROFINET_interface_1. Можно также временно задать значение 64 (но это менее надёжно).

8.3. Соединение не устанавливается (STATUS 7002 бесконечно)

Причина: Клиент не может подключиться к порту 502. Возможно, брандмауэр блокирует порт, или контроллер не имеет IP-адреса.
Решение: Проверьте сетевые настройки. Пропингуйте контроллер. Убедитесь, что в проекте задан IP-адрес для интерфейса.

8.4. Путаница с порядком байт

Симптом: Данные читаются, но значения не соответствуют ожидаемым (например, число 1.0 читается как 1.0E-38).
Причина: Клиент и сервер используют разный порядок байт.
Решение: В клиенте включите опцию «Word Swap» или «Byte Swap». Если такой опции нет, придётся поменять порядок байт в программе контроллера с помощью инструкции SWAP для каждого слова.

8.5. Неверный порт (502 vs 503)

В некоторых реализациях (например, LOGO! как сервер Modbus) используется порт 503. Для S7‑1200/1500 порт по умолчанию 502. Убедитесь, что клиент подключается именно на порт 502. Если нужно изменить, укажите другой LocalPort в структуре TCON_IP_v4.


9. Заключение и дальнейшие шаги

Мы детально разобрали создание сервера Modbus TCP на контроллерах S7‑1200/1500. Такой сервер позволяет интегрировать Siemens PLC в разнородные системы автоматизации, предоставляя доступ к регистрам хранения, катушкам и входам с возможностью гибкого ограничения прав.

Ключевые выводы:

  • Используйте неоптимизированные DB для регистров хранения, чтобы избежать ошибок.
  • Ограничивайте доступ к катушкам и входам, если это не требуется для сторонней системы.
  • Контролируйте порядок байт при работе с REAL и многобайтовыми значениями.
  • Всегда проверяйте идентификатор интерфейса и корректность IP-настроек.

Следующий шаг:
Если вам нужно, чтобы S7‑1200/1500 сам опрашивал другие устройства по Modbus TCP (выступал клиентом), изучите блок MB_CLIENT. В TIA Portal он работает аналогично, но требует настройки активного соединения (ActiveEstablished := TRUE) и указания удалённого сервера.

Menu