Delphi 5.0的实现方法吧(不用USB通信,主机直接和PLC通信)。VB的没有现成的
2 实现方法
2.1 设计思想
利用Delphi 5.0语言编程,实现上位机与PLC之间的串口通信,定时向PLC发出读数据的命令,PLC响应后,把存放在数据区的数据送入接收缓冲器,然后把数据赋给临时变量,数据经过处理后用于显示。如果采用RS—485串行通信总线标准进行通信,只要使用RS485/RS232接口转换器即可。其通信简图如图1所示:
上位机和Omron C200H PLC的通信接线示意图如图2所示:
2.2 通信协议
上位机通过RS232C串口与主机通信有两种启动方式:一种是由上位机向PLC发送通信请求命令,另一种是由PLC向上位机发送通信请求命令。工业过程监控一般采用第一种启动方式。该方式通信协议如下(以Omron C200H PLC为例):
(1) 上位机—>PLC的命令帧格式:
@ IP2 IP1 ID2 ID1 -CT- F2 F1 * /
其中:@为帧开始标志符;IP2、IP1为PLC的节点标识码,两位十进制数,用来指定与上位机通信的PLC,对应上位机,PLC可在DM6648和DM6653中设置自己的通信节点码;ID2、ID1为两字节命令码;CT为正文内容,用以设置具体的命令参数;F2、F1为两字节的帧校验码FCS,它是从开始符“@”到正文结束的所有字符的ASCII码按位异或的结果;“*”和“/”两字符表示命令结束。
(2) PLC—>上位机的响应帧格式:
@ IP2 IP1 ID2 ID1 E2 E1 -CT- F2 F1 * /
其中:@为帧开始标志符;IP2、IP1为与主机通信的PLC节点标识码;ID2、ID1为两字节命令码;E2、E1为命令结束状态码,如00表示正常结束,01表示RUN模态下无法完成;CT为正文内容,仅在收到读数据命令是生产;F2、F1为两字节的帧校验码FCS,它是从开始符“@”到正文结束的所有字符的ASCII码按位异或的结果;“*”和“/”两字符表示命令结束。
3 ActiveX控件的引入
3.1 引入MSComm控件的意义
在计算机的串行通信中,常用的通信方式有三种:直接读写串口、利用WINDOWS API函数读写串口和利用串口通信控件MSComm操作串口。其中直接读写串口即通过调用_inp()和_outp()函数直接读写串口;利用WINDOWS API函数读写串口即通过调用API函数中的CreateFile()、ReadFile()、WriteFile()等函数操作串口。
使用这两种方法进行编程,既繁琐复杂,又不直观。而通过从Visual Basic中引进Active 控件MSComm,编程者只需通过改变MSComm控件的属性设置和编写相应的初始化程序,就能在Windows环境下简单方便地实现不同用户的串行通信要求。
3.2 引入MSComm控件的方法
(1) 进入Delphi 5.0编程环境下,在菜单项中选中Component/Import ActiveX选项,将出现ActiveX控件导入窗口(如图3);
(2) 在其中选中Microsoft Comm Control 6.0(Version 1.1),并按需要选定Palette pages、unit dir name、Search path值(一般取默认值),最后选择Install按钮进行安装。即可将MSComm 控件引入到Delphi 5.0中。
(3) 在编程使用中,直接打开ActiveX控件,选取TMSComm控件,放在窗体上,右键选取Properties,出现如图4所示的属性窗口,设置其属性即可。其使用方法与Delphi其它控件相同。
3.3 MSComm控件相关属性
MSComm控件有27个属性,其中一部分可缺省设置为不用,常用的属性如下:
(1) CommPort:设置串行口选择。缺省值为1,选择为COM1;若赋值为2,则选择COM2。
(2) PortOpen:设置通信端的状态。设置为True时,打开端口;设置为False时,关闭端口并清除接受和发送缓冲区。
(3) Settings:设置通信时的波特率、奇偶校验、停止位参数。
(4) Inputlen:设置每次从接受缓冲区读却的字符个数。缺省值为0,表示将读取接受缓冲区中全部内容;若设置值为n,表示每次将读取接受缓冲区中的n个字符。
(5) InputMode:设置接收数据的类型。
(6) InBufferCount:设置返回接受缓冲区中等待被读取的字符个数。初始化程序时,InBufferCount设置值为0,表示清除接受缓冲区。
(7) OutBufferCount:设置返回发送缓冲区中等待发送的字符个数。设置值为0时,表示清除发送缓冲区。
(8) InBufferSize:设置接受缓冲区中的长度,缺省值为1024字节。
(9) OutBufferSize:设置发送缓冲区中的长度,缺省值为512字节。
(10) Rthreshold:设置表示在触发OnComm事件之前接收缓冲区允许有的字符数。缺省值为0,表示即使接收缓冲区有字符时,也不会触发OnComm事件;设置值为n时,表示接收缓冲区每有n个字符时,就会触发一次OnComm事件。
(11) Sthreshold:设置表示在触发OnComm事件之前发送缓冲区允许有的字符数。缺省值为0,表示不触发OnComm事件;设置值为n时,表示发送缓冲区每有n个字符时,就会触发一次OnComm事件。
(12) DTREnable:设置DTR的有效性。
(13) RTSEnable:设置RTS的有效性。
(14) Input:从串口读取数据。
(15) Output:向串口写入数据。
4 编程实例
4.1 编程原理
本文采用Delphi5.0语言作为软件开发平台,主要是因为Delphi在图形处理和数据库管理等方面具有较强的功能,且代码编译速度快,控件使用方便。本例将介绍在Delphi的编程环境下,如何实现每隔一段时间(本例是1000ms)从PLCDM0000开始读取两个字节的内容到数据存储区PLCData[40]中。这样假设PLC的节点号为00,那么上位机的命令为:
“@00RD00000001F2F1*/r”
而PLC的应答为:
“@00RD000000D0D1D2D3P2P1*/r”
其中:D0-D3是上位机要读取的数据,F2、F1是PLC的校验码,P2、P1是上位机的校验码,且可以通过给出一个帧数据校验函数来进行校验数据发送和接收是否准确。
4.2 程序实现
(1) 启动Delphi 5.0,生成应用窗体,命名为PLCComm。在窗体上添加通信开始按钮BtnR、通信停止按钮BtnT,并在ActiveX控件栏选中MSComm控件,插入窗体,命名为MSComm1。
(2) 为窗体添加FormCreate事件,进行串口初始化,代码如下:
procedureTForm1.FormCreate(Sender: TObject);
begin
https://www.wendangku.net/doc/b54237455.html,mPort:=1;
//选择COM1(1-COM1,2-COM2)
MSComm1.PortOpen:=True;
//打开端口
MSComm1.Settings:='9600,n,8,1 ';
//设置波特率为9600,无校验,8个数据位,1个停止位
MSComm1.InputLen:=0;
//设置为在读操作时读取接收缓冲区的所有数据
MSComm1.InBufferSize:=1024;
//设置接受缓冲区为1024字节
MSComm1.OutBufferSize:=512;
//设置发送缓冲区为512字节
MSComm1.InBufferCount:=0;
//清除接收缓冲区
MSComm1.OutBufferCount:=0;
//清除发送缓冲区
MSComm1.InputMode:=ComInputModeText;
//置为二进制输入方式
MSComm1.RThreshold:=1;
//设置为接收缓冲区每接收一个字符将引发一次OnComm事件
MSComm1.DTREnable:=True;
//置DTR有效
MSComm1.RTSEnable:=True;
//置RTS有效
end;
也可右键单击MSComm控件,选取Properties,出现如图4所示的属性设置窗口,按上述赋值进行属性设置即可。
(3) 编写帧校验函数:
https://www.wendangku.net/doc/b54237455.html,mFCS(var FData:array of Byte;n:Integer);
var
sum,f1,f2:Byte;
i:Integer;
begin
sum:=0;
f1:=0;
f2:=0;
for i:=0 to n-5 do
begin
sum:=sum xor FData[i];
f1:=sum and $0f; //取sum低四位
f2:=sum and $f0; //取sum高四位
f2:=f2 shl 4;
Fdata[n-3]:=f1;
Fdata[n-4]:=f2;
end;
end;
(4) 为通信开始按钮BtnR添加OnClick事件:
procedure TForm1.Btn_ReceiveClick(Sender: TObject);
begin
if not(MSComm1.PortOpen) then
MSComm1.PortOpen:=True;
//打开串口
MSComm1.InputLen:=0;
//清除接收缓冲区
MSComm1.DTREnable:=True;
MSComm1.RTSEnable:=True;
MSComm1.InputMode:=ComInputModeText;
MSComm1.RThreshold:=1;
MSComm1.Output:='@00RR0001000130*'+chr(13);
end;
(5) 为通信停止按钮BtnT添加OnClick事件:
procedureTForm1.BtnTClick(Sender: TObject);
begin
MSComm1.PortOpen:=False;
MSComm1.DTREnable:=False;
MSComm1.RTSEnable:=False;
end;
(6) 为MSComm控件添加OnComm事件:
procedure TForm1.MSComm1Comm(Sender: TObject);
var
PLCData:string;
begin
if https://www.wendangku.net/doc/b54237455.html,mEvent=2 then
PLCData:=MSComm1.Input;
end;
5 结束语
本通信方案由于采用了ActiveX控件和面向对象的编程方法,因而具有封装性、继承性、多态性等多方面的特性,从而在工业控制的小型监控系统中有着广阔的应用前景。该方案已在河南信阳火电厂输煤系统中得到了应用,实际运行表明,该通信方式简单、稳定,取得了令人满意的效果。