利用串行接口平台进行PLC与计算机通信多是协议通信。以OMRONPLC为例,主要是用HostLink(上位链接)协议,CS、CJ、及CP机还可用FINS协议。其实,不管什么协议,计算机程序只是通信命令的差异,而程序的结构、算法都是一样的。本节主要讨论Host Link协议编程。
1.HostLink协议要点
OMRONHostLink协议适用于所有它的PLC在串行接口平台上与计算机通信。通信由计算机向PLC发送命令,PLC应答,PLC为被动通信。这也是PLC与计算机之间用得最多的通信。在一次发送或应答中所含字符的集合称为帧。规定一个帧最多可含131个字符(节)。
1)帧格式。图7-47所示为计算机命令帧格式,其中每个方格为一个字符。
图7-47 计算机命令帧格式
这里,@为命令开始字符。节点号用BCD码,2位数,可在00~31之间选取,但必须与通信对方设定的节点号一致;命令码使用2个英文大写字母,代码解释见后;数据与命令码有关,数据的地址部分用BCD码,数据的数值部分用十六进制码,用到英文字符要大写;∗及CR(回车符),为结束字符,是命令帧的结束标志。FCS为异或校验,对FCS之前命令帧每个字符的ASCII,按位依次异或,所得的结果值再换成ASCII。此值不足2位数,高位要补0,如用到英文字符也要大写。如下面一帧信息:@10(单元号)RH(命令)00310001(数据)58(FCS)∗CR(结束符)。这里的FCS为58。这58是这么计算出来的:
再转换为ASCII为:00110101(5)00111000(8)。
图7-48所示为PLC响应帧格式。它与命令帧基本相同,所差的只是在数据部分。这里增加了2个字符的返回码,如果命令正确,执行返回码为00,不然将根据命令执行情况返回不同代码,而返回数据则不一定必要。写命令,就没有返回数据;读命令,才有返回数据。
提示:PLC的节点号可使用CX-Programmer编程软件设定。出厂时,PLC默认节点号为00。
2)多帧通信。如果通信交换的字符数超过131个字符,可以进行拆分而用多次通信,使每次都少于131个字符。也可使用多帧通信,如读、写程序,无法拆分。只能用多帧通信。多帧通信分为多帧响应及多帧命令,如图7-49、图7-50所示。
如读很多数据,或读PLC程序,响应就是多帧响应。从图7-49可知,它的首响应帧没有结束“∗”字符。计算机收到这个响应帧后,发应答符(回车符);PLC收到回车应答符后,再发后续数据,即中间帧,这样帧仅仅是数据、FCS及回车符。计算机收到这个响应帧后,再发应答符(回车符);PLC收到回车应答符后,再发后续数据,即中间帧,但如果已是最后数据,那么按结束帧发送。结束响应帧与中间响应帧不同的是有“∗”字符。计算机收到这样的帧就可做别的处理。响应大小由PLC自动生成,前面的帧为128个字符,结束帧为余下的不足128个字符。
如写很多数据,命令就是多帧命令。如图7-50所示就是多帧命令、应答及其结束响应的过程。与图7-49不同的是,它的命令帧大小由人工任意确定,只要不超过128个字符即可。
图7-48 PLC响应帧格式
图7-49 多帧响应
图7-50 多帧命令
3)返回码。表7-11所示为主要的返回码。用好它,可便于通信程序的调试。
4)命令码。命令分为3个等级。等级1能读写PLC数据,若PLC处于监控及编程状态,还可向PLC写数据。等级2可向PLC传送程序,并可读写I/O表。等级3可进行I/O登记及I/O分布情况的读入。
表7-11 返回码及其含义
一般用等级1、2,但使用编程软件要用到等级3。这3个命令等级可在上位链接单元作相应设定予以确定,如不用上位链接单元通信,一般为3级,而且随机型不同,可接收的通信命令也不尽相同。高档及新机型可接收的命令较多。
具体的通信命令可分为以下几类:
(a)测试类:命令码为TS,用于对通信可行性进行测试。其格式为:
@××TS#####……FCS∗CR
这里××为PLC地址,可以是00~31,由对PLC进行设定确定;#####为任意数字或字符;FCS为纵向校验码,两个字符;∗为字符∗;CR为回车。
计算机送这个命令给PLC后,若PLC返回的是同样的代码,则说明通信成功,可行;否则为通信不成功,不能正常进行通信。
这类命令常用于对通信硬件进行测试。
(b)数据读写类:命令码为RX,或WX,这里,X为数据区符号,如DM区为D,保持继电器为H,辅助继电器为J,计数器、定时器(现值)为C,其设定值为#(或$、或%)等。PLC有多少内部器件就有多少相应的符号。
如为读命令,命令码后的数据先是指定读数据区的首地址,占4个字符;其后为要读的数据有多少字,也占4个字符,如读1个字符,为0001。
如为写命令,命令码后的数据是写数据区的首地址,占4个字符;其后为依次向该数据区要写的内容,每个字占4个字符,要写多少字(通道),就有多少“4个字符”。
接着为校验码,即FCS,是两个字;最后为∗及回车符。
例1 @00RH00000002∗CR
例2 @00WH0000 FFFF FFFF∗CR
这里,例1为要从PLC的RH00开始的RH区读2个字的内容。例2为要向PLC的WH区WH00开始的通道,依次写入FFFF,FFFF两个字的内容。
PLC收到这两条命令后,如正确地执行了,其响应将分别为:
@00RH00XXXX XXXX FCS∗CR(对例1)
这里的XXXX XXXX为RH00及RH01通道的数据。FCS为校验码,占两个字符。
@00WH00FCS∗CR(对例2)
这里,WH后的00表示WH命令已正确执行。
应指出的是,数据写命令只能在监控及编程状态下才可能执行。
(c)PLC状态读写:OMRON PLC有3种状态,即编程、监控及运行。这3种状态可由PLC读写,其命令码分别为:MS及SC。
如果为状态读,其响应数据有两个字,各有其含义。而其第一个字的08及09位分别代表PLC的几种工作状态。如08、09位为
00编程
10运行
11监控
如果为写状态,其数据仅一个字节,其1、0位的取值与要写的状态对应如下:
1位0位
00编程
10监控
11运行
(d)强迫置位与复位:其命令码分别为KS、KR。
KS(强迫置位)的格式为:
@××〖单元号〗KS〖置位命令〗××××〖数据区〗××××〖通道号〗××〖位号〗××〖置位值〗FCS∗CR〖结束符〗
KR(强迫复位)的格式为:
@××〖单元号〗KR〖复位命令〗××××〖数据区〗××××〖通道号〗××〖位号〗××FCS∗CR〖结束符〗
这里的数据区是指出强迫置位复位的内部器件名称,如IR区,为CIO加空格;LR区为LR加两个空格;TIM为TIM加空格;TIMH为TIMH等。其对应关系见表7-12。
表7-12 数据对应关系
强迫置位、复位是对该单元的直接赋值,不受程序影响,而数据写,则要受程序影响。强迫置位、复位只能在监控或编程方式下才能被执行。除了单点置位、复位,还有多点置位、复位,其命令码分别为FK、FR。另外,还有强迫置位、复位取消,其命令码为KC,无操作数。
(e)程序读写:其命令码分别为RP(读)、WP(写)。
RP的格式为:
@××〖单元号〗RP〖命令码〗FCS〖校验码〗∗CR〖结束符〗
其响应为:
@××〖单元号〗RP〖命令码〗××〖响应码〗××……〖程序机器码〗FCS〖校验码〗∗CR〖结束符〗
WP的格式为:
@××〖单元号〗WP〖命令码〗××……〖程序机器码〗FCS〖校验码〗∗CR〖结束符〗
其响应为:
@××〖单元号〗WP〖命令码〗××〖响应码〗FCS〖校验码〗∗CR〖结束符〗
PLC的程序什么时候都可以读,但写只能在编程状态下进行。
(f)I/O表读写:其命令码分别为RI(读)、WI(写)。
RI的格式为:
@××〖单元号〗MI〖命令码〗××〖〗FCS∗CR〖结束符〗
其响应为:
@××〖单元号〗MI〖命令码〗××〖响应码〗××……〖数据〗××〖FCS〗∗CR〖结束符〗
WI的格式为:
@××〖单元号〗MI〖命令码〗××……〖数据〗××〖FCS〗∗CR〖结束符〗
其响应为:
@××〖单元号〗MI〖命令码〗××〖响应码〗××……〖数据〗××〖FCS〗∗CR〖结束符〗
这两个命令用于I/O表登记。写只能在编程状态下才能进行。
(g)QQMR(登记)及QQIR(读):
QQMR的格式为:
@××〖单元号〗QQMR〖命令码〗××××〖数据区符号〗×××××〖通道号〗××〖位号〗,〖分割符〗……××〖FCS〗∗CR〖结束符〗
这里的分割符(,)之后还可有另一组数据,且一组之后还可另有一组。若之后没有新组,则不再插分割符,直接继之以FCS及∗CR。
其响应码为:
@××〖单元号〗QQMR〖命令码〗××〖响应码〗××〖FCS〗∗CR〖结束符〗
QQIR的格式为:
@××〖单元号〗QQIR〖命令码〗××〖FCS〗∗CR〖结束符〗
其响应码为:
@××〖单元号〗QQIR〖命令码〗××……〖有关数据〗××〖FCS〗∗CR〖结束符〗
这两条命令要配合使用。登记命令执行后登记的内容将一直保持,直到PLC掉电或再登记入新的内容,故登记之后,只要发简单的QQIR命令,即可成批地按登记的要求读PLC中不同器件的数据,非常方便。但这两条命令属于第三级命令。HostLink单元需设成能执行三级命令时,它才能被执行。
(h)其它命令:还有其它一些通信命令,而且随着技术发展和新机型的出现,还将有新的命令推出,这一点一定要引起使用者注意。
其它命令中常用的有通信取消及通信初始化。它们的命令码分别为XE(取消)、∗∗(初始化)。
XZ命令的格式为:
@××〖单元号〗XZ〖命令码〗XX〖FCS〗∗CR〖结束符〗
∗∗的格式为:
@××〖单元号〗∗∗〖命令码〗XX〖FCS〗∗CR〖结束符〗
这两条命令无响应码,常用于通信失败时进行再起动。
2.计算机编程
VB、VC、Delphi或C++Builder等,都是可视化的编程软件,都可用以编写计算机通信程序。可视化编程可用通信控件编程,也可用Windows的通信API函数编程。
(1)VB6.0编程。VB编程使用通信控件比较方便。如用串行接口平台通信,有微软公司开发的串行接口通信控件(MSComm);如用Control Link网通信,有OMRON公司提供的通信控件。安装好VB、Control Link网络管理软件后,这些控件会自动加入到Windows的动态库中。
在使用这些控件之前,要先把它从VB控件库中调入到VB的工具箱中。
1)MSComm控件及其应用
a)CommPort(通信口)属性。指定用计算机的哪个串行接口进行通信。若用多个串行接口与不同的对象通信,则可多用几个控件。一个控件管理一个通信口。
b)Settings(参数设定)属性:指定串行接口的波特率、奇偶校验及停止位等特性。此设定应与PLC的设定一致。
c)Port Open(打开)属性:设置其为真,打开;否则关闭。进行通信之前,必须先打开。
d)InputMode(读取数据类型)属性:确定Input属性如何取回数据。设为comInputMo-deText(默认),数据将以字符或字符串格式读出。设为comInputModeBinary,数据将以二进制数用数组格式读出。如果数据只用ANSI字符集,则用comInputModeText;否则用comIn-putModeBinary。
e)Input(读取)属性:把输入缓冲区的内容读到指定的字符变量中。读后缓冲区的内容清为零。缓冲区的大小可设,最大可达4k字。
如果接收数据类型设为字符格式,则要先声明一个字符串变量,直接接收数据之后就可以显示它了。如:
如果接收数据类型设为二进制数,读取为数值是不可以视的;要先声明一个字节数组,读取后再转换为字符串才可以显示。如:
f)Output(输出)属性:把输出的命令送输出缓冲区,并且逐字向指定通信对象发送,直到缓冲区空。(www.xing528.com)
发送的数据可以是可视的字符串,也可以是不可视的二进制数。
如果是可视的字符串,要先声明一个字符串变量,并进行赋值。然后发送这个字符串就可以了,即:
声明字符串变量
如果发送的数据类型设为二进制数,因为它是数值,是不可视的,要先声明一个字节数组,再把可视的数值转换为不可视的二进制数,并赋值给所声明的字节数组,然后发送这个字节数组,即
提示:发送、接收使用二进制方式,虽然它的数据不可视,不太方便,但通信效率高。同样的帧长,而收、发的数据可增大一倍。更何况有的协议,如ModbusRTU还必须使用二进制格式通信。
g)RThreshold(接收字符数)属性:设定值为整型数。如果设置为0(默认值),接收缓冲区接收到字符不产生OnComm事件。如果设置为1,每收到一个字符会使MSComm控件产生OnComm事件。其余类推。
h)OnComm()事件属性:这个控件只有这一个事件。只要Comm Event(也是一种属性)的值发生变化,OnComm()事件就会发生。
Comm Event取值与通信口的状况有关,有18个可能的取值。其中10个与通信口的出错(如缓冲区满、通信时间超出……)有关;而7个与通信的进程(如输入或输出缓冲区内容改变……)有关。如什么事件也不发生,则其值为零。
2)通信编程使用的方法:
(a)程序访问方法。它用程序定时或依需要访问事件属性或访问缓冲区计数值(InBuf-flrCount或OutBuffCount)的变化,依其变化情况作相应的通信处理。以下以读PLCDM0000及0001的值为例说明这个编程。
本例使用的窗口为Form1,其上加载的控件有:MSComm1(通信控件,未特别指明其特性用默认值)、Text1(文本控件,用以显示所得到数据)及Command1(按钮控件,用以激发Command1_Click过程,实现通信),如图7-51a所示。
图7-51 程序访问方法显示窗口及控件
程序代码如下(“’”之后为注解):
而FCS函数代码为:
运行本程序,点击“Command1”按钮,如果通信正常,Text1将显示所读数据,如7-51b所示为12345678。如果通信不正常,将弹出图7-51c所示的对话框,显示“通信有误!”
(b)事件驱动方法。所用说明实例及使用控件同上。程序代码如下(“’”之后为注解):
执行本程序效果与上述访问方法相同。只是如果通信不正常,将没有提示;必要时可增加Timer控件予以监视;超出监视时间还没有回应,也可提示出错。
(2)Delphi6.0编程。Delphi是Inprise公司推出的基于对象Pascal语言的可视化集成开发工具。也可使用微软公司提供的MSComm控件,只是在使用前要以“ActiveXControl”的身份加载到它的集成编程平台上,然后把这控件拖放到程序所用的窗口(FORM)中。
图7-52a所示为Delphi6.0通信程序实例的运行窗口。实例除了使用MSComm控件,还有其它标准控件,如图7-52b所示。
从图7-52可知,其上有:6个“Button”(按钮),分别为,open(打开通信口)、关闭通信口(close)、fcs(FCS校验)、send(发送)、receive(接收)及exit(程序退出)的按钮。还有用以键入通信命令的“Edit1”(编辑文本框,用以输入通信命令)、“Edit2”(编辑文本框,用以显示或键入命令原码+校验码+结束码)及一个显示PLC应答数据的“Memo1”(文本框)。微软MSComm控件运行时是看不见的,编辑时对它的属性设定与PLC的串行接口特性一致。
图7-52 Delphi6.0通信程序实例
a)运行窗口 b)所用控件
以下为本程序代码。显示Delphi的“开头”代码是由系统生成的。用浅色字符表示。其余为各个按钮点击后执行的程序代码,由用户编写,并含有简要注解。有6个程序段分别与6个按钮对应。
运行本程序后,只要在“命令原码”处键入“@00RD00000020”通信命令(读DM0000开始的10个字的数据),然后单击“fcs”按钮,再依次单击“open”按钮,“send”按钮、“receive”按钮,如通信正常,将看到如图7-53所示的情况。输入其它命令将有不同显示。要退出系统,先单击“close”按钮,后再单击“exit”按钮即可。
(3)VB.Net编程。VB.Net包装在微软新版本的Visual Studio 2005开发工具中。使VB提升为也可面向对象及多线程编程。在它的.Net Framework 2.0类库中,包含Serial- Port类(用于串行接口通信),类似VB6.0的MSComm控件,但功能却有很大提升,可更方便地用于串行接口通信程序编程。
图7-53 VB.Net开发环境及Form1窗口
图7-53所示为VB.Net的开发环境及建立的一个工程“VB.Net”窗口。
从图7-53可知,在VB.Net窗口上,加载了5个button按钮控件及3个textBox文本控件。前者用于激发执行与通信相关的程序,后者用以键入与显示通信数据。此外,还有串口通信控件SerialPort1。
这5个button1~button5分别用于打开串行接口、关闭串行接口、起动FCS校验码计算、发送通信命令及接收通信数据。textBox1~textBox3分别用于键入通信命令、存储FCS运算结果、显示接收数据。
程序作为Form1类包装在一起,其有关代码及必要注释如下。
图7-54所示为本程序运行画面。这时,如在textBox中键入“@00RD00000020”通信命令(读DM0000开始的10个字的数据),然后单击“button3”按钮,再逐次单击“open”按钮、“button4”按钮、再单击“button5”按钮。如通信正常,将看到如图7-54所示的情况。输入其它命令将有不同显示。要结束通信,可单击“button2”按钮来关闭通信口。要退出系统,可单击窗口右上角的“”键。
(4)C#编程。C#编程语言是微软在微软新版本的VisualStudio2005中,新开发的编程语言。具有VB界面好、开发快及VC程序效率高、运行速度快的双重优点。也是与SUN公司JAVA“PK”的产物。它也自带有通信控件SerialPort,可很方便地用以编程写通信程序。
图7-55所示为C#的开发环境及建立的一个工程“C#”窗口。
图7-54 通信程序运行画面
图7-55 C#开发环境及Form1窗口
从图7-55知,在C#窗口上,与上述VB.Net窗口一样,也加载了5个button按钮控件及3个textBox文本控件。前者用于激发执行与通信相关的程序,后者用以键入与显示通信数据。此外,还有串行接口通信控件SerialPort1。
这5个button1~button5分别用于打开串行接口、关闭串行接口、起动FCS校验码计算、发送通信命令及接收通信数据。textBox1~textBox3分别用于键入通信命令、存储FCS运算结果和显示接收数据。
程序关代码及必要注释如下。
本程序运行与图7-54所示的VB.Net的运行画面相同。如在textBox中键入“@00RD00000020”通信命令(读DM0000开始的10个字的数据),然后单击“button3”按钮,再依次单击“button1”按钮、“button4”按钮、“button5”按钮,要结束通信,也可单击“button2”按钮。要退出系统,可单击窗口右上角的“”键。
(5)VC编程。VC通信程序编程使用API(ApplicationProgramInterface,应用程序接口)函数比较方便。
1)API函数是微软公司在设计Windows操作系统时加进去的。使Windows除了协调应用程序的执行、分配内存、管理系统资等之外,还成了一个应用服务中心,为应用编程提供了很大方便。串行接口通信用API函数主要有:
CreateFile,打开串行接口;
GetCommState,读取串行接口通信参数;
SetCommState,设置串行接口通信参数;
BuilderCommDCB,用字符串中的值来填充设备控制块;
GetCommTimeouts,读取通信超时参数;
SetCommTimeouts,设置通信超时参数;
SetCommMask,设置被监控事件;
WaitCommEvent,等待单个被监控事件发生;
WaitForMultipleObjects,等待多个被监测对象的结果;
WriteFile,发送数据,即写串行接口;
ReadFile,接收数据,即读串行接口;
GetOverlappedResult,返回最后重叠(异步)操作结果;
PurgeComm,清空串行接口缓冲区,退出所有相关操作;
ClearCommError,更新串行接口状态结构体,并清除所有串行接口硬件错误;
CloseHandle,关闭串行接口。
2)串行接口通信程序要点。串行接口通信有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式)。同步操作时,调用的API函数会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而重叠操作方式中API函数会立即返回,在后台进行操作,避免线程的阻塞。无论哪种操作方式,一般都通过4个步骤来完成,即打开串行接口、配置串行接口、读写串行接口及关闭串行接口。
(a)打开串行接口。
用API函数CreateFile来打开或创建。该函数的原型为:
(b)配置串行接口。
在打开串行接口,获得通信设备句柄后,需要对串行接口进行配置。为此,要用到DCB(Device Control Block,设备控制块)结构。DCB结构包含了串行接口通信的各项参数设置,诸如波特率、数据位数、奇偶校验和停止位数等信息。下面仅介绍该结构几个常用的参数:
如果需要修改通信参数,可先修改DCB结构,然后再调用SetCommState函数实现所作的更改。即:
除了上述设置,一般还要设置I/O缓冲区大小和超时值。Windows用I/O缓冲区来暂存串行接口输入和输出的数据,调用SetupComm函数可以设置串行接口的输入和输出缓冲区的大小。即:
在读写串行接口时,需要考虑超时问题。超时的作用是指在指定的时间内没有读取或发送指定数量的字符,读写仍然会结束。
要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个CommTimeouts结构。调用SetCommTimeouts可以用某一个CommTimeouts结构的内容来设置超时。经验证明CommTimeouts结构中各个参数的设置将会影响到通信效率。在保证正确通信的前提下,各个参数的值越小,通信速度越快。
(c)读写串行接口。
可以使用ReadFile和WriteFile读写串行接口,下面是这两个函数:
在使用ReadFile和WriteFile读写串行接口时,既可以同步执行,也可以重叠执行。同步执行时,函数直到操作完成后或设置的超时时间到才返回,这意味着当前线程被阻塞,从而导致效率下降。重叠执行时,即使操作还未完成,这两个函数也会立即返回,费时的I/O操作可以在后台进行。
如果操作成功,这两个函数都返回TRUE。需要注意的是当ReadFile和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果。例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError函数返回ERROR_IO_PENDING,这说明重叠操作还未完成。
(d)关闭串行接口。
利用API函数关闭串行接口非常简单,只需使用CreateFile函数返回的句柄作为参数调用CloseHandle即可:
3)VC串行接口通信编程实例。VC用Api函数编写通信程序上述4要点的代码,当然还得有个装载容器。这容器最简单是用对话框。图7-56所示为对话框。其上有:5个“按钮”,3个“文本框”。按钮分别为:Open Port(打开通信口)、Close Port(关闭通信口)、FCS(FCS校验)、Send(发送)及Re-ceive(接收)。文本框分别为:“命令原码”,用以输入通信命令;“命令原码+校验码及结束码”,用以显示FCS计算后的命令码;“接收字符”,用以显示接收到的字符。
图7-56 通信对话框
程序中5个按钮函数的代码见下:
(a)串行接口建立及打开:
(b)FCS计算:
(c)发送数据:
(d)接收数据:
(e)串口关闭:
运行本程序,在“命令原码”处键入“@00RD00000010”通信命令(读DM0000开始的10个字的数据),然后单击“FCS校验(FCS)”按钮,再单击“打开通信口(Open Port)”按钮,再单击“Send(发送)”按钮,再单击“Receive(接收)”按钮,再单击“Close Port(关闭通信口)”按钮,如通信正常,将看到如图7-56所示的情况。
VC通信程序可处理成多线程的,即在前台处理其它工作的同时另建立一个线程,在后台处理通信(VB只好用中断了),这既提高了工作速度,又可作到程序的其它任务处理与通信两不误。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。