Delphi与仪表之间的MODBUS通讯.docx

上传人:b****2 文档编号:11707802 上传时间:2023-06-02 格式:DOCX 页数:9 大小:18.18KB
下载 相关 举报
Delphi与仪表之间的MODBUS通讯.docx_第1页
第1页 / 共9页
Delphi与仪表之间的MODBUS通讯.docx_第2页
第2页 / 共9页
Delphi与仪表之间的MODBUS通讯.docx_第3页
第3页 / 共9页
Delphi与仪表之间的MODBUS通讯.docx_第4页
第4页 / 共9页
Delphi与仪表之间的MODBUS通讯.docx_第5页
第5页 / 共9页
Delphi与仪表之间的MODBUS通讯.docx_第6页
第6页 / 共9页
Delphi与仪表之间的MODBUS通讯.docx_第7页
第7页 / 共9页
Delphi与仪表之间的MODBUS通讯.docx_第8页
第8页 / 共9页
Delphi与仪表之间的MODBUS通讯.docx_第9页
第9页 / 共9页
亲,该文档总共9页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Delphi与仪表之间的MODBUS通讯.docx

《Delphi与仪表之间的MODBUS通讯.docx》由会员分享,可在线阅读,更多相关《Delphi与仪表之间的MODBUS通讯.docx(9页珍藏版)》请在冰点文库上搜索。

Delphi与仪表之间的MODBUS通讯.docx

Delphi与仪表之间的MODBUS通讯

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通讯,给出的代码也是具有代表性的一部分。

难点主要有以下几点:

第一,延时和多线程,为的是让串口来得及处理所有的操作;第二,校验,为的是扔掉乱码;第三,通讯,为的是监视数据和修改数据。

下面是上位机与一台仪表进行通讯的代码示例,与多台仪表进行通讯的代码也是如此。

  procedureTfrmMain.

  Comm1ReceiveData(Sender:

TObject;Buffer:

Pointer;

  BufferLength:

Word);

  {接收数据}

  var

  rBuff:

array[1..3]ofbyte;

  begin

  move(buffer^,rBuff,BufferLength);

  EdtAdr.Text:

=inttohex(rBuff[1],2);//VSD仪表地址

  ifinttohex(rBuff[2],2)='00'then//状态1

  ImgLR1.Caption:

='远控'

  else

  begin

  ifinttohex(rBuff[2],2)='01'then

  ImgLR1.Caption:

='手动'

  else

  ifinttohex(rBuff[2],2)='02'then

  ImgLR1.Caption:

='自动';

  end;

  ifinttohex(rBuff[3],2)='00'then//状态2

  ImgLR2.Caption:

='停止'

  else

  begin

  ifinttohex(rBuff[3],2)='01'then

  ImgLR2.Caption:

='运行'

  else

  begin

  ifinttohex(rBuff[3],2)='02'then

  ImgLR2.Caption:

='整定'

  else

  ifinttohex(rBuff[3],2)='03'then

  ImgLR2.Caption:

='去皮';

  end;

  end;

  end;

  procedureTfrmMain.Timer1Timer(Sender:

TObject);

  {在本程序段中时时处理创建线程和释放线程,由此来完成仪表的读写数据功能}

  var

  mm:

MyRead;

  begin

  try

  mm:

=MyRead.Create(False);//创建线程

  ifmmnilthen

  mm.FreeOnTerminate:

=True;//释放线程

  ifEdtMaName1.Visible=Truethen

  begin

  if((ImgRun1.Visible=True)And(mRunOrStop[1]=True))

  Or((ImgStop1.Visible=True)And(mRunOrStop[1]=False))then

  mDoRun[1]:

=False;

  ifStrToFloat(EdtOutSet1.Text)=StrToFloat(EdtInnerSet1.Text)then

  mDoWrite[1]:

=False;

  end;

  except;

  end;

  end;

  procedureMyRead.Execute;

  {线程执行过程}

  var

  Buf:

array[1..13]ofbyte;

  hb,LB:

Byte;

  crc:

Word;

  i,j,m:

Integer;

  begin

  WithfrmMaindo

  begin

  ifBtnIsUse1.Caption=’是’then

  {发送读命令}

  begin

  buf[1]:

=$01;//设备地址

  buf[2]:

=$04;//功能码

  buf[3]:

=$00;

  buf[4]:

=$62;//起始地址

  buf[5]:

=$00;

  buf[6]:

=$0E;

  {以下为crc校验}

  crc:

=$FFFF;

  forj:

=1to6do

  begin

  crc:

=crcxorbuf[j];

  fori:

=0to7do

  begin

  m:

=crcand$01;

  crc:

=crcshr1;

  ifm=1thencrc:

=crcxor$a001;

  end;

  end;

  hb:

=crcShr8;

  crc:

=crcShl8;

  LB:

=crcShr8;

  buf[7]:

=Byte(LB);

  buf[8]:

=Byte(hb);

  buf[9]:

=$00;

  buf[10]:

=$00;

  buf[11]:

=$00;

  buf[12]:

=$00;

  buf[13]:

=$00;

  comm1.writeCommData(@buf,13);//发送数据

  sleep(200);//延时200ms

  end;

  ifBtnIsUse1.Caption=’是’then

  {发送写命令}

  begin

  ifmDoRun[1]=Truethen

  begin

  buf[1]:

=$02;//设备地址

  buf[2]:

=$05;//功能码

  buf[3]:

=$00;

  buf[4]:

=$32;//起始地址

  buf[5]:

=$FF;

  buf[6]:

=$00;//启动

  {以下为crc校验}

  crc:

=$FFFF;

  forj:

=1to6do

  begin

  crc:

=crcxorbuf[j];

  fori:

=0to7do

  begin

  m:

=crcand$01;

  crc:

=crcshr1;

  ifm=1thencrc:

=crcxor$a001;

  end;

  end;

  hb:

=crcShr8;

  crc:

=crcShl8;

  lb:

=crcShr8;

  buf[7]:

=Byte(lb);

  buf[8]:

=Byte(hb);

  buf[9]:

=$00;

  buf[10]:

=$00;

  buf[11]:

=$00;

  buf[12]:

=$00;

  buf[13]:

=$00;

  comm1.writeCommData(@buf,13);

  sleep(200);//延时200ms

  end;

  end;

  end;

  end;

  线程:

或许细心的朋友会问:

“为什么要创建多线程呢?

”直接在时钟内实现发送读、写命令不行吗?

如果是一台仪表通讯的话,我告诉你用单线程绝对没问题,但如果是多台仪表通讯的话,那就不一定了。

试问有多台仪表需要读写时,对每台仪表进行读写时都要延时,那么会出现什么问题呢?

那就是单线程来不及处理,导致程序反应缓慢,要解决这个问题的好办法之一也就是用多线程了。

以上是具体的代码实现,主要的功能就是让多台仪表同时准确地进行读写数据。

  四、总结

  现在已经是信息时代了,通讯在这个时代显得尤为重要,可以毫不夸张地说通信无所不在,今天所讲述的MODBUS通讯也是其中的一种而已,但是学会MODBUS通讯这件事情说大不大说小不小,因为虽然说它只是那么多通讯协议中的一种而已,但是它对于今后遇到的各类支持MODBUS通讯协议的仪表有很大的借鉴作用,所以我觉得教会大家这件事情是很有必要且很有意义的。

  

  作者简介:

庞一凡,高校教师,从事软件开发工作25年,多年从事职业学校一线教育,擅长于数据库及工业控制方面的软件开发。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2