Цитата Сообщение от petera Посмотреть сообщение
Мой вариант
Захват-1.png

Прерывания таймера - 40мкс.
В обработчике прерываний подсчитывается длительность входных импульсов - dT в единицах прерывания, для каждого входа

Код:
PROGRAM PWM_meter
VAR
	count: DWORD;		(*счетчик прерываний таймера*)
	in: BYTE;
	start1: DWORD;
	State1: INT;
	start2: DWORD;
	State2: INT;
	start3: DWORD;
	State3: INT;
	start4: DWORD;
	State4: INT;
END_VAR
В обработчике прерываний подсчитывается длительность входных импульса - dT в единицах прерывания для каждого входа
Код:
count:= count + 1;
in:= SysPortIn(0);

(*--- Первый вход ПЛК ---*)
CASE State1 OF
0:
IF in.0 THEN
	start1:= count;
	State1:= 1;
END_IF
1:
IF NOT in.0 THEN
	dT1_cycle:= count - start1;
	State1:= 0;
END_IF
END_CASE

(*--- Второй вход ПЛК ---*)
CASE State2 OF
0:
IF in.1 THEN
	start2:= count;
	State2:= 1;
END_IF
1:
IF NOT in.0 THEN
	dT2_cycle:= count - start2;
	State2:= 0;
END_IF
END_CASE
Полученные значения передаются в PLC_PRG через глобальные переменные
Код:
VAR_GLOBAL
	dT1_cycle: DWORD;
	dT2_cycle: DWORD;
	dT3_cycle: DWORD;
	dT4_cycle: DWORD;
END_VAR
Коэффициенты заполнения рассчитываются в PLC_PRG
Код:
PROGRAM PLC_PRG
VAR
	init:BOOL:=TRUE; (* Переменная для инициализации прерывания таймера при запуске основной программы *)
	F: REAL := 75.0;		(*Частота ШИМ в Гц*)
	D1: REAL;	(* коэфф. заполнения 1 в %*)
	D2: REAL;	(* коэфф. заполнения 2 в %*)
	D3: REAL;	(* коэфф. заполнения 3 в %*)
	D4: REAL;	(* коэфф. заполнения 4 в %*)
END_VAR

 (*Инициализируем обработчик прерывания таймера и настраиваем период срабатывания таймерного прерывания*)
IF (init=TRUE) THEN
	SetIRQ(40);  (*Период задается в мкс, должен быть кратен 20*)
	(*ВНИМАНИЕ! Включенный обработчик прерывания работает даже после останове программы,
	 если необходимо его отключать и повторно включать, то делайте это в обработчике событий  "Stop" и "Start"*)
	init:=FALSE; (*Обнуление переменной инициализации, чтобы она не происходила на втором и последующих циклах ПЛК*)
END_IF

(*коэффициент заполнения D= dT/T= dT * F      *)
D1:= DWORD_TO_REAL(dT1_cycle) * 40 * F / 10000; (* коэфф. заполнения в %*)
D2:= DWORD_TO_REAL(dT2_cycle) * 40 * F / 10000;
D3:= DWORD_TO_REAL(dT3_cycle) * 40 * F / 10000;
D4:= DWORD_TO_REAL(dT4_cycle) * 40 * F / 10000;
Спасибо большое за подсказку, буду тестировать. А чем обусловлен выбор 40 мкс? повышением точности?. Я выбирал 60 чтоб меньше грузить ПЛК,точность устраивает.