Спасибо всем кто откликнулся. Задача решена.
Добавляешь устройство Modbus_TCP_Master, в него уже Modbus_TCP_Slave. Создаем два канала для записи в регистры СП310-Р:
канал 0 - для записи PSB регистра, передний фронт которого триггерит макрос синхронизации времени в СП310-Р, Modbus функция записи - Write Single Coil (Код функции 05) (Видео с реализацией https://youtu.be/elizZ9l_-sw?si=RxBhQcyMJ1rJ-C_Z и архив проекта https://ftp.owen.ru/CoDeSys3/99_Foru...projectarchive).
канал 1 - для записи группы регистров (Год, месяц, день, часы, минуты...). Write Multiple Registers (Код функции 16).
Остается дело за малым, а именно написать код, который бы выполнял синхронизацию раз в час.
// Область переменных
PROGRAM PLC_PRG
VAR

iStep: INT := 0; // Шаг автомата

// По переднему фронту инициируется синхронизация времени
xStartSync: BYTE;
wYear: WORD;
wMonth: WORD;
wDay: WORD;
wHour: WORD;
wMinute: WORD;
wSecond: WORD;
// Опрос Modbus slave
fbModbusChannel: IoDrvModbusTCP.ModbusChannel;
xTrigger: BOOL;
xExecute: BOOL;
fbTimeSyncTimer: TON;
iChannelIndex: INT;

fbStartDelay: TON;
xFirstCycle: BOOL := TRUE;
END_VAR
VAR CONSTANT
i_Channel_0: INT := 0;
i_Channel_1: INT := 1;
// Период синхронизации времени
tTimeSyncPeriod: TIME := T#1H;
END_VAR

//-----------------------------------------------------------------------------

// Область кода
fbTimeSyncTimer(
IN := (iStep = 0),
PT := tTimeSyncPeriod
);

// НОВЫЙ ТАЙМЕР: Задержка 2 секунды после включения ПЛК для инициализации сети
fbStartDelay(
IN := TRUE,
PT := T#2S
);

// 2. Вызов функционального блока Modbus ВСЕГДА на каждом цикле
fbModbusChannel(
slave := Modbus_TCP_Slave,
xExecute := xExecute,
iChannelIndex := iChannelIndex
);

// 3. Пошаговый автомат синхронизации
CASE iStep OF

0: // Ожидание срабатывания таймера ИЛИ первого старта
xExecute := FALSE;

IF fbTimeSyncTimer.Q OR (xFirstCycle AND fbStartDelay.Q) THEN

IF xFirstCycle THEN
xFirstCycle := FALSE;
END_IF

// Получение текущего времени из контроллера
wYear := TargetVars.stRtc.uiGetYear MOD 100;
wMonth := TargetVars.stRtc.usiGetMonth;
wDay := TargetVars.stRtc.usiGetDay;
wHour := TargetVars.stRtc.usiGetHour;
wMinute := TargetVars.stRtc.usiGetMinute;
wSecond := TargetVars.stRtc.usiGetSecond;

iStep := 10;
END_IF

10: // ШАГ 1: Запись значений времени (Channel 1)
iChannelIndex := i_Channel_1;
xExecute := TRUE; // Даем команду на отправку

// Ждем завершения операции
IF fbModbusChannel.xDone THEN
xExecute := FALSE; // Сбрасываем execute перед следующим шагом
xStartSync := 1; // Выставляем флаг синхронизации для панели
iStep := 20;
ELSIF fbModbusChannel.xError THEN
xExecute := FALSE;
iStep := 999; // Обработка ошибки
END_IF

20: // Пауза в 1 цикл для сброса фронта xExecute у ФБ
xExecute := FALSE;
iStep := 30;

30: // ШАГ 2: Отправка команды "Применить время" (Channel 0)
iChannelIndex := i_Channel_0;
xExecute := TRUE;

IF fbModbusChannel.xDone THEN
xExecute := FALSE;
xStartSync := 0; // Сбрасываем флаг синхронизации
iStep := 0; // Возврат в начало, таймер fbTimeSyncTimer начнет отсчет заново
ELSIF fbModbusChannel.xError THEN
xExecute := FALSE;
iStep := 999;
END_IF

999: // Ошибка обмена (например, панель еще не загрузилась)
xExecute := FALSE;
xStartSync := 0;

// Если при первом старте произошла ошибка связи, мы НЕ сбрасываем xFirstCycle.
// Автомат попробует снова синхронизироваться на следующем цикле (через шаг 0),
// не дожидаясь tTimeSyncPeriod, пока связь наконец-то не установится успешно.
xFirstCycle := TRUE;

iStep := 0; // Возврат в начало

END_CASE