admin 管理员组文章数量: 1086019
2024年3月12日发(作者:模块建房知识)
Delphi与仪表之间的MODBUS通讯
【摘 要】在工控领域,经常会遇到各式各样的现场仪表,这些仪表分散在现场的各
个位置,这样的话对管理人员和现场操作人员来说都非常不方便,那如何解决这个问题呢?
此时就会用到一种方案,那就是配置上位机,用来集中控制这些仪表,这就是所谓的集散
系统。那么如何通过上位机与现场仪表通讯来获取仪表的数据,同时又能对仪表进行远程
操作呢?这也就是今天要论述的课题。在进行通信程序编写之前,我们首先得对现场仪表
有一定的了解,最起码地是应该知道现场仪表支持什么通讯协议,需要设置哪些参数,然
后才能展开下一步的工作。
【关键词】Delphi;ModBus;集散系统;多线程
一、MODBUS通讯协议
MODBUS是由莫迪康(现为施耐德公司的一个品牌)在1979年发明的,是全球第一个
真正用于工业现场的总线协议。MODBUS协议是应用于电子控制器上的一种通用语言,
通过它,控制器之间或其他设备之间可以通信,它已经成为一通用工业标准。有了它,不
同厂商生产的控制设备可以连成工业网络,进行集中监控。它定义了一个控制器能认识使
用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请求访问其它
设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域
格局和内容的公共格式。当在一Modbus网络上通信时,此协议决定了每个控制器须要知
道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制
器将生成反馈信息并用Modbus协议发出。在其它网络上,包含了Modbus协议的消息转
换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由
路径及错误检测的方法。
二、VSD-6仪表简介
VSD-6仪表是某厂家自己制作的一款仪表,它具有一个标准的MODBUS端口(二线制
的RS485接囗),在一条RS485总线上可接入接出1至16台VSD-6控制仪表,可方便地
同各种组态软件(如:组态王、WINCC、昆仑通态)直接连接通讯,也可以按照标准
MODBUS(RTU)通讯协议自编程。此处需要注意的是MODBUS通讯协议还分RTU协议和
ASCII协议,VSD-6仪表支持的是MODBUS(RTU)通讯协议,若理解错了将导致无法与
VSD-6仪表正常连接通讯。关于该仪表的通讯参数主要有:Adr-仪表通讯地址、Com-通
讯串口号、Baud-通讯波特率,当要通讯之前首先得设置好通讯串口号和通讯波特率,这
个对于每台仪表来讲是一样对待的,而通讯地址就是惟一用来区分仪表的参数,每台仪表
应该设置不同的通讯地址,否则将造成程序无法判断是哪台仪表。
三、上位机与仪表通讯
上位机与VSD-6仪表通讯有很多种方法,最简单地做法是通过组态软件,但是通过组
态软件在工业控制方面,由于速度的要求,达不到用户的要求,所以我们用Delphi自身的
SpComm控件来实现Delphi与VSD-6的仪表通讯。今天就着重讲述下自己编程来实现
MODBUS通讯。
本系统采用的上位机编程软件是Delphi,首先我们需要安装支持Delphi的通信组件
SpComm,具体的安装方法网上有很多介绍,此处就不再讲述了,下面进入正题。
1、首先要根据VSD-6仪表的通讯协议在Delphi程序中设置通信口参数。如:波特
率9600,偶校验,一位起始位、八位数据位、一位停止位,数据都为8位二进制(RTU)码。
2、编写通讯程序。
本程序主要要实现的功能是监视到VSD-6仪表的一些数据,如:仪表的当前状态、流
量、设定量和皮重等,同时当VSD-6仪表打到远程控制状态时,可以在上位机上对VSD-6
仪表进行远程操作。对于本通讯程序来讲,主要是如何来做MODBUS通讯,给出的代码
也是具有代表性的一部分。难点主要有以下几点:第一,延时和多线程,为的是让串口来
得及处理所有的操作;第二,校验,为的是扔掉乱码;第三,通讯,为的是监视数据和修
改数据。下面是上位机与一台仪表进行通讯的代码示例,与多台仪表进行通讯的代码也是
如此。
procedure TfrmMain.
Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
{接收数据}
var
rBuff:array[1..3] of byte;
begin
move(buffer^,rBuff,BufferLength);
:=inttohex(rBuff[1],2); //VSD仪表地址
if inttohex(rBuff[2],2)='00' then //状态1
n:='远控'
else
begin
if inttohex(rBuff[2],2)='01' then
n:='手动'
else
if inttohex(rBuff[2],2)='02' then
n:='自动';
end;
if inttohex(rBuff[3],2)='00' then //状态2
n:='停止'
else
begin
if inttohex(rBuff[3],2)='01' then
n:='运行'
else
begin
if inttohex(rBuff[3],2)='02' then
n:='整定'
else
if inttohex(rBuff[3],2)='03' then
n:='去皮';
end;
end;
end;
procedure 1Timer(Sender: TObject);
{在本程序段中时时处理创建线程和释放线程,由此来完成仪表的读写数据功能}
var
mm:MyRead;
begin
try
mm:=(False); //创建线程
if mmnil then
Terminate:=True; //释放线程
if e=True then
begin
if ((e=True) And(mRunOrStop[1]=True))
Or((e=True) And(mRunOrStop[1]=False)) then
mDoRun[1]:=False;
if StrToFloat()=StrToFloat() then
mDoWrite[1]:=False;
end;
except;
end;
end;
procedure e;
{线程执行过程}
var
Buf:array[1..13] of byte;
hb,LB:Byte;
crc:Word;
i,j,m:Integer;
begin
With frmMain do
begin
if n=’是’
{发送读命令}
begin
buf[1]:=$01; //设备地址
buf[2]:=$04; //功能码
buf[3]:=$00;
buf[4]:=$62; //起始地址
buf[5]:=$00;
then
buf[6]:=$0E;
{以下为crc校验}
crc:=$FFFF;
for j:=1 to 6 do
begin
crc:=crc xor buf[j];
for i:=0 to 7 do
begin
m:=crc and $01;
crc:=crc shr 1;
if m=1 then crc:=crc xor $a001;
end;
end;
hb:=crc Shr 8;
crc:=crc Shl 8;
LB:=crc Shr 8;
buf[7]:=Byte(LB);
buf[8]:=Byte(hb);
buf[9]:=$00;
buf[10]:=$00;
buf[11]:=$00;
buf[12]:=$00;
buf[13]:=$00;
ommData(@buf,13); //发送数据
sleep(200); //延时200ms
end;
if n=’是’ then
{发送写命令}
begin
if mDoRun[1]=True then
begin
buf[1]:=$02; //设备地址
buf[2]:=$05; //功能码
buf[3]:=$00;
buf[4]:=$32; //起始地址
buf[5]:=$FF;
buf[6]:=$00; //启动
{以下为crc校验}
crc:=$FFFF;
for j:=1 to 6 do
begin
crc:=crc xor buf[j];
for i:=0 to 7 do
begin
m:=crc and $01;
crc:=crc shr 1;
if m=1 then crc:=crc xor $a001;
end;
end;
hb:=crc Shr 8;
crc:=crc Shl 8;
lb:=crc Shr 8;
buf[7]:=Byte(lb);
buf[8]:=Byte(hb);
buf[9]:=$00;
buf[10]:=$00;
buf[11]:=$00;
buf[12]:=$00;
buf[13]:=$00;
ommData(@buf,13);
sleep(200); //延时200ms
end;
end;
end;
end;
线程:或许细心的朋友会问:“为什么要创建多线程呢?”直接在时钟内实现发送读、
写命令不行吗?如果是一台仪表通讯的话,我告诉你用单线程绝对没问题,但如果是多台
仪表通讯的话,那就不一定了。试问有多台仪表需要读写时,对每台仪表进行读写时都要
延时,那么会出现什么问题呢?那就是单线程来不及处理,导致程序反应缓慢,要解决这
个问题的好办法之一也就是用多线程了。以上是具体的代码实现,主要的功能就是让多台
仪表同时准确地进行读写数据。
四、总结
现在已经是信息时代了,通讯在这个时代显得尤为重要,可以毫不夸张地说通信无所
不在,今天所讲述的MODBUS通讯也是其中的一种而已,但是学会MODBUS通讯这件
事情说大不大说小不小,因为虽然说它只是那么多通讯协议中的一种而已,但是它对于今
后遇到的各类支持MODBUS通讯协议的仪表有很大的借鉴作用,所以我觉得教会大家这
件事情是很有必要且很有意义的。
作者简介:庞一凡,高校教师,从事软件开发工作25年,多年从事职业学校一线教
育,擅长于数据库及工业控制方面的软件开发。
版权声明:本文标题:Delphi与仪表之间的MODBUS通讯 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1710178472a561094.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论