Добрый день, столкнулся со странным поведением при работе с PersistantVars.
Задача следующая, СПК110 должен работать как Slave по Modbus RTU и Modbus TCP. По обоим каналам могут приходить новые значения для уставок. Также уставки могут меняться с сенсорной панели.
Уставки сохраняются в PersistantVars.
Код:
(*Уставки для ШП1.*)
SpAT1_MaxFillTm: TIME (*:= T#9M*); (*Допустимое время набора давления в ресивере.*)
SpAT1_MaxFillUpTm: TIME(*:= T#1M30S*); (*Допустимое время набора давления в ресивере.*)
SpAT1_DrainPeriod: TIME(*:= T#6H*); (*Периодичность сброса конденсата.*)
SpAT1_DrainTm: TIME(*:= T#7S*); (*Длительность открытия клапана сброса конденсата.*)
SpL11_PurgePeriod: TIME(*:= T#2H*); (*Периодичность продувки*)
SpL11_ML_MaxPurgeTm: TIME(*:= T#10M*); (*Макс. длительность продувки «-» линии*)
SpL11_PL_MaxPurgeTm: TIME(*:= T#10M*); (*Макс. длительность продувки «+» линии*)
SpL11_ML_AlmDirtyTm: TIME(*:= T#9M30S*); (*Время формирования предупреждения «Сильно забита «-» линия».*)
SpL11_PL_AlmDirtyTm: TIME(*:= T#9M30S*); (*Время формирования предупреждения «Сильно забита «+» линия».*)
SpL11_UDL_PurgeDelay: TIME(*:= T#5S*); (*Пауза между началом продувки сверху и снизу.*)
(*Уставки для ШП2.*)
SpAT2_MaxFillTm: TIME(*:= T#9M*); (*Допустимое время набора давления в ресивере.*)
SpAT2_MaxFillUpTm: TIME(*:= T#1M30S*); (*Допустимое время набора давления в ресивере.*)
SpAT2_DrainPeriod: TIME(*:= T#6H*); (*Периодичность сброса конденсата.*)
SpAT2_DrainTm: TIME(*:= T#7S*); (*Длительность открытия клапана сброса конденсата.*)
SpL21_PurgePeriod: TIME(*:= T#2H*); (*Периодичность продувки*)
SpL21_ML_MaxPurgeTm: TIME(*:= T#10M*); (*Макс. длительность продувки «-» линии*)
SpL21_PL_MaxPurgeTm: TIME(*:= T#10M*); (*Макс. длительность продувки «+» линии*)
SpL21_ML_AlmDirtyTm: TIME(*:= T#9M30S*); (*Время формирования предупреждения «Сильно забита «-» линия».*)
SpL21_PL_AlmDirtyTm: TIME(*:= T#9M30S*); (*Время формирования предупреждения «Сильно забита «+» линия».*)
SpL21_UDL_PurgeDelay: TIME(*:= T#5S*); (*Пауза между началом продувки сверху и снизу.*)
Для проверки уставок сделано три POU:
ModbusRtuData
ModbusTcpData
PLC_PRG
Все три POU выполняются последовательно в одной задаче.
Пример кода проверки:
Код:
IF SpL11_PurgePeriod.tmVal <> PersistentVars.SpL11_PurgePeriod THEN // Если значение пришедшее по Modbus не совпадает с сохранённым в СПК, то проеряем.
IF (SpL11_PurgePeriod.tmVal>=GVL.PurgePeriod_MIN) AND (SpL11_PurgePeriod.tmVal<=GVL.PurgePeriod_MAX) THEN // Проверка пределов.
PersistentVars.SpL11_PurgePeriod:= SpL11_PurgePeriod.tmVal; // Если новое значение подходит, то сохраняем в Persistant
ELSE
SpL11_PurgePeriod.tmVal:= PersistentVars.SpL11_PurgePeriod; // Если новое значение НЕ подходит, то в Modbus-регистр пишем старое значение.
END_IF
PLC_PRG.SpL11_PurgePeriod:= PersistentVars.SpL11_PurgePeriod; // Обновляем значения уставок в POU для проверки значений введённых с сенсорной панели, чтобы в данном POU не проводилась повторная проверка.
ModbusTcpData.SpL11_PurgePeriod.tmVal:= PersistentVars.SpL11_PurgePeriod; // Обновляем значения уставок в POU для проверки значений пришедших по каналу Modbus TCP, чтобы в данном POU не проводилась повторная проверка.
END_IF
Проблема возникает при отключении питания СПК и повторном включении. Все уставки кроме одной сохраняются и восстанавливаются корректно. Значение уставки SpL11_PurgePeriod: TIME, если в переменной перед выключением СПК сохранили значение T#2H (0x006D DD00), после перезагрузки СПК принимает значение T#1H 59M 03S 424MS (0x006D 0000). Если сохраняли значение T#4H (0x00DB BA00), после перезагрузки СПК принимает значение T#3H 59M 12S 384MS (0x00DB 0000). Т.е. в PersistantVars при сохранении значения сохраняется только старший значащий регистр, а вместо младшего регистра записывается ноль.
Если закомментировать строку
Код:
PLC_PRG.SpL11_PurgePeriod:= PersistentVars.SpL11_PurgePeriod;
, то проблема уходит, но она необходима, для того чтобы исключить повторную проверку уставки.
Переменная PLC_PRG.SpL11_PurgePeriod объявлена в секции VAR_INPUT.
Подскажите в чём может быть проблема, если сталкивались?