Skip to main content

子程序

功能: 子程序的调用

经常重复执行的任务,例如型腔铣削、钻孔和换刀,可以替换为 G 代码子程序并从那里调用。在调用过程中,可以将参数传递给子程序。数据类型 BOOL, LREAL, 和 STRING 允许用于此目的。

提示

如果使用子程序,则必须使用功能块 SMC_ReadNCFile2SMC_NCInterpreter 代替 SMC_ReadNCFileSMC_NCDecoder.

提示

子程序仅在在线解码器中工作(不在 CNC 编辑器中)。

每个子程序都存储在一个单独的文件中。这些文件保存在控制器的一个或多个子目录中。他们必须有文件扩展名 .cnc.文件名必须与子程序的名称相对应并且小写。示例:子程序名称“钻孔”-> 文件名 drill.cnc.

重要

注意子程序的文件名必须小写。

POU SMC_ReadNCFile2 有一个输入 aSubProgramDirs : ARRAY[0..4] OF STRING(174).除此之外,最多可以指定五个子目录。它们按照给定的顺序进行扫描。如果多个目录中存在同名的子程序,则查找具有数组中索引最低的目录的子程序。子程序名称转换为小写。

47. 例子
aSubProgramDirs = ['subprograms/user', 'subprograms/system', '']

子程序 DrillA1 首先在文件中扫描 subprograms/user/drilla1.cnc.如果此文件不存在,则继续搜索 subprograms/system/drilla1.cnc.



可以通过变量间接调用子程序(更准确地说,通过类型表达式 STRING)。表达式(以及任何变量查找)在解释器到达行的预处理时被评估 - 通常在 G 代码中使用变量的情况下。在这种情况下,参数的类型检查仅在解释器到达该行时才进行,而不是在解析期间进行,就像静态调用的情况一样。

提示

子程序不能在 CNC 编辑器中离线创建。

子程序调用的最大嵌套深度

  • 4.18.0.0 版本之前:子程序调用的最大嵌套深度限制为 14。

  • 版本 4.18.0.0 及更高版本:嵌套深度现在仅受内存限制。可以使用库参数更改最大值 SMC_CNC_LibParams.MAX_SUBPROGRAM_NESTING_DEPTH

调用的语法

子程序调用是 G 代码中的特殊程序段,仅由程序段号和调用组成。不允许添加额外的词。

N<SentenceNo> <Name> <BracketOpen> <ActualParamList> <BracketClosed>
N<SentenceNo> DYNCALL <BracketOpen> <SubNameExp> [, <ActualParamListNotEmpty]  <BracketClosed>

<SubNameExp> : An expression with exactly one value of type STRING
<ActualParamList> ::= Empty | <ActualParamListNotEmpty>
<ActualParamListNotEmpty> ::= <ActualParamValue> | <ActualParamValue>, <ActualParamListNotEmpty>

<Name>

有效的 IEC 标识符,最少 3 个字符,最多 80 个字符。它必须对应于定义子程序的文件名(不带扩展名)。大写或小写对子程序名称无关紧要。人物 [a-zA-Z0-9_] 是允许的。

以下关键字对名称无效: RETURN,\\ IF,\\ ELSE,\\ END_IF,\\ CASE,\\ END_CASE,\\ FOR,\\ END_FOR,\\ WHILE,\\ END_WHILE, REPEAT,\\ UNTIL,\\ END_REPEAT.

<ActualParamList>

必须与子程序定义的参数值数量完全相同(请参阅“声明的语法”)。每个参数值的类型必须与声明一致。

<BracketOpen>/<BracketClosed>

出于兼容性原因,在默认设置中使用大括号代替括号 SMC_ReadNCFile2 和子程序调用和声明。括号在 G 代码中有效用于注释。

功能块 SMC_ReadNCFile2 有一个模式(bParenthesesAsComments input) 其中括号不是注释。相反,多行注释是用 (* 并关闭 *).在这种新模式中,大括号和圆括号均可用于子程序调用和声明。

<ActualParamValue>

变量、文字或任何表达式

例子

N10 SUB1()
N20 DRILL(10.0)
N30 SUB2(5, "Text", 2.5)
N40 G36 O#SUBNAME  D'DRILL'    % Indirect call via local variable
N40 DYNCALL(#SUBNAME, 2)       % equivalent to N40 DRILL(2)
N50 DYNCALL($SUBNAME$, 2, 4)   % Indirect call via IEC variable

声明的语法

子程序必须保存在单独的文件中。第一行(既非空行也非注释行)必须包含子程序的声明。以下语法适用:

SUBPROGRAM <Name> <BracketOpen> <FormalParamList> <BracketClosed> <RESTORE_OPT>
<Inhalt Unterprogramm>
END_SUBPROGRAM

<FormalParamList> ::= Empty | <FormalParamListNotEmpty>
<FormalParamListNoEmpty> ::= <FormalParam> | <FormalParam> , <FormalParamListNotEmpty>
<FormalParam> ::= <ParamName> : <ParamType>
<ParamName>   ::= #[a-zA-Z0-9_]+

<ParamType> ::= LREAL | BOOL | STRING ; String with a maximum length of 255 bytes
<RESTORE_OPT> ::= RESTORE_MODES

<ParamName>

名称的长度最多为 80 个字符(不包括前缀 #)。

RESTORE_MODES

如果指定了此关键字,则返回到调用程序时将恢复以下模态状态(设置为调用时的值):

  • 主动 G 代码

  • 相对/绝对模式(G90/G91、G98/G99)

  • 圆平面和2D/3D模式

  • 解码器坐标系(包括缩放)

  • 进给率(路径轴和附加轴)、快进速度、最大加速度和减速度(路径轴和附加轴)

  • 特征标志和通用参数 (G38)

  • 刀具半径(D字)

  • 刀具偏置 (G43)

  • S型材(S字)

以下模态状态不会恢复:

  • 解码器/解释器的当前位置以及当前的基数样条状态。该位置包括整个结构 SMC_POSINFO (即 X、Y、Z、方向和所有附加轴)。

  • 路径预处理 POU(G40-G43、G50-G52、G60-G61、G70-G71)的状态(开/关)

  • 附加轴的模数设置 (PA, PB, …)

注意:不管这个关键字是什么,当从子程序返回到调用程序时,隐式计数器变量(G36、G37)被恢复。

例子

SUBPROGRAM SUB1()                 ; no formal parameters
SUBPROGRAM DRILL(#depth : LREAL)
SUBPROGRAM SUB2(#a : LREAL, #b : STRING, #c : LREAL)
SUBPROGRAM SRM1() RESTORE_MODES

返回的语法

返回要么在子程序文本的末尾(在 END_SUBPROGRAM) 或明确使用以下语法: N<block number> RETURN.

在子程序中使用形参

形式参数的值可以在子程序中通过 #<ParamName>.

形式参数的数量限制为 21。

48. 例子
SUBPROGRAM SUB(#Param1 : LREAL)
N10 G01 X#Param1


调用堆栈的显示

口译员(SMC_NCInterpreter) 的输出包含 10 个最活跃的程序/子程序: aActivePrograms : ARRAY[0..9] OF STRING.第一个条目(aActivePrograms[0]) 是当前解释的程序/子程序。第二个条目(aActivePrograms[1]) 是调用程序/子程序等。如果没有调用程序,则对应的字符串为空。

也可以在插值时显示调用堆栈。这 SMC_DisplayNCCallstack POU 以与解释器相同的格式显示活动程序/子程序,只是稍后(即运行时)。这样做时,解释器输出 CallstackInfo (SMC_NCCallstackInfo) 并将插值器传递给它 VAR_IN_OUT 变量。 SMC_NCCallstackInfo 存储所有调用堆栈更改,包括相应的 SMC_GeoInfo 对象编号,在环形缓冲区中。此时,这将解释时间和插值时间之间可存储的调用堆栈更改次数限制为 128。 由于环形缓冲区不满足多任务标准, SMC_DisplayNCCallstack 必须从解释器任务中调用。

示例程序CNC 实例 07:使用表达式和子程序显示了插值时调用堆栈的显示示例。