1、SIMOTION 编程(一) 2013-05-16 在SCOUT光盘里,有个非常详细的编程指南(点击此处查看),非常好,只是不 知道为什么被放在这么不起眼的位置。该编程指南用来帮助用户获得一个标准、 统一的代码, 并且使代码可以更容易地维护和重新使用。 不仅如此, 错误可以在 早期阶段(例如,由编译器)被识别和避免。 统一外观,可维护以及清晰的源代码对于工程师和工程公司具 有非常重要的意义。 有些遗憾, 这么个好东西是全英文的, 在学习SIMOTION的过 程中, 我挑选出这本手册中比较重要的编程标准, 翻译出来, 希望对大家有所帮 助。 其中规则是原则上必须遵守的, 而建议则是尽量遵守的条目
2、。 其实编程的规 范标准不仅对于SIMOTION工程师有意义, 对于其他编程例如PLC也是可以借鉴的。 代码支持识别错误和bug,例如,通过使用前缀可以简单地识别类型不兼容。 目的:代码问题在早期阶段发现。 规范标准应用程序和库 目的:程序代码更容易学习和提高程序代码的可重用性 模块化 目的:增加程序透明度水平 封装子功能,使用不同的模块进行简单组合,每个模块定义清晰而独立的接口。 增加适用性使代码可以持续改进 目的:改变的各个模块的程序代码对于功能/功能块库或项目/方案影响降到最 低。不同的编程工程师应该可以在单独的模块中修改程序代码。 规则1 : 每一个编程的源文件必须进行文档记录, 特别
3、是专用的FB FC 。 并应该使用统一 的模板,程序模板在SCOUT光盘中有提供。 建议:不使用特殊字符,例如,U,A等。 规则2 : TAB不容许在源代码中使用。 应使用四个空格的缩进。 当使用SCOUT内部ST编辑器 中是自动完成的。 这是为了避免不同的编译器对于TAB的解释长度差异而考虑的。 建议:为提高可读性,源代码单行长度应限制在80 个字符。 建议:各种ST代码段相关的功能应使用换行符分隔。 建议: 整体的意见 (描述一个函数或代码段的战略注释) : 应设在相应的代码 段 开始描述。 局部注释 (战术注释) 如果可能的话, 应位于代码行的同行末尾 - 否 则在相关联的代码行之前。
4、规则3 : 在ST中注释以/ /开始。 注释在斜线符号后开始, 没有任何空格。 出于测试目的,完整的块可以被简单地使用(* *)进行屏蔽。 规则4 : 每个程序单元名称需包含一个前缀。这个前缀表明当前的程序单元功能。规则5 : 使用前缀x, 表明在一个单位中使用数据、 功能、 FB和程序, 以确保少量代码 的 POU的紧凑。 规则6 : 前导下划线字符(“_”)识别功能和功能块是保留给西门子系统功能的。前导 下划线字符不应该被用来在应用程序本身。 规则7 : 不得使用使用大写或小写进行标识符的区分。 一旦某种书写方式的标识符已被选 中,其在所有的源代码中使用。 推荐: 标识符中的名称采用英文。
5、 名称表示上下文中的源代码标识符的意义和目 的。 规则8 : FC / FB的输入和输出变量不使用前缀。如果结构被用于输入和输出变量,那么 该结构的元素成员应具有前缀。 规则9 : 常量不包含前缀。 规则10: 使用前缀后名称以大写字母开始 举例: 局部变量:rMaxLength 规则11: 在系统中定义的名称 (例如,变量和函数的名称)是不允许再使用的。 推荐:名称的最大长度为32 个字符。 规则12: 功能,功能块和程序名称结构应根据下面的示意图 组合 :操作对象属性 例如: 标识符:FCSwapWordBigEndian: 名称:SwapWordBigEndian 操作:Swap 对象:
6、Word 属性:BigEndian 规则13: 前缀和标识符之间使用分隔符(下划线字符)是不允许的。 规则14: 变量前缀用来表示数据类型的内存位置。 括号中的前缀是一种替代方法,使用哪一种需要在整个项目中保持一致。 举例: gasFeeder 全局送料器结构数组 推荐: 使用 字母 e s a 开头并且使用type 作为结尾。 SIMOTION 编程(二) 规则15: 枚举 (枚举) 的元素全部写大写字母。 如果包括单独的单词, 那么使用下划线 字 符分开(常量也是)。 规则16: 前缀和标识符不使用下划线隔开。 推荐:数组范围应从0 开始到“最大值-1”结束。 推荐: 类型定义应在接口部分
7、进行, 特定的设备变量类型须具有独特、 明确的定 义 推荐:类型定义并不适用于基本数据类型。 规则17: 常量的名称总是用大写字母。 为了能够识别单个的单词或缩写, 单词或缩写之间 应插入下划线字符。 推荐:应加以避免直接在代码中使用数值,如果可能的话,使用常量。 规则18: 当声明变量,该变量被缩进,然后由换行符分开。 推荐: 变量只是在默认数据类型初值不适用时进行初始化。 如果可能的话, 在初 始化时,应作出定义的变量运行的原因。 推荐:初始化(分配常量数据),通常使用它的数据类型(文字)实现。 Example: b16Mask1 : WORD := 16#01; /not ok b16M
8、ask2 : WORD := 16#0001; /ok b8Mask3 : BYTE := 2#0000_1010; /ok b32Mask4 : DWORD := 5; /not ok b32Mask5 : DWORD := 16#0000_0005;/ok r32Temp1 : REAL := 40; /not ok r32Temp2 : REAL := 40.0; /ok i16Counter1 : INT := 16#00; /not ok i16Counter2 : INT := 10; /ok 推荐:尽可能的避免在程序中访问操作SIMOTION 设备的过程映像,以提高代码 的可移植
9、性。应在集中的位置进行IO 的定义。 Example: /declaration boJogPos AT %IX10.1 : BOOL; b8Port1 AT %IB1 : BYTE; i16ToolKey AT %IW10 : INT; /cast possible i32ProgNum AT %QD10 : DINT; /access to I/O-Image b8Image := b8Port1; /ok b8Image := %IB1; /not ok 规则19: 每个程序中需要在程序代码中包含一个描述性的标题。描述中包含了以下几点: -功能的说明 -任务分配的说明 -目标系统的要求
10、-程序版本一起与作者和日期 具体可以参考模板和手册中的实例。 推荐: 只要不产生负面影响的理解意义的前提下二元运算符和赋值操作符前后应 均有空格 。 Example: i8SetValue := i8SetValue1 + i8SetValue2; /ok i8SetValue:=i8SetValue1+i8SetValue2; /not ok 推荐:表达式应始终设置在方括号中,以清楚显示的顺序解释。 Example: boSetFlag := (r32ActualPosition 150.0); 推荐: 对于复杂的表达式, 为了突出重点, 每个“子条件”使用一个换行符。 这 意味着代码可以使
11、用透明、清晰的注释。 推荐:条件部分和指令部分之间应保持一个严格的划分。 规则20: 如果一行写不下完整的条件,布尔逻辑运算符应位于每行的最右侧。IF 指令中 的条件需缩进四个空格,THEN 与对应的IF 位于同一高度。如果IF 条件可以在 一行写完, 则THEN 位于此行的最右端, 对于每一个新的结构层次, 括号字符偏 移一个空白, 所以括号中的条件结构层次以相同的方式缩进。 具体可以参考模板 和手册中的实例。 规则21: 一个CASE 指令必须始终包含一个else 分支, 以便能够对运行期间发生的错误进 行处理。 规则22: 主体控制结构中的每个指令均被缩进,须整齐。 规则23: 如果功能
12、或功能块提供错误代码,这些错误码必须始终进行评估。 推荐:一个功能FC 的返回类型应始终声明。 Example: FUNCTION FCSwapWord : WORD /description 推荐:一个函数调用时应该按照声明的顺序进行参数赋值。 输入参数应该有默 认值,因为它可使程序的调用更简短、更透明。 推荐:对于ST 编程,应该每个参数开始一个新行。 推荐: 很多输入参数 (值传递) - 尽可能被封装在一个结构 (更高效的拷贝) 。 在 LAD / FBD 中,个别变量经常需要修改其数值 : 例如对于简单的使用控制变 量 ,可以作为单独的变量设置。输入输出参数从运行的角度来看是更有效的调
13、 用(名称调用) e.g. 用于传递大的数据量 举例: /structure within VAR_IN_OUT FBBottleCheckOutlet( formulaInOut := sFormula4711 ,vectorInOut := sMatrix20118 ,. ); 规则24: 如果参数具有标准意义则标识符和功能方面需要根据PLCopen 的V1.1 规范,然 后应使用适当的标准标识符。 此外, 可以使用Reset 中止函数和函数块并输出显 示resetActive。这两个变量是可选的,PLCopen 的V1.1 中没有定义。 建议:如果程序员使用VAR_INPUT 参数res
14、et 复位,则可以使用VAR_OUTPUT 参 数resetActive。在 复 位过程中此resetActive 参数信号始终存在 (例如: 轴目 前被停止,但还没有到达停止状态。如果可以在一个时钟周期停止,则 resetActive 仅显示一个周期的高电平。 规则25: 与PLCopen 相反,总是使用Done 参数代替inVelocity,INGEAR INSYNC。 推荐:如果用布尔输出变量INGEAR 和INSYNC 名称,那么这些变量应该与 SIMOTION 系统函数的输出:_MC_GearIn,_MC_CamIn 相同(设置为TRUE 时,只 要该轴与主站同步运行轴)。 规则26
15、: 如果程序员使用的VAR_INPUT 参数execute,则 VAR_OUTPUT 参数Done 必须使用。 规则27: FC 和FB 参数不使用前缀。这样做的原因是为了SIMOTION 参数名称和PLCopen的规范保持一致性。 规则28: FC 和FB 参数内的结构元素应使用前缀。 规则29: 参数名称中包含一些词汇, 应选择与口语相同的词语的序列。 参数名称以小写字 母开始。包含一些词汇的名称都写在一起,每一个字以大写字母开始。 推荐:库的名称须包括前缀L(如LCarton)。不使用下划线字符。库名称的最 大字符长度限于8 个字符以内。 SIMOTION 编程(三) 续编程指南翻译 规
16、则30: 所有的功能/功能块/导出类型的名称定义结构为:前缀+该库的名称+名称+ (type)。 这可以防止被分配相同的名称用于其它库。 名称空间的使用是不允许的, 更长的 名字会使处理LAD/ FBD/ MCC 更加困难。 规则31: 每个库包含一个UNIT 的版本历史记录。此UNIT 名称aVersion。 规则32: 扩展类型的定义和常量在单独的UNIT 中独立声明 。 规则33: 在一个库中定义的类型定义最多可以从库中导出两个UNIT。 dProtected 的名称 表示知识产权保护和dPublic 名称表示开放的unit 定义。 规则34: 在一个库中最多有两个unit 定 义全局常
17、量。 支持产权保护的名称为cProtected, 开放的unit 定义为cPublic。 注意:数据和常量定义UNIT 的名称只是为库定义。 举例如下: 规则35: 一种应用定义一个库(例如 DPV1 服务)或者一种设备类型(包装机) 或者相 似的设备定义一个库。 规则36: 在库中的功能或者功能块是被用户程序反复被使用的, 如果功能或者功能块只是 在库中使用, 则功能或者功能块的名称中不包含库的名称, 通用功能或者功能块 按如下规则使用: 1.小的功能或者功能块如果在库中使用独立的UNIT 编写会增加更新时间和成 本,因为当功能调整后每一个使用了此功能的unit 都需要更新,当然如果此功 能
18、或者功能块没有导出则无需更新文档或记录。 2.如果通用功能或者功能块如果处理的数据多或者代码复杂, 需要在库中独立保 存为UNIT, 每个需要导出使用的UNIT 都需要文档记录, 文档记录内部如何使用 即可。 3.集中和更高级别的功能/功能块应该保存在自己独立的库中, 使其更容易复用。 规则37: 库中的unit 数目应尽可能的减少 规则38: 不可以对整个库进行知识产权保护,只对独立的UNIT 进行保护,意味围着可以 独立修改设备的版本。如果没有密码无法修改知识产权保护的库。 规则39: 一个库可以有些unit 加密有些不加,例如可以根据功能调整数据的定义,比如 数组的大小,但是不可以访问源
19、代码。 规则40: 最好是使用ST 编程语言创建库,可以有效的编写复杂的算法。如果库也包含简单功能或者逻辑功能,可以使用图形化语言编程。 规则41: 已经生成的功能/功能块必须适用于在 LAD/ FBD 中使用。 功能块的处理对于用户 需要尽可能简单 - 即使这需要更多的编程时间和资源。 推荐:应编写循环运行状态下使用的功能块。优先的选择为在后台任务中处理。 这也是使用一个无限循环的原因(运动功能的 While true 中应避免循环功能)。 当运行的时候,无限循环的运动任务是无法下载的。 规则42: 只有结构,功能或者功能块需要在接口区做导出声明,使数据进行良好的封装。 本地数据最好是宣布在
20、UNIT 的IMPLEMENTATION 中(unit 全局)或在POU 中。 背景:减少可以导出的代码或常量和类型可以降低文档的成本。 规则43: 库功能中的全局定义 (数据, 实例块) 需要避免或者受限声明, 或者库中的通 用 功能功能块如果不使用也需要受限声明。 规则44: 对于多次调用的功能块参数必须保持一致的处理 ,必须保证所使用的值保持不 变 (例如, 通过输入参数保存在帮助变量和只要值的变化是不允许的, 抑制这些 帮助变量被写入)。 规则45: 由于库不支持调试, 重点是必须放在能够测试以及监测符号浏览器中的变量。 在 这种情况下, 内部变量必须定义成一个合适的形式, 让他们提供
21、足够的执行步骤 和序列信息功能。例如,这可能包括处理状态或实际步数。 推荐:如果很多参数传送,选择一种VAR_IN_OUT 变量使用。例如,使用一个结 构描述配置数据, 实际值, 设定值,TO, 输出 功能块状态。 对于需要经常修改的 控制或者状态变量单独声明为一个输入或者输入输出变量会使LAD、FBD 调用更 为方便。 推荐:如果参数结构要保存在不同的存储位置(断电保持中的设定值,/ HMI 使 用的全局变量值),则可以使用几个VAR_IN_OUT 类型变量。 推荐: 数值参数如果在SIMOTION 中有默认值, 例如: 速度, 加速度, 加加速度, 可以使用-1.0 的值初始化。 如果用户不进行适当的参数分配, 则会使用默认值。 规则46:出于性能方面的考虑,工艺对象的实际值如果功能块没有使用,则不 写入到VAR_IN_OUT 参数结构或连接到一个输出变量。 规则47: 应该使用结构数组, 而不是数组结构。 背景: 这简化了在 HMI 的处理, 也可以更 快数据传输到HMI。 推荐: SIMOTION 系统功能包含PLCopen 功能块, 可以用于编写标准功能, 如 JOG, Homing 等程序功能块编程。