PLC在进行通信时,调用的块上总是有个数据缓存区保存着我们要发送出去的或者接收到的数据,通常我们都是用Byte或者Word的数组。在这里介绍几个小技巧,来避开把数据一个一个的写入到数组里的繁琐代码。
分为三个小问题:建立DB块时应注意的问题;Modbus通信时的缓冲;序列化与反序列化。
一、建立DB块应注意的小问题
如果某个DB块要用作通信的缓冲区,挂在函数块的某个输入上,就一定要去除“优化的块访问”,否则会编译错误。对于初学者,这个问题可能总是会忽略。操作步骤如下。
(1)右击DB块,单击“属性”。
(2)去掉“优化的块访问”的勾选。如图1。
图1. 去掉“优化的块访问”
二、Modbus通信时的缓冲
对于Modbus通信的DATA_PTR参数(Master)或者MB_HOLD_REG参数(Slave)可以直接将整个DB块挂上去,不一定要挂数组型的数据,如图2和图3,注意一定要将DB块去掉优化访问。DB块内可以随意的写任何类型的数据,如图4,不过变量的位置(偏移量)会与他的地址有关。
图2. Modbus RTU主站通信函数块
图3. Modbus RTU从站通信函数块
图4. 用于Modbus缓存的DB块
因此在用PLC通过Modbus协议与变频器、仪表之类的设备通信时,可以建一个DB块,去掉优化访问后,在DB块里按照设备的寄存器通信地址的顺序去创建变量即可。如果中间出现了不关心的变量,不想一个个的创建变量,可以用Word数组代替那部分地址的变量。
对于Modbus TCP的数据缓冲区一样使用。
三、序列化与反序列化
有一些通信模块,比如一些第三方厂家提供的模块的通信函数,其缓冲数据可能只能是Byte数组,不能像上文说的,直接挂DB块。我们可以通过“Serialize”(序列化)和“Deserialize”(反序列化)的指令来实现各个类型的数据和数组的相互转换,比MOVE指令要简便,并且不容易出错。
序列化是指将我们的数据(可能是DB块,也可能是各种类型的变量)按顺序转化为一个个的字节,反序列化是指把字节数组里的字节按照顺序写入我们的数据中。
1.序列化
如图5序列化例程。
图5. 序列化例程1
通过介绍些Serialize块的四个参数来介绍功能。SRC_VARIABLE是要序列化的变量,可以是一个DB块(是否去掉“优化的块访问”都可以),也可以是任意类型的变量。本例程的”DB_Recipe”.aa的内容如图4。DEST_ARRAY是储存结果的数据变量,为BYTE数组。POS是一个InOut型参数,不可以写入常数,其代表的意思用本例程来介绍,如图5给POS初始化为10,”DB_Recipe”.aa的数据将从buf的偏移量10的位置(不是索引号10)开始写入,函数运行完后,POS的值将会增加,增加量为写入的字节数,比如例程的”DB_Recipe”.aa占用14个字节,POS的值会变为10+14=24。Ret_Val是错误信息。
我们还可以将多个数据非常方便的序列化到一个数组里。例程如图6。本例程还是从偏移量10开始写入,将”DB_Recipe”.aa和”DB_Recipe”.bb都进行序列化。本例程序列化的结果为,”DB_Recipe”.aa的数据(14个字节)在buf的10
到23的位置,”DB_Recipe”.bb的数据(14个字节)在buf24到37的位置,POS的值为38。
图6. 序列化例程2
2.反序列化
例程如图7。SRC_ARRAY为存有数据流的Byte数组,DEST_VARIABLE为我们实际需要的数据,可以是DB块也可以是任意类型的变量。POS与Ret_Val不做过多介绍。
反序列化也可以像“序列化例程2”一样的结构进行使用。
图7. 反序列化例程
因篇幅问题不能全部显示,请点此查看更多更全内容