C 程序块应用举例 步骤 2:软件编程 1)创建数据块 DB1,定义两组为 100 个字节的数组 2)在“项目树”>“数据块”>“属性”下,将优化块访问勾选去掉。 -292-
CTMC 运动控制器用户手册 3)创建数据块 DB1 的写数据和读数据的缓冲区,定义两组为 100 个字节的数组 4)在 OB1 中,从“指令”-->“S7 通信”下,调用 Get、Put 通信指令,程序编写如下: CALL “GET” , %DB2 //调用 PUT,使用背景 DB 块:DB2 REQ :=%M0.0 //系统时钟 0.1 秒脉冲 ID :=W#16#0100 //连接号,要与连接配置中一致,创建连接时的连接号 DONE :=%M100.0 //为 1 时,发送完成 ERROR :=%M100.1 //为 1 时,有故障发生 STATUS :=%MW102 //状态代码 ADDR_1 :=P#DB1.DBX0.0 BYTE 100 //从通信伙伴数据区读取数据的地址 ADDR_2 :=P#M10.0 BYTE 10 //从通信伙伴数据区读取数据的地址 SD_1 :=P#DB1.DBX0.0 BYTE 100 //本地接收数据地址 SD_2 := P#M10.0 BYTE 10 //本地发送数据区 CALL“PUT”, %DB3 //调用 GET,使用背景 DB 块:DB3 -293-
C 程序块应用举例 REQ :=%M0.0 //系统时钟 0.1 秒脉冲 ID :=W#16#0100 //连接号,要与连接配置中一致,创建连接时的连接号 NDR :=%M110.0 //为 1 时,接收到新数据 ERROR :=%M110.1 //为 1 时,有故障发生 STATUS :=%MW112 //状态代码 ADDR_1 :=P#DB1.DBX100.0 BYTE 100 //发送到通信伙伴数据区的地址 ADDR_1 :=P#M0.0 BYTE 10 //发送到通信伙伴数据区的地址 RD_1 :=P#DB1.DBX100.0 BYTE 100 //本地发送数据区 RD_1 :=P#M0.0 BYTE 10 //本地发送数据区 步骤 3:监控结果 通过在 S7-1200 侧编程进行 S7 通信,实现两个 CPU 之间的数据交换,监控结果: 1200>>M228IL(MB0-MB0) 1200<<M228IL(MB10-MB19) 1200<<M228IL -294-
CTMC 运动控制器用户手册 1200>>M228IL ! 注意 M228IL 中 V 区对应于 DB1,即在 PUT 指令中使用的通信伙伴数据区 ADDR_1=P#DB1.DBX0.0 BYTE 100 在 M228IL 中对于为 VB0~VB99。即在 GET 指令中使用的通信伙伴数据区 ADDR_1=P#DB1.DBX100.0 BYTE 100 在 M228IL 中对于为 VB100~VB199。 8.2.4 其它产品与 CTMC 系列 CPU 的网口通讯 示例 1:组态王与 CTMC 系列 CPU 的 S7 协议通信 本例以组态王为主站,CTMC 系列 CPU 做从站,进行 S7 协议的通信。 主站配置 参考以下步骤对组态王软件进行 S7 协议主站的配置: 1)在串口的设备配置向导中选择 S7 通信协议 -295-
C 程序块应用举例 从站配置 在 CTMC 系列 CPU 的系统块中配置好 IP 地址即可,操作示意如下: 示例 2:昆仑通态触摸屏与 CTMC 系列 CPU 的 S7 协议通信 本例以昆仑通态触摸屏为主站,CTMC 系列 CPU 做从站,进行 S7 协议的通信。 备注:昆仑通态上位机也可以作为主站与 CTMC 系列 CPU 进行 S7 协议的通信。 主站配置 参考如下步骤对昆仑通态触摸屏进行 S7 协议的主站配置: -296-
CTMC 运动控制器用户手册 从站配置 在 CTMC 系列 CPU 的系统块中配置好 IP 地址即可,操作示意如下: -297-
C 程序块应用举例 示例 3:威纶通触摸屏与 CTMC 系列 CPU 的 S7 协议通信 本例以威纶通触摸屏为主站,CTMC 系列 CPU 做从站,进行 S7 协议的通信。 主站配置 从站配置 在 CTMC 系列 CPU 的系统块中配置好 IP 地址即可,操作示意如下: -298-
CTMC 运动控制器用户手册 8.3 高速计数输入程序示例 8.3.1 高速输入模式 13 程序示例 初始化模式 13(HSC0 为例) HSC0 为外部捕获信号的单相计数器(模式 13),初始化步骤如下: 1、用初次扫描存储器位(SM0.1=1)调用执行初始化操作的子程序。由于采用了这样的子程序调 用,后续扫描不会再调用这个子程序,从而减少了扫描时间,也提供了一个结构优化的程序。 2、初始化子程序中,根据所希望的控制操作对 SMB37 置数。例如: SMB37=16#F8 产生如下结果: 允许计数 写入新的初始值 写入新的预置值 将初始计数方向设为增 将启动和捕获输入设为下降沿有效 3、执行 HDEF 指令时,HSC 输入置 0,MODE 输入置 13。 4、向 SMD38(双字)写入所希望的初始值(若写入 0,则清除)。 5、向 SMD42(双字)写入所希望的预置值。 6、为了捕获当前值(CV)等于预置值(PV)中断事件,编写中断子程序,并指定 CV=PV 中断事 件(事件号 12)调用该中断子程序。 7、执行全局中断允许指令(ENI)来允许 HSC0 中断。 8、执行 HSC 指令,使 PLC 对 HSC0 编程。 9、退出子程序。 梯形图如下: -299-
C 程序块应用举例 HSC0 接入脉冲信号至 I0.0,再给 HSC0 接入捕获信号至 I0.2, 此例中,运行初始化程序后,如果捕获信号 I0.2 输入下降沿,HSC0 的当前值就会锁存至 SMD930。 8.3.2 高速输入模式 14 程序示例 初始化模式 14(HSC0 为例) HSC0 为外部捕获信号的单相计数器(模式 14),初始化步骤如下: 1、用初次扫描存储器位(SM0.1=1)调用执行初始化操作的子程序。由于采用了这样的子程序调 用,后续扫描不会再调用这个子程序,从而减少了扫描时间,也提供了一个结构优化的程序。 2、初始化子程序中,根据所希望的控制操作对 SMB37 置数。例如: SMB37=16#F8 产生如下结果: 允许计数 写入新的初始值 写入新的预置值 将初始计数方向设为增 将启动和捕获输入设为下降沿有效 3、执行 HDEF 指令时,HSC 输入置 0,MODE 输入置 14。 4、向 SMD38(双字)写入所希望的初始值(若写入 0,则清除)。 5、向 SMD42(双字)写入所希望的预置值。 6、为了捕获当前值(CV)等于预置值(PV)中断事件,编写中断子程序,并指定 CV=PV 中断事 件(事件号 12)调用该中断子程序。 7、执行全局中断允许指令(ENI)来允许 HSC0 中断。 8、执行 HSC 指令,使 PLC 对 HSC0 编程。 9、退出子程序。 梯形图如下: -300-
CTMC 运动控制器用户手册 HSC0 在 PLC 内部已经连接至 Q0.0,再给 HSC0 接入捕获信号至 I0.2, 此例中,运行初始化程序后,如果 Q0.0(通常是轴 0)输出脉冲,当捕获信号 I0.2 输入下降沿, HSC0 的当前值就会锁存至 SMD930。 -301-
9 C 程序块应用举例 9 本章主要介绍 CTMC 运动控制器的 C 程序块应用,具体内容如下: 9.1 在 Magicworks PLC 中的 C 语言编程步骤 9.2 C 语言基础 9.3 运算符与表达式 9.4 for 循环语句 9.5 选择语句 9.6 libplc200.a 库介绍 -302-
C 程序块应用举例 本章概要 C 函数编程语言是 MagicWorks PLC 软件功能的升级加强。在原有梯形图和 STL 两种编程语言基础 上,允许 C 函数编程与梯形图等编程语言一起工作。利用 C 语言编写功能块,增强程序的可读性和 维护性,同时,C 语言丰富的运算函数可实现各种调用功能,节省了内部空间,也提高了编程效率。 目前 CTMC 全系列 V2.84 固件版本的 PLC 支持 C 函数编程语言。 本章介绍 MagicWorks PLC 的 C 语言编程功能的使用,具体内容如下: 在 Magicworks PLC 中的 C 语言编程步骤 C 语言基础 运算符与表达式 for 循环语句 选择语句 libplc200.a 库的介绍 9.1 在 Magicworks PLC 中的 C 语言编程步骤 1、在 MagicWorks PLC 中新建项目,选择“程序块”后右键点击空白处,选择“插入新对象” “C 程序块”。 2、编辑 C 程序属性,此处定义的符号名将自动作为 C 函数名,建议不要用中文定义,复制代码时 CF 块的符号名与 C 语言函数名一定要相同,否则将不执行。如果工程师希望进行代码保护,也可 以参考以下步骤增加密码保护。 -303-
C 程序块应用举例 3、函数创建成功后,可在程序块中看到 CF0。 4、双击 CF0,进入 C 函数程序编程窗口。MagicWorks PLC 新建 CF0 后会默认加入以下三个头文 -304-
CTMC 运动控制器用户手册 件。 5、在局部变量窗口中定义需要外部输入或输出的参数值,全部定义完成后点击“ ”初始化 C 程 序块,重新生成函数模板。C 函数的名称和函数参数不要随便改动。 <备注> 局部变量窗口最多只能定义 16 个变量。 6、在生成的模板中,编写程序,编程完成后点击执行编绎操作,输出窗口中若无提示错误,即可 被 OB1 或其他 FC 调用。从参数符号表定义的参数,输入参数会转变 C 语言相应类型的输入参数, 参数可以直接使用;而输入输出和输出参数,会变成相应类型的指针,通过指针在 C 函数里将结果 写回 STL 系统,即 C 函数无返回值,返回值只能通过指针传回。 -305-
C 程序块应用举例 7、编写完成的 C 函数子程序,需在 OB1 主程序或者其它执行的 FC 中调用。当执行程序块下载时, C 子程序也将一同下载到 PLC 中。(注:C 函数内部不可在线监控,但是在梯形图调用处是可以监 控输入输出的)。以下程序执行的功能为:如果 M0.0=0,则 vw4=vw0-vw2;如果 M0.0=1,则 vw4=vw0+vw2。 -306-
CTMC 运动控制器用户手册 9.2 C 语言基础 9.2.1 头文件 编译器提供了许多在头文件中声明的标准函数。头文件也称为包含文件,头文件作为一种包含功能 函数、数据接口声明的载体文件,主要用于保存程序的声明。 <stdio.h> 输入输出函数; <stdarg.h> 支持变元个数可变函数的宏; <math.h> 数学浮点函数; <stdlib.h> 内存分配函数; <string.h> 字符串处理函数; <stdbool.h> bool 类型和布尔值 true 和 false; <complex.h> 支持复数; <ctype.h> 字符分类函数; <wctype.h> 宽字符转换函数。 头文件包含了各种函数的声明以及各种变量的声明,MagicWorks PLC 新建 C 程序块后会默认加入 以下三个头文件。 #include \"math.h\" #include \"stdio.h\" #include \"plc200.h\" 其中,头文件<stdio.h>含有大量高级输入/输出(I/0)函数的声明,是 C 语言中的标准输入输出头文件, stdio 即 stand input output 的缩写,程序中含有输入输出操作,就必须使用该头文件。 头文件<math.h>中声明了常用的一些数学运算,比如乘方,开方运算、求三角函数、对数之类的函 数,可以直接调用。 plc200.h 是合信 200 系列小型 plc 的库 plc200.a 的头文件,库 libplc200.a 主要使用户能够调用底层 函数和 STL PLC 系列进行交互,用户可以使用的函数可在头文件 plc200.h 中查看,头文件 plc200.h 在编程软件安装目录\\ccompile\\include\\plc200.h 里。 9.2.2 变量 1、定义变量 变量定义的一般形式:数据类型 变量名 例如:FP32 real1; //定义 32 位浮点数 S16 int1; //定义 16 位有符号整型 const FP32 PI=3.1415926; //定义 32 位浮点数常量 PI 局部变量窗口定义的参数值,执行“初始化 C 程序块”,程序编程窗口会自动将参数定义到子程序 中。 -307-
C 程序块应用举例 ! 注意 变量名必须以字母或下划线开头,名字中间只能由字母、数字和下划线“_”组成;最后一个 字符可以是类型说明符。 变量必须先定义,后使用。 一个变量名只能定义一次,变量建议定义在程序头部,变量定义不允许使用中文变量,且严格 区分大小写。 一些较简单的字符变量名容易跟一些原有计数器混淆,例如 c 表示计数器,c1 就不允许使用 2、static 局部变量与普通变量 局部变量与普通变量的区别 1) 内存分配和释放 普通局部变量只有执行到变量定义的语句时才分配空间。 static 局部变量在编译阶段(函数还没有执行),变量的空间已经分配。 普通局部变量离开作用域{},自动释放其空间,也就无法使用此变量。 static 局部变量只有在整个程序结束的时候才将其自动释放。 2) 初始化 普通局部变量不初始化,为随机值。 static 局部变量不初始化,为 0。 static 局部变量初始化语句只有第一次执行时有效,但是可以赋值多次。 static 局部变量只能用它常量初始化。 变量在全局数据区分配内存空间;编译器自动对其初始化其作用域为局部作用域,当定义它的函数 结束时,其作用域随之结束。 C 语言编程举例如下:只要 var1 不等于 0,则 var2 加一。 void CF_3( S16 var1, S16 *var2 ) { static S16 temp; if(var1!=0) { temp=temp+1; -308-
CTMC 运动控制器用户手册 } setS16(var2,temp); } //temp 变量用 static 修饰符 9.2.3 注释的使用 编写 C 语言时使用注释有助于对代码的理解,注释不进行编绎,不会影响程序的执行。在 C 语言中 有两种注释方式: 以/*开始、以*/结束的块注释(block comment) 以//开始、以换行符结束的单行注释(line comment) Magicworks PLC 中既可手动注释,也可以采用注释键进行注释。点击菜单栏中的注释键 即可注 释,点击菜单栏中的取消注释键 即可取消注释。 9.2.4 各类数值型数据间的混合运算 在进行运算时,不同数据的类型需要转换成同一类型数据,然后进行运算。 运算过程:先自动转换成同类数据,再进行运算。 转换规则:低字节类型转换成高字节类型。 C 语言编程例程:c = S16 a + FP32 b,a 将自动转换为 FP32 的数据类型,再与 b 相加,结果得到 一个 FP32 型的 c。 C 语言编程如下: #include \"math.h\" #include \"stdio.h\" #include \"plc200.h\" void CF_2( S16 data_a, FP32 data_b, FP32 *data_c ) { FP32 temp; temp=data_a+data_b; setFP32(data_c,temp); } 编译后得到的 CF 块,通过 OB1 或者其他 FC 调用: -309-
C 程序块应用举例 9.2.5 强制类型转换 将指定表达式的值转换为指定类型,需要编程者指定需要转换的类型。 形式:(类型名)(表达式) 例如:(S16)(a+b) 说明:1)类型名和表达式需加括号 2)在强制类型转换时,得到一个所需类型的中间变量,原来变量类型未发生变化。 C 语言编程例程:将一个 32 位浮点数四舍五入取整然后转换成 16 位整数。 void CF_2(FP32 data_b, S16 *data_c ) { S16 temp; If (data_b>0) { temp=(S16)(data_b+0.5); } else { temp=(S16)(data_b-0.5); } setS16(data_c,temp); } 编译后得到的 CF 块,通过 OB1 或者其他 FC 调用: 9.2.6 数组 数组是一组有序数据的集合,若将有限个类型相同的变量的集合命名,这个名称为数组名;数组中 每个元素的数据类型都相同,用户通过数组名和下标来确定数组中的元素。 一维数组的定义方式:类型说明符 数组名[整形常量表达式] 例如:FP32 real0[10]; 说明:定义了一个数组,数组名为 real0,有 10 个元素,每个元素的类型均为 FP32 型;这 10 个 元素分别是 real[0]、real[1]、real[2]、……real[8]、real[9]。 初始化数组:数组可在声明的初始化,初始化数组时,各个索引变量的值要封闭在{}内,并用逗号 分隔,例如:S16 aa[3]={2,6,1};等价于:S16 aa[3];aa[0]=2;aa[1]=6;aa[2]=1; -310-
CTMC 运动控制器用户手册 ! 注意 下标从 0 开始。如:数组第 1 个元素为 real1[0],第 8 个元素为 real1[7]。 C 语言一般是不允许对数组的大小做动态定义的,如 FP32 real1[n],这是不允许的。 语言不检查数组下标越界,因此使用时不要越界使用,本例中数组元素个数是 10 个,下标范 围为:0-9,不能超出 9。 数组中的各元素的存储是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起。 C 语言编程示例:将 VD100 开始连续 10 个值,复制到 VD200 后。 void CF_0( void* real1, void* real2 ) { S16 i,j; FP32 temp[10] ={0,0,0,0,0,0,0,0,0,0}; //定义数组 for (i=0;i<10;i++) { temp[i]=getFP32(real1+4*i); //数组地址 } for (j=0;j<10;j++) { set FP32((real2+4*j),temp[j]); } } 调用生成的 CF0 状态表结果如下所示: -311-
C 程序块应用举例 9.3 运算符与表达式 9.3.1 赋值运算符与赋值表达式 1、赋值运算符= 赋值表达式:将一个数值赋给一个变量或将一个变量的值赋给另一个变量。 赋值形式:变量名=常量或表达式; 赋值作用:将右边常量或表达式的值赋给左边的变量。如: a=3、a=b*c ! 注意 所有的语句,包括赋值语句,必须要以分号“;”结尾。 赋值后,原来左边的值被右边表达式的值替换 如果右边表达式的值类型与左边变量的类型不一致,以左边变量的类型为准,将右边表达式值 的类型自动转换为左边变量的类型。 2、多重赋值运算符:多重赋值是将表达式的值同时赋给几个变量,在这种情况下,要把被赋值的 变量名按次序写在赋值号的左边。 赋值形式:变量 1=变量 2=…=变量 n=表达式 等价于:变量 1=(变量 2=(…=(变量 n=表达式))) 例如:a=b=c=7; 3、复合赋值运算符:在赋值符“=”之前加上其它运算符。常见的有:+=、-=、*=、/=、%= 复合赋值运算的功能:与左边的变量进行复合运算后再赋给左边的变量。 -312-
CTMC 运动控制器用户手册 例如: 等价于 a=a+3 a+=3; 等价于 x=x*(y+8) x*=y+8; x%=3; 等价于 x=x%3 int a=1,b=2,c=2; c*=a-b; 等价于 c=c*(a-b)=2*(-1)=-2 9.3.2 算术运算符 C 语言中的算术运算符有: +:加或取正值运算符 -:减或取负值运算符 *:乘运算符 /:除运算符 %:取余运算符 其中,加减乘除均为取余运算符,它们要求有两个运算对象。 9.3.3 自增自减运算符 运算符说明:++表示自增,变量值加 1, --表示自减,变量值减 1。 用法 1:单独作为一个表达式被使用。例如:i++或者++i 等价于 i=i+1 用法 2:出现在其他表达式中参与运算,++i/--i 表示 i 自增/自减 1 后再参与其它运算;而 i++/i-- 则 是 i 参与运算后,i 的值再自增/自减 1。 例如:S16 j,i=3; j=++i; // i,j 的值为 4 j=i++; // j 的值为 4,然后 i 的值变为 5 j=-(i++); // j 的值为-5,然后 i 的值变为 6 9.3.4 关系运算符与表达式 关系运算:比较两个操作数是否满足给定的关系,用于简单的条件判断。在 C 语言中有以下关系运 算符: (1) < 小于 (2) <= 小于或等于 (3) > 大于 (4) >= 大于或等于 (5) == 等于 (6) != 不等于 关系运算符的结果只能是 0 或者 1,值为真时结果为 1,值为假时结果为 0。 例如:3.24<=2.98; //值为假,运算结果为 0 0.5!=3+1; //值为真,运算结果为 1 关系表达式:用关系运算符将两个表达式(算术表达式、关系表达式、逻辑表达式、赋值表达式、 字符表达式)连接起来的式子,称为关系表达式 关系表达式的一般形式为:表达式 关系运算符 表达式 关系运算符的优先级低于算术运算符,高于赋值运算符。 例如:a=1+2>3-1; //等价于 a=((1+2)>(3-1)),结果为 a=1 -313-
C 程序块应用举例 9.3.5 逻辑运算符与表达式 逻辑运算也称布尔运算,用于复杂的条件判断。 表 9-1 运算符 运算符 含义 优先级 ST 描述 NOT ! 逻辑非 1 AND OR \&\& 逻辑与 2 ll 逻辑或 3 逻辑表达式的一般形式:表达式 逻辑运算符 表达式 表 9-2 逻辑运算真值表 A 取值 B 取值 !A A\&\&B AllB 1 1 非0 非0 0 0 1 0 1 非0 0 0 0 0 0 非0 1 0 00 C 语言编程例程:当(a>b)\&\&(b>c)结果为真时 d=1,当(a>b)\&\&(b>c)结果为假时 d=0。 void CF_1( BOOL *data_d ) { S16 data_a=3,data_b=2,data_c=1; if ((data_a>data_b)\&\&(data_b>data_c)) { *data_d=1; } else { *data_d=0; } } 编译后得到的 CF 块,通过 OB1 或者其他 FC 调用: 9.3.6 条件运算符与条件表达式 条件运算符与条件表达式 有两个符号:问号和分号,它与三个操作数组成三元运算。 一般形式:<表达式 1>?<表达式 2>:<表达式 3> 优先级:逻辑>条件>赋值 -314-
CTMC 运动控制器用户手册 例如:S16 max,a=5;b=3; max=a>b?a:b 结果:max=5 C 语言编程例程:比较 2 个值的大小,并将最大值输出。 void CF_0( FP32 real1, FP32 real2, FP32 *max ) { FP32 max_t; max_t=real1>real2?real1:real2; setFP32(max,max_t); } 编译后得到的 CF 块,通过 OB1 或者其他 FC 调用: 9.4 for 循环语句 在应用程序中,需要多次执行某些步骤,这个过程叫循环;for 循环是编程语言中一种循环语句, 循环程序的设计需要建立程序使它能够循环返回并循环执行自身程序。 for 循环语句的一般形式: for(单次表达式;条件表达式;末尾循环体) { 中间循环体; } 例如:for (i=1;i<=100;i++) { sum=i+sum; } for 循环中的语句反复被执行,每次循环后,变量 i 会自动加 1。i=1 和 i<=100 是循环控制变量的起 始值和终止值。当控制变量达到终止值时,程序就执行 for 语句后的下一条指令。 例如:求 1-20 的平方和! void CF_1( S16 *int3 ) { S16 int3_t=0; S16 i; for (i=1;i<=20;i++) { int3_t=int3_t+i*i; } setS16(int3,int3_t); } -315-
C 程序块应用举例 编译后得到的 CF 块,通过 OB1 或者其他 FC 调用: 9.5 选择语句 9.5.1 if 选择结构语句 if 选择结构:判断 if 条件,根据判断结果执行后续操作的选择结构。 1)单分支 if 选择结构的一般格式: if(表达式) //表达式:指判断条件,真为 1,假为 0 { 执行语句; //仅当表达式为真时,才执行此处执行语句 } 例如:输入一个数,判断能否被 4 或者 7 整除,满足条件输出为 1。 void CF_0( S16 int1, S16 *out1 ) { S16 out_t=0; if (int1%4==0||int1%7==0) { out_t=1; } setS16(out1,out_t); } 编译后得到的 CF 块,通过 OB1 或者其他 FC 调用: 2)双分支 if 选择结构的一般格式: if(表达式) //表达式:指判断条件,真为 1,假为 0 { 执行语句; //仅当表达式为真时,才执行此处执行语句 } else { 执行语句; //条件为 0,执行 else 后的语句 } 例如:输入一个数,偶数输出 a,奇数输出 b。 void CF_0(S16 int1, U8 *out1 ) { -316-
CTMC 运动控制器用户手册 char out; if (int1%2==0) { out='a'; } else { out='b'; } setU8(out1,out); } 编译后得到的 CF 块,通过 OB1 或者其他 FC 调用: 3)多重 if 选择结构的一般格式: if(表达式) { 执行语句; } else if(表达式 1) { 执行语句; } else if(表达式 2) { 执行语句; } …… else { 执行语句; } //最后一个 else{}可以省略,有则必须放在 else if 后面 例如:输入成绩,大于等于 90 为 A,80-89 为 B,70-79 为 C,60 到 69 为 D,低于 60 为 E。 多重 if 执行的流程图如下: -317-
C 程序块应用举例 C 语言编程如下: void CF_1( S16 score, U8 *level ) { char level_t; if (score>=90) { level_t='A'; } else if (score>=80) { level_t='B'; } else if(score>=70) { level_t='C'; } else if(score>=60) { level_t='D'; } else { level_t='E'; } setU8(level,level_t); } 9.5.2 switch 多分支选择语句 switch 语句是多分支条件判断语句,它根据表达式的值使程序从多个分支中选择一个用于执行的分 支。 switch 的一般格式: switch(表达式) { case 常量表达式 1 : 语句 1; -318-
CTMC 运动控制器用户手册 break; case 常量表达式 2 : 语句 2; break; …… case 常量表达式 n : 语句 n; break; default : 语句 n+1; } ! 注意 case 条件执行语句后需加 break 跳出 switch 结构,否则无法分支; 常量表达式的值必须互不相等,否则有二异性; case 的顺序无关紧要, default 可有可无。 switch 语句不等同于 if 语句,switch 只能进行值的相等性检查,不是逻辑判断;if 语句不但可 以进行值的相等性判断,还可以计算关系表达式或逻辑表达式,进行逻辑判断的真假。 例如: void CF_0( S16 Level, BOOL *heat1, BOOL *heat2, BOOL *heat3, BOOL *fan ) { *heat1=*heat2=*heat3=*fan=0; switch (Level) { case 1:*fan=1; break; case 2:*fan=0; break; case 3:*heat1=1; break; case 4:*heat1=*heat2=1; break; case 5:*heat1=*heat2=*heat3=1; break; default:*heat1=*heat2=*heat3=1; } } 9.6 libplc200.a 库介绍 libplc200.a 库为 Magicworks PLC 自带的库,该库中含有从 STL 取值和将值写回 STL 的函数以及 STL 系统与 C 语言系统的数据转换操作函数,用户可直接调用这些函数。用户可以使用的函数可在 头文件 plc200.h 里查看,头文件 plc200.h 在编程软件安装目录\\ccompile\\include\\plc200.h 里。 -319-
C 程序块应用举例 下面将对 C 程序块的数据类型以及各种操作函数进行介绍。 9.6.1 CF 块参数符号表中可选择的数据类型 表 9-3 CF 块支持的数据类型 数据类型 注释 关键字 BOOL 位 U8 unsigned char S8 8 位无符号数 unsigned char U16 8 位有符号数 S16 16 位无符号数 signed char U32 16 位有符号数 unsigned short S32 32 位无符号数 FP32 32 位有符号数 signed short void* unsigned int 浮点数 指针:指向任何类型的数据 signed int float -- <备注> void*可以指向任何类型的数据,所有提供指针均使用 void* 型,让用户在 C 代码中进行强 制转换,返回值为空,返回结果,可通过指针传递。 9.6.2 大小端转换 由于 STL 系统的数据使用的是大端模式,而 C 语言使用的是小端模式,因此直接操作指针赋值会 有字节序混乱的问题,因此我们提供了一组通过指针从 STL 取值和将值写回 STL 的函数,函数的 具体形式在 MagicWorks PLC 安装目录\\ccompile\\include\\plc200.h 里。 大端模式:数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。 小端模式:是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。 参数通过指针在 C 语言系统和 STL 系统进行传递时,由于 C 语言系统使用的是小端模式,而 STL 系统使用是的大端模式,所以需要调用大小端转换接口。 9.6.3 STL 系统与 C 语言系统的数据转换操作函数 1、通过指针将值写回 STL 环境:由于输入输出和输出参数会变成相应类型的指针类型,且大小端 转换的问题,所有的输入输出或输出参数都要通过以下指令将结果从 C 语言写回到 STL 环境。 void setU8(U8 *P, U8 d); //将一个 U8 数据,从 C 语言写回 STL 系统 void setS8(S8 *P, S8 d); //将一个 S8 数据,从 C 语言写回 STL 系统 void setU16(U16 *P, U16 d); //将一个 U16 数据,从 C 语言写回 STL 系统 -320-
CTMC 运动控制器用户手册 void setS16(S16 *P, S16 d); //将一个 S16 数据,从 C 语言写回 STL 系统 void setU32(U32 *P, U32 d); //将一个 U32 数据,从 C 语言写回 STL 系统 void setS32(S32 *P, S32 d); //将一个 S32 数据,从 C 语言写回 STL 系统 void setFP32(FP32 *P, FP32 d); //将一个 FP32 数据,从 C 语言写回 STL 系统 void setBOOL(BOOL *P, BOOL d); //将一个 BOOL 数据,从 C 语言写回 STL 系统 例子如下:输入 int1 与 int2 相加,输出 int4 进行了大小端转换,输出结果正确;输出 int3 没有进行 大小端转换,输出结果不正确。 2、通过指针从 STL 取值:如果在 C 函数输入参数中直接调用 PLC 的 V 区、M 区等寄存器,可以 将 PLC 寄存器的指针输入给 C 函数,通过取指针值的方式获取 PLC 内存区的值到 C 语言,但必须 通过以下函数进行转换。 U8 getU8(U8 *p); //从 p 地址取得一个 C 语言系统可用的 U8 数据 S8 getS8(S8 *p); //从 p 地址取得一个 C 语言系统可用的 S8 数据 U16 getU16(U16 *p); //从 p 地址取得一个 C 语言系统可用的 U16 数据 S16 getS16(S16 *p); //从 p 地址取得一个 C 语言系统可用的 S16 数据 U32 getU32(U32* p); //从 p 地址取得一个 C 语言系统可用的 U32 数据 S32 getS32(S32* p); //从 p 地址取得一个 C 语言系统可用的 S32 数据 FP3 getFP32(FP32* p); //从 p 地址取得一个 C 语言系统可用的 FP32 数据 FP3 getBOOL(BOOL* p); //从 p 地址取得一个 C 语言系统可用的 BOOL 数据 <备注> 不通过指针从 STL 取值:输入变量不通过指针的方式,而是输入变量直接获取 PLC 寄存器 -321-
C 程序块应用举例 的值,就不需要使用 get 函数。 C 语言编程如下: 1、将 VW100 开始连续 20 个 VW 值赋给 VW200 地址段。 void CF_2( void* int1, void* int2 ) { S16 r,i; for(i=0;i<20;i++) { r=getS16(int1+2*i); setS16((int2+2*i),r); } } 调用生成的 CF 块 状态表结果如下所示: 2、将 V 区开始的 LEN 个 INT 值进行大小排序,显示到另一个 V 区。 void CF_0( void* varin, S16 len, void* varout ) { S16 i,j,n,k,l; S16 temp[len]; for (l=0;l<len;l++) //将 V 区的值存入 temp 数组 { temp[l]=getS16(varin+2*l); } for (i=len;i>1;i--) //冒泡法将大小值排序,每次最大就像气泡一样\"浮\"到数组的上面 { for(j=0;j<i-1;j++) //依次比较相邻的两个元素,使较大的元素向后移 if (temp[j]<temp[j+1]) { n=temp[j]; -322-
CTMC 运动控制器用户手册 temp[j]=temp[j+1]; temp[j+1]=n; } } for(k=0;k<len;k++) //将 temp 数组值传出到 V 区 { setS16((varout+2*k),temp[k]); } } 编译后得到的 CF 块,通过 OB1 或者其他 FC 调用: 状态表结果如下所示: 9.6.4 获取内存基地址的操作函数 U8 *getLBase(void); //获取地址 LB0 的值 U8 *getIBase(void); //获取地址 IB0 的值 -323-
C 程序块应用举例 U8 *getQBase(void); //获取地址 QB0 的值 U16 *getAQBase(void); //获取地址 AQW0 的值 U16 *getAIBase(void); //获取地址 AIW0 的值 U8 *getSMBase(void); //获取地址 SMB0 的值 U8 *getVBase(void); //获取地址 VB0 的值 U8 *getTVBase(void); //获取地址 T0 的值(定时器值) U8 *getTBBase(void); //获取地址 T0 的值(定时器位) U8 *getSBase(void); //获取地址 SB0 的值 U8 *getCVBase(void); //获取地址 C0 的值(计数器值) U8 *getCBBase(void); //获取地址 C0 的值(计数器位) U8 *getACBase(void) //获取地址 AC0 的值 -324-
附录 附录具体包含以下内容: A 运控相关概念介绍(仅 M228IL 支持) B CANfree 通信指令库介绍 C 以太网“ct_socket”通信库指令介绍 D 以太网设置库指令介绍 E Trace 追踪功能 F 订货信息 -325-
附录 A 运控相关概念介绍(仅 M228IL 支持) 【插补】 插补即根据给定的数学函数,在理想的轨迹式轮廓上的已知点之间,确定一些中间点的一种方法。 插补方式有:直线插补、圆弧插补等。 【直线插补】 选择四轴中任意两轴进行直线插补。 位置控制中,以直线为轨迹对实现群组化的 X 轴、Y 轴这 2 轴、或者包括 Z 轴在内的 3 轴的电机动 作进行控制的插补控制。指定方法通过终点指定。 【圆弧插补】 从四轴中任选两轴进行圆弧插补。圆弧插补从当前位置开始,根据所指定的圆心、终点位置、圆弧 半径(正数或负数)及插补的方向(按顺时针或逆时针)来进行。 位置控制中,以圆弧为轨迹对实现群组化的 X 轴、Y 轴这 2 轴的电机动作进行控制的插补控制。圆 弧的指定方法包括中心点指定、通过点指定两种。 【连续插补】 连续插补是执行一系列插补指令的过程,例如连续执行直线插补、圆弧插补、直线插补、等指令。 在此过程中线段与线段之间,运动没有停顿,速度保持连续。 速度 表示连续插补速度曲线 max. 表示非连续插补速度曲线 m in. 连续插补起始点 第一段终点 第二段终点 时间 连续插补终点 该点速度取决于每段插补之间的角度和 最大速度(ma x.)、最小速度( min.) 【PTP 控制】 以位置为目标,达到位置即停止,表示为 Point to Point。以下简称为「PTP 控制」。 1)速度达到 max. 后按照该速度匀速运行,收到 STOP 信号后,减速至 min. 停止,即完成目标位 置。 -326-
CTMC 运动控制器用户手册 速度 max. min. TA 时间 2)速度未达到 max. ,收到 STOP 信号后,减速至 min. 停止,即完成目标位置。 速度 max. min. 时间 3)第一段位置执行完成后立即执行下一段位置。 速度 max. min. TA 时间 【SPD 控制】 以速度为目标,达到该速度后匀速运行,表示为<Set Speed Point>。本手册中简称为「SPD 控 制」。 1)速度达到目标速度 set_speed 后按照该速度匀速运行,收到 SOFT_STOP 信号/RUN=0 后,减 速至 min. 停止,收到 E_STOP 命令后立即停止。 速度 E _STOP Set _speed RUN=0/SOFT_STOP min. TA TD TD 时间 2)速度达到目标速度 set_speed 1 后按照该速度匀速运行,运行过程中目标速度 set_speed 1 被修 -327-
附录 改为 set_speed 2,由当前速度加速运行到新的目标速度 set_speed 2 后,若收到 SOFT_STOP 信 号/RUN=0,减速至 min. 停止,收到 E_STOP 命令后立即停止。 速度 E_STOP Set_speed 2 Set_speed 1 RUN=0/SOFT_STOP min. TA1 TA2 TD TD 时间 【加速时间 TA/减速时间 TD】 PTP 控制、SPD 控制的情况下,电机开始动作后,在达到目标速度之前的时间为加速时间 TA,从 目标速度到停止的时间为减速时间 TD。SPD 控制的情况下,即为从当前速度到下一个目标速度的 加速时间、或者减速时间。 【CW、CCW】 表示电机的旋转方向。CW 表示顺时针,CCW 表示逆时针。 CW :clockwise、CCW :counterclockwise 【绝对位置控制方式】 通过距离原点的绝对位置来指定目标位置,并进行控制的方式。 【相对位置控制方式】 通过相对位置来指定从当前位置到目标位置的距离,并进行控制的方式。 -328-
CTMC 运动控制器用户手册 ①将位置指令值指定为+ 5000 ②指定为+ 3000 绝对位置方式 0 3000 5000 ①将位置指令值指定为+ 5000 ②指定为- 2000 相对位置方式 0 3000 5000 【回原】 位置控制中的基准位置称为原点,而移动到该位置的动作称为回原。移动到事先所设定的基准位置 原点,将该坐标作为位置 0。 【减速停止】 使正在运行的动作中断,减速并停止的功能。减速时间为动作过程中的减速时间。 【紧急停止】 使正在运行的动作中断,减速并停止的功能。相较于一般的减速停止,其减速时间设定得更短。可 单独地对减速时间进行设定。 【反馈脉冲输入】 可对编码器发出的反馈脉冲进行计数。 -329-
附录 B CANfree 通信指令库介绍 B.1 功能介绍 CTMC 运动控制器可通过调用 CANfree 通信指令库来进行 CANfree 通信,完成 CANfree 数据收发 和滤波,CANfree 是在 CAN 通信基础协议上完成了一次封装,方便用户更加简单直接地使用,本 节主要介绍该指令库的安装和应用。 B.2 添加库文件 MagicWorks PLC 中添加库 打开 MagicWorks PLC(V2.10 及更高版本),选择“文件”--“添加/删除库”,在弹出的窗口单 击“添加”: 在存放“canlib_free_v1_3.ctmwl”文件的位置选中文件,如下图所示,单击“打开”并确认添加。 安装成功后,在目录树的“库”下可以看到新增加的 canfree_lib(v1.3)。 -330-
CTMC 运动控制器用户手册 MicroWIN 中添加库 打开 STEP 7-MicroWIN,在“文件”--“添加/删除库”,找到库文件“canlib_free_v1_3.mwl”, 如下图所示: 在存放“canlib_free_v1_3.mwl”文件的位置找到文件,如下图所示,单击“添加”按钮。 安装成功后,在目录树的“库”下可以看到新增加的 canfree_lib(v1.3)。 -331-
附录 B.3 库指令说明 CAN 通信指令库共有五条指令,分别是: CANInt(CAN 初始化指令) CANSend(CAN 发送数据指令) CANRcv(CAN 接收数据指令) CANFilter(CAN 数据过滤指令) CanRcvN(接收多帧数据) CAN 初始化 ① 指令名称:CANInt ② 功能:初始化 CAN 自由口; 表 B-1 CAN 初始化指令 库函数 参数名称 输入输 类型 数值 说明 出属性 BOOL 范围 EN BYTE -- IN -- CAN 通道选择 Channel IN BYTE 0-2 0:本地 CAN0 通道 2:CAN 扩展板通道 Baud IN BYTE 0-7 1:本地 CAN1 通道 BYTE 波特率 Mode IN 0-1 0(1MHz);1(800kHz);2 Err OUT 0-4 (500kHz);3(250kHz);4 (125kHz);5(50kHz);6(20kHz); 7(10kHz) 帧格式 0:CAN_A 标准帧 1:CAN_B 扩展帧 错误码,参见表 B-4。0-无错,4- 参数错误 ③ 示例 初始化 CAN 口参数为:CAN 小板通道,250KHz 波特率,帧格式为扩展帧格式 -332-
CTMC 运动控制器用户手册 CAN 发送数据 ① 指令名称:CANSend; ② 功能:CAN 发送数据;启用该指令,Enable 置 1 则发送一次 表 B-2 CAN 发送数据指令 库函数 参数名称 输入输 类型 数值 说明 出属性 BOOL 范围 EN -- IN BYTE -- CAN 通道选择 Channel 0:本地 CAN0 通道 IN Dword 0-2 1:本地 CAN1 通道 FrameID BYTE 2:CAN 扩展板通道 DataLen IN Dword -- 发送数据的帧 ID SendPtr IN BOOL -- 发送数据的帧长度 Enable IN BYTE -- 发送数据缓冲区指针 IN -- 使能位 Sta OUT BYTE 0-1 发送状态(0-未完成,1-完成) 发送完成置 1,自动清 0 Err OUT 0-4 错误码(参见表 B-4) 本地 CAN0/CAN1 通道:0-无错; 1-发送超时;4-参数错误 CAN 扩展板通道:0-无错,2-发 送缓冲区已满 ③ 示例 通过 CAN 扩展板通道发送 8 字节数据,帧 ID 为 2016(通过 SM0.0 调用,通过使能位 Enable 触 发) CAN 接收数据 ① 指令名称:CANRcv; ② 功能:CAN 接收数据;收到数据后会把数据填到接收缓冲区,接收指令是查询接收缓冲区有没 有数据。Enable 置 1 一次,就查一下接收缓冲区。 -333-
附录 表 B-3 CAN 接收数据指令 库函数 参数名称 输入输 类型 数值 说明 出属性 BOOL 范围 EN -- IN BYTE -- CAN 通道选择 Channel 0:本地 CAN0 通道 IN BOOL 0-2 1:本地 CAN1 通道 Enable Dword 2:CAN 扩展板通道 RcvPtr IN Dword -- 使能位 FrameID IN BYTE -- 接收数据缓冲区指针 DataLen OUT BYTE -- 接收到数据的帧 ID OUT 0-1 接收到数据的帧长度 Sta OUT BYTE 接收状态:0-接收未完成 1-接收 0-4 完成 Err OUT 错误码(参见表 B-4) 0-无错;3-接收缓冲区已空 ③ 示例 通过 CAN 扩展板通道接收指针所指存储器中的数据,存放帧 ID 为 2016(通过 SM0.0 调用,通过 使能位 Enable 触发) 表 B-4 Err 错误码定义 错误编码 定义 0 无错误 1 发送超时 2 缓冲区已满(发送) 3 缓冲区已空(接收) 4 参数错误 CAN 接收数据报文过滤 ① 指令名称:CANFilter; ② 功能:CAN 接收数据报文过滤;如果只接收特定帧 ID 的 CAN 报文,可以调用过滤指令。如果 程序不调用过滤指令,默认过滤 ID 和掩码都是 0,即接收任何 CAN 报文。 表 B-5 CAN 数据过滤指令 库函数 输入输 类型 数值 说明 参数名称 范围 出属性 EN IN BOOL -- -- Channel ID CAN 通道选择 IN BYTE 0:本地 CAN0 通道 0-2 1:本地 CAN1 通道 2:CAN 扩展板通道 IN DWORD 要接收的数据报文 ID -334-
CTMC 运动控制器用户手册 MASK 对 ID 进行掩码控制。Mask 为 1 的 bit 位,接收帧 ID 对应的 bit 位必须与指令设置的 ID 对应 bit IN DWORD -- 位匹配,才能通过 CAN 过滤器; Mask 为 0 的 bit 位,接收帧 ID 对应的 bit 位为 0 或 1 都可以通 过 CAN 过滤器。 ③ 示例 通过 CAN 扩展板接收帧 ID 为 0x180xxxxx 的报文 接收多帧数据 ① 指令名称:CanRcvN; ② 功能:读取若干帧 CAN 数据,输出实际数量帧 CAN 数据,顺序存放到缓冲区内存,13 字节偏 移一帧 表 B-6 CAN 接收多帧数据 库函数 参数名称 输入输出 类型 数值 说明 属性 BOOL 范围 EN IN -- BYTE -- CAN 通道选择 Channel IN 0-2 0:本地 CAN0 通道 BYTE 1:本地 CAN1 通道 In_packets IN DWORD -- 2:CAN 扩展板通道 RcvPtr IN 0-1 设定一次接收的帧数 Enable IN_OUT BOOL 0-4 接收数据内存地址 Out_packets OUT BYTE 使能位 OUT BYTE 实际接收到的帧数 Sta 接收状态:0 - 未完成; 1 - OUT BYTE 完成 Err 错误码(0 无错误,3 缓冲区 已空,4 参数错误) CAN 数据结构(共 13 字节) 帧长 len<=8 帧数据 Data 帧 ID 1byte 8bytes 4bytes ③ 示例 通过 CAN0 口一次接收 30 帧数据存储在 VB100 中,将实际的输出帧数存放到缓冲区地址 VB37 中。 -335-
附录 C 以太网“ct_socket”通信库指令介绍 C.1 功能介绍 CTMC 系列 CPU 目前共支持 4 个 socket 连接,UDP 和 TCP 各两个,以太网 socket 通信库提供四 条指令,分别是 SOCK_Open、SOCK_Send、SOCK_Recv、SOCK_Close。 C.2 添加库文件 【添加库文件】 在项目管理器界面或编程界面选择“文件”--“添加/删除库”,在弹出的窗口中单击“添加”浏览 至库文件存储位置: 找到库文件“ct_socket_v1_1.ctmwl”如下图所示,点击“打开”按钮,再点击“确定”。 安装成功后,在程序块界面目录树的“库”下可以看到新增加的“ct_socket(v1.1)”: -336-
CTMC 运动控制器用户手册 C.3 库指令说明 约定项 范围 说明 连接号(SockID) 0~255 0,1 255 为无效连接号 连接类型 (SockType) 1~65535 0为UDP连接,1为TCP客户端连接 端口号 本地端口号要选用不被其他连接占用的端口号,如系统块里默 (Lport/Rport) 认端口号20000为PLC监控连接使用。TCP客户端的本地端口 号由底层分配,Lport可设置为任何值(UDP模式下不能设为 65535),Rport需与服务器端口号一致。 套接字错误码约定: 错误码 说明 0 无错误 1 连接已关闭 2 端口号错误。常用,本地端口号被占用,或端口号超出范围报错 3 设备断线 4 UDP 建立连接失败。常用,创建连接失败,返回连接号 255 5 TCP 客户端连接远方服务端失败 6 TCP 服务端监听失败 7 数据长度错误,最大数据长度为 512 字节 8 数据区为空错误 9 连接号错误 10 接收数据错误(没接收到数据) 11 连接类型错误 12 IP 信息错误 13 超时错误 14 TCP 客户端需要重连标志。常用,TCP 重连 1)SOCK_Open 指令:创建一个 UDP 连接/TCP 连接,创建成功返回正确连接号(0~254),暂 不支持 TCP server,创建失败,返回无效连接号 255。 -337-
附录 参数说明 说明 变量类型 数据类型 备注 参数地址 IN BYTE SockTy 链接类型,UDP(0) IN 不支持 TCP 服务器连接。 和 TCP-CLIENT(1) IN BYTE DestIP0 目标IP地址的第1个 IN 例如目标地址为192.168.1.202,第 字节。 IN BYTE 一个字节为192。 DestIP1 目标IP地址的第2个 例如目标地址为192.168.1.202,第 字节。 BYTE 二个字节为168。 DestIP2 目标IP地址的第3个 例如目标地址为192.168.1.202,第 字节。 BYTE 三个字节为1。 DestIP3 目标IP地址的第4个 例如目标地址为192.168.1.202,第 字节。 WORD 四个字节为202。 Lport WORD TCP-CLIENT模式,LPort由底层随 Rport 本地端口,UDP使用 IN BYTE 机分配 Timeout BOOL 与远程服务器端口号一致。 Enable 目标端口 IN BOOL 单位:100ms。 Done 超时时间 IN BYTE SockID 使能位 I/O BYTE 使能后自动清零。 Error 读写功能完成位 OUT 底层分配,应用要提供一个全局内 存保存连接号。 输出连接号 OUT 错误码。0:无错 错误代码 OUT 2)SOCK_Send 指令:使用指定连接给服务器发送数据。 参数说明 说明 变量类型 数据类型 备注 参数地址 输出连接号 OUT BYTE 底层分配,应用要提供一个全局内 SockID 数据缓冲区 IN 存保存连接号。 DWORD 指向待发送数据的指针,可以指向 SndPtr I、Q、M或V存储器的指针(如 -338-
CTMC 运动控制器用户手册 Len 待发送字节数 IN WORD \&VB100) BYTE 范围为1~512字节。 Timeout 超时时间 IN BOOL 单位:100ms。 BOOL 使能 Enable 使能位 I/O BYTE 使能后自动清零。 错误码。0:无错 Done 读写功能完成位 OUT Error 错误代码 OUT 3)SOCK_Recv 指令:使用指定连接接收数据 参数说明 说明 变量类型 数据类型 备注 参数地址 输出连接号 OUT BYTE 底层分配,应用要提供一个全局内 存保存连接号。 SockID 数据缓冲区 IN DWORD 指向接收数据存储位置的指针,可 以指向I、Q、M或V存储器的指针(如 RcvPtr 超时时间 IN BYTE \&VB100) 使能位 I/O BOOL 单位:100ms。 Timeout 读写功能完成位 OUT BOOL 使能 Enable 实际接收字节数 IN WORD 使能后自动清零。 Done 错误代码 OUT BYTE 范围1~512字节。 错误码。0:无错 Len Error 4)SOCK_Close 指令:关闭指定的连接 参数说明 说明 变量类型 数据类型 备注 参数地址 底层分配,应用要提供一个全局内 输出连接号 OUT BYTE 存保存连接号。 SockID OUT BOOL 使能后自动清零。 关闭完成 OUT BYTE 错误码。0:无错 Done 错误代码 Error 【应用实例】 TCP 客户端掉线重连,通过发送出错标志来确定是否重新打开连接:重连标志 14 -339-
附录 D 以太网设置库指令介绍 D.1 功能介绍 以太网设置指令库 ETHERNET_SET(V1.2)用于设置 PLC 以太网口本地通信参数,无需停止 CPU 即可设置或获取远程以太网 PLC 的 IP 地址、MAC 地址和设备名称。 D.2 添加库文件 以太网设置指令库包含以下四条指令,相关库文件可从合信官网免费下载,网址: http://www.co-trust.com 【添加库文件】 在项目管理器界面或编程界面选择“文件”--“添加/删除库”,如下图所示: 找到“ct_ethernet_set_v1.2.ctmwl”选中并点击“打开”如下图所示,再点击“确定”。 -340-
CTMC 运动控制器用户手册 安装成功后,在程序块界面目录树的“库”下即可以看到“ ETHERNET_SET(V1.2)”: D.3 库指令说明 获取 IP 地址库 ① 库名称:GIP_ADDR ② 功能:获取 IP 地址 库函数 参数名称 输入输 类型 说明 出属性 BOOL EN IN BYTE 使能端,允许 SM0.0 调用 状态字 STATUS OUT DWORD bit0=1 表示获取成功 DWORD bit1=1 表示获取失败 IP_ADDR OUT DWORD 其他位未使用 MASK OUT IP 地址,共四个字节,每个字节由低到高 GATE OUT 分别表示 IP 地址的对应四个数值。 子网掩码,共四个字节,每个字节由低到 高分别表示子网掩码的对应四个数值。 网关,共四个字节,每个字节由低到高分 别表示网关的对应四个数值。 设置 IP 地址库 ① 库名称:SIP_ADDR ② 功能:设置 IP 地址; -341-




