专题介绍:用C语言编写应用层逻辑基本信息一般说来,梯形图特别适合逻辑控制程序的编写,因为支持在线监控和调试,现场修改也比较方便。但是梯形图不太适合写复杂的数学运算,例如通过循坏求平均值,通过迭代进行排序,亦或实现一个复杂的数学公式等。如果用梯形图来实现这些东西,可能需要很多很多的功能块,一方面看上去很不紧凑,另一方面效率也比较低,而且还需要占用很多临时变量来存储中间结果。针对这种情况,我们在KQD Application Editor中加入了C语言的支持。C语言的代码在下载时会直接编译成目标硬件的CPU指令,拥有超高执行的效率。C语言实现的计算可以被梯形图调用,C语言中也可以直接读写PLC的变量。 添加C语言子程序这里举例说明如何在梯形图中添加C代码,在KQD Application Editor的【项目管理】中,右键点击【程序块】,在弹出菜单中选择【插入】子菜单的【Function (SBRx)】命令: 弹出的对话框中,选择插入的单元【SBR_1 (SBR1)】,点击确定: 弹出的对话框中,选择POU类型【NativeC】,点击确定: 即可进入【SBR_1 (SBR1)】的C代码编程界面: C语言中读写PLC变量在C语言中,不能直接使用PLC变量来进行运算,这是因为PLC变量一般使用大端模式(高位字节存储在低地址),而C语言中采用的是CPU的默认模式,一般为小端(低位字节存储在低地址)模式,所以必须通过特殊函数来读写PLC变量。假设我们希望在SBR1中实现PLC变量MW20的自加,需要按照下面的方式来书写: 其中GetU16表示从PLC中获取一个无符号16位整数,第1个参数M表示在PLC的M区域中取,第2个参数表示偏移量为20,返回的结果即为存储在MW20的无符号16位整数值。 我们在主循环中调用此C语言编写的SBR子程序,即可实现PLC变量MW20的自加过程: 全部的PLC变量读函数如下:
全部的PLC变量写函数如下:
参数说明
如果确实需要PLC变量的地址,可以使用PLC变量的外部声明来获取,例如上面的代码可以写成: 全部的PLC变量外部声明如下:
使用数学函数因为最终需要将C代码编译成目标硬件CPU可以执行的指令,支持的数学函数完全依赖于编译器的实现。目前KQD Application Editor自带的编译器有两款:
只需要在C代码的头部包含【math.h】头文件,即可使用编译器提供的数学函数库,如果目标CPU支持硬件浮点,KQD Application Editor会根据目标硬件的CPU开启硬件浮点功能。 带参数的SBR实现公式计算虽然我们可以通过C语言来直接读写PLC变量,但是为了接口更为清晰,一个更好的办法就是利用SBR的输入输出参数来封装算法。这里我我们以PT100的温度计算为例,已知PT100在0°以上的计算公式: Rt1 = R0 * (1 + A * t1 + B * t1 * t1) 其中:
修改SBR1的关联变量如下: 这里我们使用牛顿迭代法获得公式的近似解: 因为这里使用了fabs来求绝对值,所以需要包含数学库math.h。这里通过GetF32函数从临时变量LD0获取输入电阻;完成计算后通过SetF32函数将结果写入LD4输出温度。 在主程序中调用SBR1,下载程序后进行监控,电阻Res输入120,即可得到当前温度51.5661: 定义全局变量或常量可以在SBR中定义全局的变量或常量: 修改SBR1的关联变量如下: 在主程序中调用SBR1,下载程序后进行监控,水泵索引PIndex输入2,即可得到当前水泵的高效流量范围QLow和QHigh: C语言中调用梯形图指令基于FCC的KQD Application Editor编程系统实际上是一个编译型系统,应用逻辑最终都会编译成目标硬件的CPU指令来执行。在FCC系统中,用梯形图编写的SBR,最终也是需要转换成C代码,然后和用C代码编写的SBR一起编译。对于链接程序来说,用梯形图编写的SBR和用C代码编写的SBR是完全等价的。 基于开发板DK60-STM32F412RE的PLC类型,我们在【SBR_0 (SBR0)】中写入以下梯形图: 点击编译,然后在KQD Application Editor的程序目录中,找到【KQDSoftwarePack\1.0.x\User\Functionals\SMX\Temp】目录下的【Fcc_POU_ECxx.c】文件: 我们具体来看第一个网络:
通过观察自动生成的代码可以发现,对于运算类型的代码,例如LD指令,直接带参数调用Fcc_EC40_LD函数即可。对于PLC系统指令,例如Udp_Bind指令,并不是简单的运算,必须由PLC系统来完成,则通过Fcc_ExcuteInstruction函数来实现,不同的PLC系统指令通过指令号来区分。如果是调用PLC系统指令,需要通过一个全局变量Fcc_param来进行参数的交换。 Fcc_param的定义在【Fcc_Priv.h】文件中实现: 这里我们新建一个NativeC的SBR1,将SBR0的自动生成的C代码部分拷贝到SBR1中去,让SBR1完成SBR0同样的功能。我们在SBR1的代码上稍作修改,完成一个简单的变量应答功能,当以太网的UDP的端口收到变量字符串时,通过字符串形式发送变量的值: 将此程序下载到开发板DK60-STM32F412RE,在状态表中设置VW10的值: 打开TCP&UDP测试工具,通过UDP连接到开发板的3002端口,发送字符串【VW10】,则可以看到开发板返回的值【4455】 |