Создание аналога счетчика CTU с максимальным значением DWORD в CoDeSys v2.
При создании программы ПЛК в среде программирования CoDeSys v2 часто используется компонент счетчик CTU. Например, при работе с энкодером он посчитывает импульсы, поступающие с быстрого входа контроллера на вход CU. Выход CV счетчика CTU имеет тип WORD. Что ограничивает его выходное значение максимум 65535-мя подсчитываемыми импульсами (реально он останавливает счет на значении 32767 – максимальном 16 битном числе со знаком). Проблему можно решить, написав собственный счетчик.
Для этого создаем новый функциональный блок. Открываем вкладку PUI, добавляем новый объект.
В открывшемся окне выбираем тип PUI - функциональный блок, язык программирования - ST. Даем ему название, например mycounter. Нажимаем кнопку OK.
В открывшемся окне редактора кода задаем следующие переменные
Входные переменные:
inenc: BOOL := FALSE; (*Вход счетчика*)
resetcount: BOOL := FALSE; (*Сброс счетчика*)
Выходные переменные:
countout: DWORD; (*Выход счетчика*)
Задаем выходной переменной тип DWORD что позволит накапливать в нем значения до 4294967295.
Кроме того используем элементы:
R_TRIG – детектор переднего фронта,
и
S_TRIG – детектор заднего фронта.
Подробнее об этих элементах можно прочитать во встроенной справочной системе CoDeSys v2.
Объявляем их в разделе внутренних переменных:
RTRIGInst : R_TRIG ;(*детектор переднего фронта*)
FTRIGInst : F_TRIG ; (*детектор заднего фронта*)
Их задача ловить начало и конец импульса приходящих от энкодера.
Задаем для них две переменные
enin1: BOOL := FALSE; (*Выход детектора переднего фронта*)
enin2: BOOL := FALSE; (*Выход детектора заднего фронта*)
которые будут принимать значение TRYE при прохождении соответствующего фронта импульса.
И промежуточную переменную flag, которая используется для корректной работы счетчика.
flag: BOOL := FALSE; (*Промежуточная переменная*)
В разделе кода пишем:
RTRIGInst(CLK:= inenc);
enin1 := RTRIGInst.Q;
FTRIGInst(CLK:= inenc);
enin2 := FTRIGInst.Q;
IF enin1 = TRUE AND flag = FALSE THEN
countout:=countout+1;
flag:=TRUE;
END_IF;
IF enin2 = TRUE THEN
flag:=FALSE;
END_IF;
IF resetcount = TRUE THEN
countout:=0;
END_IF;
Далее сохраняем проект, Компилируем, и получаем собственный счетчик, который можем использовать в проекте.
Полный исходный код функционального блока с комментариями:
FUNCTION_BLOCK mycounter
(*Раздел объявления переменных*)
VAR_INPUT
inenc: BOOL := FALSE; (*Вход от энкодера*)
resetcount: BOOL := FALSE; (*Сброс счетчика*)
END_VAR
VAR_OUTPUT
countout: DWORD; (*Выходной счетчик*)
END_VAR
VAR
flag: BOOL := FALSE; (*Флаг что пришел передний фронт*)
RTRIGInst : R_TRIG ;(*детектор переднего фронта*)
FTRIGInst : F_TRIG ; (*детектор заднего фронта*)
enin1: BOOL := FALSE; (*Выход детектор переднего фронта*)
enin2: BOOL := FALSE; (*Выход детектор заднего фронта*)
END_VAR
(*Раздел кода*)
RTRIGInst(CLK:= inenc);
enin1 := RTRIGInst.Q;
FTRIGInst(CLK:= inenc);
enin2 := FTRIGInst.Q;
IF enin1 = TRUE AND flag = FALSE THEN
countout:=countout+1;
flag:=TRUE;
END_IF;
IF enin2 = TRUE THEN
flag:=FALSE;
END_IF;
IF resetcount = TRUE THEN
countout:=0;
END_IF;
О том как использовать этот функциональный блок в программе CoDeSys можно прочитать в следующем разделе.