Вообщем примерно так, но имеейте ввиду, что если КЗР не предусматривает останов на крайних положениях (внутренние концевики) это надо предусмотреть

FUNCTION_BLOCK PWM_VALV
VAR_INPUT
pwr:REAL; (* Мощность -100..100*)
END_VAR
VAR_OUTPUT
Open:BOOL; (* Работа на открытие *)
Close:BOOL; (* Работа на закрытие*)
END_VAR
VAR
initial:BOOL:=TRUE; (* Начальная инициализация*)
start_on:TON; (* Работа периода ШИМ*)
(*
__ __
| | Период ШИМ | |
-----------------------------| |---------------------------------------| |---------------
ШИМ Период
*)
stop_on:TON; (* Работа во ВКЛ состоянии - инверсно .Q*)

(*
|--------------------|
ВКЛ ШИМ | |
---------------------------------***********| |************
*)

tm_on:TIME; (* Время работы вых. элемента *)
prev_pwr:REAL:=0;
tmp_r: REAL;
tmp_period:REAL;
tmp_r_dwWORD;
same_add:REAL;
END_VAR
IF initial THEN
start_on.IN:=FALSE;
stop_on.IN:=FALSE;
stop_on.PT:=t#1s;
initial:=FALSE;
END_IF
IF pwr<>prev_pwr THEN

prev_pwr:=pwr*100+same_add;
tmp_r_dw:=REAL_TO_DWORD(10*MIN(ABS(pwr*100.0+same_ add),100.0));(* период шим в Миллисек*)

tm_on:=DWORD_TO_TIME(tmp_r_dw); (* Перевод Real в Миллисек*)
IF tm_on<T#20ms THEN (* Проверка мин длит импульса*)
tm_on:=t#0s;
same_add:=pwr;
ELSE
same_add:=0;
END_IF
same_add:=0.0;

END_IF
start_on(pt:=t#1s);
start_on.IN:=NOT start_on.Q;

IF start_on.Q THEN
stop_on.IN:=FALSE;
stop_on.PT:=tm_on;
END_IF
stop_on();
stop_on.IN:=TRUE;
IF pwr<>0.0 THEN
IF pwr<0 THEN
Open:=FALSE;
Close:=(NOT stop_on.Q) OR (pwr=-1.0);
ELSE
Open:=NOT stop_on.Q OR (pwr=1.0);
Close:=FALSE;
END_IF
ELSE
Open:=FALSE;
Close:=FALSE;
END_IF