TwinCat结构化文本的一些编程技巧
编程中常用到的函数和技巧(大部分为倍福控制器编程语言所使用到的)
1.利用计时器制作一个周期输出信号。
tnGetTime(IN:= NOT tnGetTime.Q , PT:= T#500MS, Q=> , ET=> ); // 0.5s 刷新一次当前时间
原理: 将计时器的输出取反 ,赋值给计时器的输入引脚 。
以此来达到一个循环。
2.TC3 获取系统时间功能块 : ‘Tc2_Utilities.NT_GetTime’ 。
下面展示功能块 NT_GetTime
。
Is_Get_Time(
NETID:= , // 默认为本地网络id , 如果获取目标控制器中的时间则需要更改
START:= tnGetTime.Q, // Bool量
TMOUT:= T#3S, // 3s 没扫描即报警 ,周期可更改。
BUSY=> , // 正在获取时间的标志
ERR=> , // 报错
ERRID=> , // 错误代码 可以在HELP中找到相关信息
TIMESTR=> ); // 结构体 包含年月日周等信息
3.功能块和函数块的用法的区别
(暂定这种说法后期认识了再回来改)
功能块可直接调用其输出进行使用 。例如 TON.Q 等等 。
函数块则不同,一般函数块里包含很多算法实现不同的功能,例:
上图为配方函数块的一些功能。
这个设置配方路径的功能从它的功能图块中可以看出,它的输出为一个返回值,可以理解为这个块是一个算法语句,而SetStoragePath为算法的结果。 所以一般的在程序中可以这么使用。
下面展示一些 使用例程
。
RecipeManCommands.SetStoragePath(stPath:=sPath); // 设置文件的保存路径
IF RecipeManCommands.SetStoragePath(stPath:=sPath) THEN
Ob_SetStoragePath := TRUE ; // 保存路径设置成功
ELSE
Ob_SetStoragePath := FALSE ; // 保存路径设置失败
END_IF
4.TC3中配方管理的一些使用技巧。
在配方管理中常用到的功能一般有以下两个:
VAR
Is_Save_Name : STRING ; // 保存配方的名称
Is_Load_Name : STRING ; // 载入配方的名称
Is_Definition_Name :STRING ; // 配方定义的名称
END_VAR
//读取保存指令
RecipeManCommands.CreateRecipe(RecipeDefinitionName:=Is_Definition_Name , RecipeName := Is_Save_Name ); // 类似句柄的作用
RecipeManCommands.ReadAndSaveRecipe(RecipeDefinitionName:=Is_Definition_Name , RecipeName := Is_Save_Name ); // 保存配方,同名将被覆盖
//加载写入指令
RecipeManCommands.ReloadRecipes(RecipeDefinitionName:=Is_Definition_Name ); // 类似句柄的作用
RecipeManCommands.LoadAndWriteRecipe(RecipeDefinitionName:=Is_Definition_Name , RecipeName:= Is_Load_Name ); // 加载制定名称文件
读取保存和加载写入的上一条指令的作用类似于句柄。不加上可能会出现一些奇奇怪怪的错误。
5.如何将现场的I/O点位于程序中的变量一一对应。
首先声明一个BYTE类型的变量。最好是以结构体的方式声明。这样后期调试时会更加清晰(在程序中映射时可以直观的看到哪个BYTE是你所需要用到的)。
然后在扫描出来的I/O或者轴上做相应的映射,这样的在你的程序中的这个BYTE就与实际的信号关联上了。
下图为映射的语法:
I/O板卡的映射语法:
变量名:AT%( I* 输入类型/ O*输出类型) : 变量类型 ;
轴的映射语法:
变量名:轴类型;
6.通过代码读取硬件设备信息(此处只限倍福设备)
读取硬件设备的信息需要用到功能块FB_MDP_ReadElement,此功能块在Tc2_MDP库中
以获取CPU温度为例:
VAR
// *****获取温度
Get_Temperature : Tc2_MDP.FB_MDP_ReadElement ;
CPU_Temperature_Index:ST_MDP_Addr; // cpu 温度的索引
END_VAR
// **************获取cpu温度
CPU_Temperature_Index.nArea :=8;
CPU_Temperature_Index.nTableId :=1;
CPU_Temperature_Index.nSubIdx :=03;
Get_Temperature(
bExecute:= tnCircle.Q ,
stMDP_Addr:= CPU_Temperature_Index,
eModuleType:=16#B ,
iModIdx:= 0,
pDstBuf:= ADR(Hardware_Info_Result.CPU_Temperature ),
cbDstBufLen:= SIZEOF(Hardware_Info_Result.CPU_Temperature ),
tTimeout:= ,
sAmsNetId:= ,
bBusy=> ,
bError=> ,
nErrID=> ,
nCount=> ,
stMDP_DynAddr=> ,
iModuleTypeCount=> ,
iModuleCount=> );
这个ST_MDP_Addr结构体中包含了索引的所有信息:
CPU_Temperature_Index.nArea :=8;
CPU_Temperature_Index.nTableId :=1;
CPU_Temperature_Index.nSubIdx :=03;
nArea:为获取IPC不同Area区域的值,如下图(读取CPU温度,CPU温度属于ConfigArea中,所以nArea :=8):
nTableId:可以理解为nArea的下一级索引 ,如图标红处:
nSubIdx: 为上图中表格的索引号 。
eModuleType: 为你所需要获取的信息硬件设备ID在这里可以找到值
iModIdx:如果设备存在多个,那么第一个为0,第二个为1,以此类推。
倍福将所有能获取的硬件信息放在了一个大的“内存区”里,这些端口的值可将其理解为一个索引,通过改变索引的信息可以直接得到我们需要的信息。
7.通过Fb_Fileopen等程序写入文件并且保存时,增加换行符。
只需要在写入数据的后面加上“$ L”或者“$n”即可。
8. 关于函数块 WSTRING_TO_UTF8的使用时需要注意到一些细节。
// 变量声明区
IDATA :wstring; // 输入的宽字符串
ODATA :string; // 转换后的字符串
a : bool ; //
// 代码区
a := WSTRING_TO_UTF8 (pDstUTF8 :=ADR(IDATA ),pSrcWSTRING := ADR(ODATA ),nDstSize :=SIZEOF(ODATA ));
①此函数块的功能是将wstring类型的字符串转换成UTF-8格式的字符串。所以输入的字符串的类型为 wstring。
②需要注意的是 函数的pDstUTF8的这个引脚,是转换后的字符串的指针。在使用此功能块时我们可以声明一个变量,然后通过ADR取地址后来对接引脚。
9. 关于函数块 FileOpen等一系列的函数块使用时需要注意到一些细节。
Fb_Fileopen 隶属于Files Function Blocks中的一员。
Files Function Blocks 可以实现对文件和或者表格的读写操作。
①在我们写数据到文件或者需要读取文件内容时 ,首先需要打开文件,所以文件的读取和写入的第一步必然是打开文件即 Fb_Fileopen。
②Fb_Fileopen 使用时需要注意文件的打开方式,不同的打开方式有不同的功能,不然的话实现不了我们想要的效果,可以通过倍福的帮助文档来查看有哪些打开模式。 Fb_Fileopen会返回一个句柄,这是后面写入和读取函数块所需要的。
③Fb_FileClose文件打开操作完成后需要关闭文件,此操作和Fb_Fileopen是配套使用的,如果不关闭,会造成文件删除不了的情况。
④Fb_FileWrite需要注意其中两个引脚pWriteBuff和cbWriteLen。pWriteBuff为指针变量 ,故使用时需要ADR变量取地址。
cbWriteLen为字符串的长度。此时我们要注意
LEN是取字符串的长度
Sizeof则取的是变量类型所需的字节数
所以我们声明的数据类型为string的变量,len和sizeof的结果是不同的。在此处需要要使用Len。
编程规范:
1.在一定的命名规则下进行编程可以使编写的程序可读性变得更高,令他人能更快的看懂程序。
如图: