Simulink® PLC Coder™ в настоящее время поддерживает основанные на плагине целевые ИДЫ, такие как Селектрон CAP1131, Studio Omron Sysmac, и так далее. Для ваших основанных на плагине пользовательских целевых ИД, которые не поддерживаются, сгенерируйте PLCOpen XML-или совместимый ASCII код структурированного текста. Настройте сгенерированный код, чтобы удовлетворить ваши целевые требования IDE путем усиления встроенных сменных опций в Simulink PLC Coder.
Сгенерировать код для ваших пользовательских основанных на плагине целевых ИД:

Следуйте блок-схеме, чтобы создать plc_custom_ide.m и при необходимости plc_precg_callback_IDEname.m, и plc_postcg_callback_IDEname.m файлы. Чтобы использовать эти файлы, чтобы создать и сгенерировать код для вашего пользовательского целевого IDE, смотрите, Генерируют Код при помощи Основанного на плагине Целевого IDE.
plc_custom_ide.m файлСоздайте plc_custom_ide.m при помощи этого шаблона:
function plc_ide_list = plc_custom_ide % Copyright 2012-2021 The MathWorks, Inc. plc_ide_list(1) = get_ide_info_myplcopen; end function ide_info = get_ide_info_myplcopen ide_info.name = 'myplcopen'; ide_info.description = 'My PLCopen XML'; ide_info.path = ''; % IDE path ide_info.format = 'xml'; % generic|xml ide_info.fileExtension = 'xml'; ide_info.cfg = get_ide_cfg_myplcopen; ide_info.precg_callback = 'plc_precg_callback_myplcopen'; ide_info.postcg_callback = 'plc_postcg_callback_myplcopen'; ide_info.xmltree_callback = PLCCoder.PLCCGMgr.PLC_PLUGIN_CG_CALLBACK_EMPTY; ide_info.pluginVersion = 2.2; ide_info.compatibleBuildVersion = 1.6; end function cfg = get_ide_cfg_myplcopen cfg.fConvertDoubleToSingle = true; cfg.fConvertNamedConstantToInteger = true; cfg.fConvertEnumToInteger = true; cfg.fConvertOutputInitValueToAssignment = true; cfg.fConvertTunableParamToInputVariable = true; cfg.fSimplifyFunctionCallExpr = true; cfg.fConvertOutputInitValueToAssignment = true; end
Определите имя своего целевого IDE, при помощи ide_info.name. Параметр конфигурации Target IDE отображает набор имени в ide_info.description.
Если ваш целевой IDE совместим с Типовыми стандартами ST, установите ide_info.format = 'generic'. Если ваш целевой IDE совместим с PLCOpen XML, установите ide_info.format = 'xml'.
Установите, куда файлы сгенерированного кода помещаются при помощи ide_info.path.
Установите расширение для своих целевых файлов IDE при помощи ide_info.fileExtension.
В function_cfg раздел файла, набор ваши сменные опции. Чтобы включить плагин, установите сменную опцию на true. Например, cfg.fArrayInitialValueBrackets = true; включает плагин. Чтобы отключить плагин, установите сменную опцию на false. Решить, в каких сменных опциях вы нуждаетесь в plc_custom_ide.m файл, см. Сменные Опции.
Если ваш пользовательский IDE требует пред - и обработка генерации почтового индекса, создайте plc_precg_callback_IDEname.m и plc_postcg_callback_IDEname.m файлы.
Предварительная обработка файла коллбэка. plc_precg_callback_IDEname.m файл обеспечивает доступ к промежуточному представлению сгенерированного кода. Промежуточный код хранится в controller тип данных struct, который содержит информацию, такую как имя блока подсистемы, входных параметров, выходных параметров, тела сгенерированного кода, и так далее. Этот коллбэк выполняется, прежде чем целевая эмиттерная функция вызвана. Создать plc_precg_callback_IDEname.m файл, используйте этот шаблон:
function controller = plc_precg_callback_myplcopen(controller) % Copyright 2012-2020 The MathWorks, Inc. % do modifications to the controller struct here, f.ex.: for i = 1:length(controller.components) controller.components(i).body = sprintf('<<header_placeholder>>\r\n%s',controller.components(i).body); end end
Постобработка файла коллбэка. plc_postcg_callback_IDEname.m файл обеспечивает доступ к файлу сгенерированного кода. Используйте этот файл, чтобы заставить сгенерированный код совпадать с требованиями синтаксиса для вашего пользовательского целевого IDE. Этот файл читает в и вносит изменения в файл сгенерированного кода, который читается в как файл строки. Создать plc_postcg_callback_IDEname.m файл, используйте этот шаблон:
function generatedFiles = plc_postcg_callback_myplcopen(fileNames) % Copyright 2012-2020 The MathWorks, Inc. fileName = fileNames{1}; str = fileread(fileName); % do modifications to str here, f.ex.: % str = regexprep(str,'BOOL_TO_LREAL','BOOL_TO_INT'); % str = regexprep(str,'<USINT/>','<INT/>'); % str = regexprep(str, 'END_STRUCT','END_STRUCT;'); [sHeader,eHeader] = regexp(str,'\(\*.*?\*\)'); header = str(sHeader:eHeader); str = regexprep(str,'<<header_placeholder>>',header); sfprivate ('str2file', str, fileName); generatedFiles = {fileName}; end
Сгенерируйте пользовательский код для своего пользовательского целевого IDE путем выбора из сменных перечисленных в таблице опций.
| Сменное имя | Сменная цель | Когда использовать плагин | Эффект плагина на сгенерированном коде |
fConvertBooleanCast | Преобразуйте булеву функцию броска типа в если еще присвоение. | Если ваш целевой IDE не поддерживает булеву функцию броска типа или оператор. | Сгенерированный код с отключенным плагином: Out1 := DINT_TO_INT(BOOL_TO_DINT(In1) +... BOOL_TO_DINT(In2)); Сгенерированный код с включенным плагином: IF In1 THEN
temp1 := DINT#1;
ELSE
temp1 := DINT#0;
END_IF;
IF In2 THEN
temp2 := DINT#1;
ELSE
temp2 := DINT#0;
END_IF;
Out1 := DINT_TO_INT(temp1 + temp2); |
fConvertDoubleToSingle | Преобразуйте двойной тип данных в один тип данных. | Если ваш целевой IDE не поддерживает двойные типы данных. Сгенерированный код двойные переменные типа данных преобразован в один типы данных. Предупреждающее сообщение сгенерировано во время генерации кода, которой типы данных, которые не поддерживаются, были найдены и преобразованы. Значения в сгенерированном коде могут отличаться от значений симуляции. | Сгенерированный код с отключенным плагином: VAR_INPUT
ssMethodType: SINT;
U: LREAL;
END_VAR
VAR_OUTPUT
Y: LREAL;
END_VARСгенерированный код с включенным плагином: VAR_INPUT
ssMethodType: SINT;
U: REAL;
END_VAR
VAR_OUTPUT
Y: REAL;
END_VAR |
fConvertDoubleToSingleEmitter | Преобразуйте двойные типы данных в один типы данных. | Если ваш целевой IDE не поддерживает двойные типы данных, и вы хотите сохранить значения после преобразования. Сгенерированный код двойные переменные типа данных преобразован в один типы данных. Предупреждающее сообщение сгенерировано во время генерации кода, которой типы данных, которые не поддерживаются, были найдены и преобразованы. Значения в сгенерированном коде совпадают со значениями симуляции, если они не превышают | Сгенерированный код с отключенным плагином: VAR_INPUT
ssMethodType: SINT;
U: LREAL;
END_VAR
VAR_OUTPUT
Y: LREAL;
END_VARСгенерированный код с включенным плагином: VAR_INPUT
ssMethodType: SINT;
U: REAL;
END_VAR
VAR_OUTPUT
Y: REAL;
END_VAR |
fConvertEnumToInteger | Преобразуйте перечислимые типы данных в целочисленные типы данных. | Если ваш целевой IDE не поддерживает перечислимые типы данных. | Сгенерированный код с плагином, отключенным для целевого IDE, который поддерживает перечислимый тип данных: VAR_TEMP
rtb_Switch: myEnum;
in: myEnum;
END_VARСгенерированный код с включенным плагином: VAR_TEMP
rtb_Switch: DINT;
in: DINT;
END_VAR |
fConvertUnsignedIntToSignedInt | Преобразует беззнаковое целое в целое число со знаком. | Если ваша цель не поддерживает тип данных беззнаковых целых чисел. | Сгенерированный код с отключенным плагином: FUNCTION_BLOCK Subsystem
VAR_INPUT
In1: UDINT;
In2: UDINT;
END_VAR
VAR_OUTPUT
Out1: UDINT;
END_VARСгенерированный код с включенным плагином: FUNCTION_BLOCK Subsystem
VAR_INPUT
In1: DINT;
In2: DINT;
END_VAR
VAR_OUTPUT
Out1: DINT;
END_VAR |
fInt32AsBaseInt | Наборы int32 тип данных как целочисленный тип данных по умолчанию. | Установка int32 как внутренний целочисленный тип данных по умолчанию может сократить количество операций броска типа в сгенерированном коде. | Сгенерированный код с отключенным плагином: FUNCTION_BLOCK Subsystem
VAR_INPUT
In1: SINT;
In2: SINT;
END_VAR
VAR_OUTPUT
Out1: SINT;
END_VAR
Out1 := DINT_TO_SINT(SINT_TO_DINT(In1) +...
SINT_TO_DINT(In2));
END_FUNCTION_BLOCKСгенерированный код с включенным плагином: FUNCTION_BLOCK Subsystem
VAR_INPUT
In1: DINT;
In2: DINT;
END_VAR
VAR_OUTPUT
Out1: DINT;
END_VAR
Out1 := In1 + In2));
END_FUNCTION_BLOCK |
fEmitEnumTypeIntegerValue | Отображает перечисление значений и соответствующее целочисленное значение в сгенерированном коде. | Отобразить перечислимые значения и их соответствие с целочисленными значениями в сгенерированном коде. | Сгенерированный код с отключенным плагином: TYPE PLCCommandState:
(FILL, HOLD, EMPTY, ACTIVATE);
END_TYPE
TYPE PLCVesselState:
(EMPTIED, NOT_FULL, FULL);
END_TYPE
TYPE PLCValveState:
(SHUT, OPEN);
END_TYPEСгенерированный код с включенным плагином: TYPE PLCCommandState:
(FILL:=0, HOLD:=1, EMPTY:=2, ACTIVATE:=3);
END_TYPE
TYPE PLCVesselState:
(EMPTIED:=0, NOT_FULL:=1, FULL:=2);
END_TYPE
TYPE PLCValveState:
(SHUT:=0, OPEN:=1);
END_TYPE |
| Сменное имя | Сменная цель | Когда использовать плагин | Эффект плагина на сгенерированном коде |
fArrayInitialValueBrackets | Заключает инициализацию массивов в область объявления в скобках. | Если ваш целевой IDE требует инициализации включения массивов в области объявления в скобках. | Сгенерированный код с отключенным плагином: EnableSetpoint_ZCE: ARRAY [0..2] OF USINT:=3,3,3 Сгенерированный код с включенным плагином:: EnableSetpoint_ZCE: ARRAY [0..2] OF USINT:=[3,3,3] |
fConvertAggregateInitValueToAssignment | Преобразует начальные значения для типов агрегированных данных к оператору присваивания. | Целевой IDE не поддерживает инициализацию массивов в области объявления. | Сгенерированный код с отключенным плагином: ARRAY [0..1] OF LREAL := LREAL#0.0,LREAL#0.0998 Сгенерированный код с включенным плагином: tb_U[0] := 0.0;
tb_U[1] := 0.0998;
|
fConvertAggregateTypeFunctionToFB | Преобразует функции с типами агрегированных данных к функциональному блоку (FB). | Целевой IDE поддерживает типы агрегированных данных для функциональных блоков только. | Сгенерированный код с отключенным плагином: function foo(...):ARRAY [0..10] OF LREAL Сгенерированный код с включенным плагином: FUNCTION_BLOCK foo VAR_OUTPUT out1: ARRAY [0..10] OF LREAL; END_VAR |
fConvertFunctionToFB | Преобразуйте функцию в функциональный блок (FB). | Целевой IDE не поддерживает | |
fConvertOutputInitValueToAssignment | Преобразуйте инициализацию выходной переменной в присвоение. | Целевой IDE не позволяет определение начального значения и требует оператора присваивания. | Сгенерированный код с отключенным плагином: FUNCTION_BLOCK foo VAR_OUTPUT somevalue: DINT := 100; END_VAR Сгенерированный код с включенным плагином: FUNCTION_BLOCK foo VAR_OUTPUT somevalue: DINT; END_VAR somevalue := 100; |
fEmitVarDeclarationBeforeDescription | Переключатели, появляется ли описание переменной прежде или после объявления переменной. | Целевой IDE требует объявления переменной перед описанием переменной. | Сгенерированный код с отключенным плагином: VAR_GLOBAL CONSTANT K3: REAL := 0.3; END_VAR Сгенерированный код с включенным плагином: VAR_GLOBAL CONSTANT K3: REAL := 0.3; END_VAR |
fErrorOnTrailingUS | Генерация кода перестала работать, когда она сталкивается с именами переменных с запаздывающим подчеркиванием. | Целевой IDE не поддерживает имена с запаздывающим подчеркиванием. | Генерация кода приводит к сбою с этим сообщением |
fHoistArrayIndexExprs | Выражения перемещений из индексов массива и создают временную переменную для выражения. | Целевой IDE не поддерживает выражения для индексов массива. | Сгенерированный код с отключенным плагином: EnvCur[TRUNC(j) - 1] Сгенерированный код с включенным плагином: temp1 := TRUNC(j) - 1; EnvCur[temp1] |
fSimplifyFunctionCallExpr | Упрощает вызов функции для простых функций. | Целевой IDE не позволяет выражения присваивания в вызовах функции. | Сгенерированный код с отключенным плагином: y := simplefunction(u_0 := u); Сгенерированный код с включенным плагином: y := simplefunction(u); |
fUseQualifiedTypeConstant | Добавляет тип данных к объявлению константы. | Целевой IDE требует типа данных для констант. | Сгенерированный код с отключенным плагином: a := 11; Сгенерированный код с включенным плагином: a := DINT#11; |
| Сменное имя | Сменная цель | Когда использовать плагин | Эффект плагина на сгенерированном коде |
fConvertTunableParamToInputVariable | Преобразует настраиваемые параметры во входные переменные функционального блока (FB). | Вы хотите преобразовать настраиваемые параметры во входные параметры функционального блока. Это позволяет вам вызывать POU с различными наборами параметров. | Сгенерированный код с отключенным плагином: FUNCTION_BLOCK Tunable_Param_to_Input
24 VAR_INPUT
25 ssMethodType: SINT;
26 Input1: REAL;
27 END_VAR
28 VAR_OUTPUT
29 Output1: REAL;
30 END_VAR
31 VAR
32 DSTATE: REAL;
33 END_VAR
34 'ST'
35 BODY
36 CASE ssMethodType OF
37 0:
40 UnitDelay_DSTATE := 0.0;
41
42 1:
43 Output1 := (Input1 - DSTATE) *
TunableParam;
48 DSTATE := Output1;
50 END_CASE;
52 END_BODY
53 END_FUNCTION_BLOCK
54 TunableParam переменная не объявляется как вход к функциональному блоку.Сгенерированный код с включенным плагином: FUNCTION_BLOCK Tunable_Param_to_Input
24 VAR_INPUT
25 TunableParam: LREAL;
26 ssMethodType: SINT;
27 Input1: REAL;
28 END_VAR
29 VAR_OUTPUT
30 Output1: REAL;
31 END_VAR
32 VAR
33 DSTATE: REAL;
34 END_VAR
35 'ST'
36 BODY
37 CASE ssMethodType OF
38 0:
39 DSTATE := 0.0;
42
43 1:
44 Output1 := (Input1 - DSTATE) *
TunableParam;
49 DSTATE := Output1;
51
52 END_CASE;
53 END_BODY
54 END_FUNCTION_BLOCK
55 TunableParam переменная объявляется как вход к функциональному блоку. |
fDefineFBExternalConstVariable | Задает внешние переменные в | Целевой IDE требует объявления внешних постоянных переменных в | Сгенерированный код с отключенным плагином: VAR_GLOBAL CONSTANT
SS_INITIALIZE: SINT := 0;
K3: LREAL := 0.3;
SS_STEP: SINT := 1;
END_VARСгенерированный код с включенным плагином: VAR_GLOBAL CONSTANT
K3: REAL := 0.3; |
fDefineFBExternalVariable | Задает внешние константы в | Целевой IDE требует объявления внешних констант в | Сгенерированный код с отключенным плагином: VAR
UnitDelay_DSTATE: LREAL;
i0_ExternallyDefinedBlock: ExternallyDefinedBlock;
END_VARСгенерированный код с включенным плагином: VAR_EXTERNAL
K1: REAL;
END_VAR |
fReplaceShiftFunctions | Замены предназначаются для функций сдвига IDE с функциями, чтобы совпадать со сдвигом Simulink функциональное поведение. | Когда количество рабочих смен больше длины типа данных, существует несоответствие между выходом блока сдвига Simulink и целевым блоком сдвига IDE. Используйте этот плагин, чтобы заменить целевые блоки сдвига IDE на блоки сдвига Simulink в сгенерированном коде. | Сгенерированный код с отключенным плагином: Out10 := WORD_TO_INT(SHL(IN:=INT_TO_WORD(In1),... N:=Out2_tmp)); SHL функция сдвига.Сгенерированный код с включенным плагином: Out10 := WORD_TO_INT(PLC_SHL(INT_TO_WORD(In1),...
DINT_TO_USINT(Out2_tmp)));
FUNCTION PLC_SHL: WORD
VAR_INPUT
in1: WORD;
in2: USINT;
END_VAR
'ST'
BODY
IF in2 > 16 THEN
PLC_SHL := 16#0;
ELSE
PLC_SHL := SHL(in1, in2);
END_IF;
END_BODY
END_FUNCTIONPLC_SHL, который реплицирует блок сдвига Simulink в целевой IDE. |
| Сменное имя | Сменная цель | Когда использовать плагин | Эффект плагина на сгенерированном коде |
fSimplifyAllIntrinsicFcn | Упрощает входные параметры всех встроенных функций. | Целевой IDE не позволяет составные выражения как часть аргументов встроенной функции. | Сгенерированный код с отключенным плагином: a := SQRT(x*y); Сгенерированный код с включенным плагином: t1 := x*y; a := SQRT(t1); |
fSimplifyIntrinsicFcn | Упрощает встроенные функции, которые являются аргументами | Целевой IDE не позволяет составные выражения как часть аргументов встроенной функции. | Сгенерированный код с отключенным плагином: a := SQRT(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyIntrinsicFcnNameList = { 'SQRT' \}
cfg.fSimplifyIntrinsicFcn = true;
t1 := x*y;
a := SQRT(t1); |
fSimplifyIntrinsicFcnNameList | Создает список встроенных функций. Входные параметры к этим встроенным функциям упрощены при помощи | Целевой IDE не позволяет составные выражения как часть аргументов встроенной функции. | Сгенерированный код с отключенным плагином: a := SQRT(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyIntrinsicFcnNameList = { 'SQRT' \}
cfg.fSimplifyIntrinsicFcn = true;
t1 := x*y;
a := SQRT(t1); |
fSimplifyOperator | Упрощает входные параметры функций оператора, перечисленных при помощи | Целевой IDE не позволяет составные выражения как часть аргументов функции оператора. | Сгенерированный код с отключенным плагином: a := SHL(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyOperatorNameList = { 'SHL' \}
cfg.fSimplifyOperator = true;
t1 := x*y;
a := SHL(t1); |
fSimplifyOperatorNameList | Создает список функций оператора. Входные параметры к этим функциям оператора упрощены при помощи | Целевой IDE не позволяет составные выражения как часть аргументов функции оператора. | Сгенерированный код с отключенным плагином: a := SHL(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyOperatorNameList = { 'SHL' \}
cfg.fSimplifyOperator = true;
t1 := x*y;
a := SHL(t1); |
fSimplifyTrunc | Упрощает входные параметры | Целевой IDE не позволяет составные выражения в качестве аргументов для | Сгенерированный код с отключенным плагином: a := TRUNC(x*y); Сгенерированный код с включенным плагином: cfg.fSimplifyTrunc = true; t1 := x*y; a := SHL(t1); |
В этом примере показано, как сгенерировать код для пользовательского целевого IDE под названием my PLCopen XMLпри помощи плагинов.
Создайте папку под названием myplcopen. Создайте plc_custom_ide.m файл в папке при помощи этого шаблона:
function plc_ide_list = plc_custom_ide % Copyright 2012-2021 The MathWorks, Inc. plc_ide_list(1) = get_ide_info_myplcopen; end function ide_info = get_ide_info_myplcopen ide_info.name = 'myplcopen'; ide_info.description = 'My PLCopen XML'; ide_info.path = ''; % IDE path ide_info.format = 'xml'; % generic|xml ide_info.fileExtension = 'xml'; ide_info.cfg = get_ide_cfg_myplcopen; ide_info.precg_callback = 'plc_precg_callback_myplcopen'; ide_info.postcg_callback = 'plc_postcg_callback_myplcopen'; ide_info.xmltree_callback = PLCCoder.PLCCGMgr.PLC_PLUGIN_CG_CALLBACK_EMPTY; ide_info.pluginVersion = 2.2; ide_info.compatibleBuildVersion = 1.6; end function cfg = get_ide_cfg_myplcopen cfg.fConvertDoubleToSingle = true; cfg.fConvertNamedConstantToInteger = true; cfg.fConvertEnumToInteger = true; cfg.fConvertOutputInitValueToAssignment = true; cfg.fConvertTunableParamToInputVariable = true; cfg.fSimplifyFunctionCallExpr = true; cfg.fConvertOutputInitValueToAssignment = true; end
Установите свои сменные опции в function_cfg раздел файла. Чтобы включить плагин устанавливает сменную опцию на true. Например, cfg.fArrayInitialValueBrackets = true; включает плагин. Чтобы отключить плагин, установите сменную опцию на false.
Создайте plc_precg_callback_IDEname.m и plc_postcg_callback_IDEname.m файлы при помощи этих шаблонов:
function controller = plc_precg_callback_myplcopen(controller) % Copyright 2012-2020 The MathWorks, Inc. % do modifications to the controller struct here, f.ex.: for i = 1:length(controller.components) controller.components(i).body = sprintf('<<header_placeholder>>\r\n%s',controller.components(i).body); end end
function generatedFiles = plc_postcg_callback_myplcopen(fileNames) % Copyright 2012-2020 The MathWorks, Inc. fileName = fileNames{1}; str = fileread(fileName); % do modifications to str here, f.ex.: % str = regexprep(str,'BOOL_TO_LREAL','BOOL_TO_INT'); % str = regexprep(str,'<USINT/>','<INT/>'); % str = regexprep(str, 'END_STRUCT','END_STRUCT;'); [sHeader,eHeader] = regexp(str,'\(\*.*?\*\)'); header = str(sHeader:eHeader); str = regexprep(str,'<<header_placeholder>>',header); sfprivate ('str2file', str, fileName); generatedFiles = {fileName}; end
Создайте plc_header_hook.m файл при помощи этого шаблона:
function headerCommentText = plc_header_hook(filePath, blockH, headerCommentText) headerCommentText = [headerCommentText(1:end-7) ... sprintf([' * Plugin Header Copy : Yes \n']) ... headerCommentText(end-6:end)]; end
plc_header_hook.m файл копирует информацию о заголовке в начале файла сгенерированного кода к каждому экземпляру функционального блока.
Добавьте новую папку и файлы к пути MATLAB.
Щелкните правой кнопкой по папке и выберите Add to Path> Selected Folders and Subfolders.
Используйте addpath функция. Например, addpath(genpath('path to your folder')).
Запустите эту команду:
plccoderpref('plctargetidepaths','default')
Перезапустите свой сеанс работы с MATLAB.
Откройте свою модель и выберите компонент модели для генерации кода. Откройте приложение PLC Coder. Нажмите Settings. На панели PLC Code Generation, в Target IDE, выбирают My PLCopen XML. Нажмите OK.

В приложении PLC Coder, вкладке PLC Code, нажимают Generate PLC Code, чтобы сгенерировать код для вашего пользовательского целевого IDE. Файлы сгенерированного кода помещаются в путь, заданный в ide_info.path = ''; % IDE path.