安控数字化油田擂台-RTU/PLC串口自定义编程-第47期(已结束) 点击:1328 | 回复:11



安控数字化

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:52帖 | 120回
  • 年度积分:1
  • 历史总积分:2471
  • 注册:2011年3月01日
发表于:2012-11-11 20:18:06
楼主

讨论主题:
在数字化油田建设中,不同的工艺采用不同的设备,近几年来越来越多的设备往智能化方向发展,一般采用RS485通信接口,但各厂家没有统一的通信协议、统一的通信物理参数,这样对实施数字化项目的工程师来讲,想要读取相应设备的数据必须自己编程,采用自定义通信协议来获取仪表数据,请谈谈RTU/PLC串口自定义编程相关的内容?

 参与方式:采取跟帖的方式参与。

 
评奖规则:由活动组织者评奖,并进行公开公布告示。

 
活动结贴:每周为1期,由安控数字化论坛擂台版主选定议题,半个月后(隔一期)擂台版主从所有参与讨论的网友中选出6个优胜者。

奖项设置:每期选出6个优胜者,其中:

 一等奖1名:奖100MP(相当于100人民币),
      
二等奖5名,奖工控精美礼物一个(工控点点、工控T恤、工控徽章、工控工具四者任选一个,相当于65人民币)。 优先考虑参与次数少于3次的ID

 活动发奖:MP评奖后一周内发放,精美礼物每月发放一次,统一在月初寄送。

北京安控科技股份有限公司

地址:北京市海淀区上地四街一号

邮编:100085

电话:400-0093-200 市场部

传真:010-62971668-6888

网址:www.echocontrol.com

E-mailyqshichang@echocontrol.com

 

           北京安控科技股份有限公司(简称安控科技),是专业从事工业级RTU(远程控制终端)产品研发、生产、销售和系统集成业务的高新技术企业,拥有完善的RTU产品链,产品被广泛应用于石油天然气、煤层气、页岩气的开采、处理、管输、储配等各个环节以及环境在线监测、城市燃气、供水供热等管网监控领域,并已远销美国、加拿大、墨西哥、土耳其、哈萨克斯坦、土库曼斯坦、伊拉克、伊朗、韩国、泰国、马来西亚等国家。基于RTU技术,安控科技在油气、环境在线监测等行业开发出多款专业化经典产品,拥有完善的油气田自动化和环保在线监测专用产品。此外,安控科技还提供工业自动化产品的OEM/ODM服务,提供SCADA自动化系统和企业管理信息系统的集成服务。

安控科技通过了ISO9001质量管理体系和ISO14001环境管理体系认证,建立了先进的生产和检测平台,并获得了多项国际认证(如UL 、CE、EMC3级认证等),产品品质达到国际先进水平。

 

安控科技成立于1998年,位于北京市中关村科技园区海淀园上地信息产业基地。安控科技始终坚持以人为本的人力资源发展战略,建立了一支以高级工程师和专业研究生为骨干的研发团队,打造了一支经过市场历练的高效经营团队,锻炼和培养了一支优秀的管理团队。安控科技始终坚持自主创新的企业发展战略,已经拥有了商标、专利、软件著作权等各类知识产权百余项,覆盖了所提供的所有自动化产品和控制系统。安控科技的研发项目多次获得国家、北京市政府的研发资金支持,部分产品被认定为国家级火炬计划项目、国家重点新产品项目、科技部创新基金项目、商务部出口研发资金项目,受到政府嘉奖与资助。

作为中国自动化学会理事单位、中国自动化学会专家咨询工作委员会常务理事单位、中国自动化学会仪表与装置专业委员会委员单位、北京市中关村企业信用促进会的第一批信用企业,安控科技在国内同行业中较早的通过ISO9001质量管理体系认证,拥有系统集成、建筑施工、环保设施运营等各类资质。

本着卓越品质,源于更高要求的核心理念,协作、严谨、勤奋、卓越的企业精神,安控人必将以更可靠的工业级RTU产品、更先进的自动化解决方案和更完善的服务答谢用户、回报社会,为振兴民族自动化事业、创建民族自动化品牌而努力奋斗。

 

 

北京安控科技股份有限公司

地址:北京市海淀区上地四街一号

邮编:100085

电话:400-0093-200 市场部

传真:010-62971668-6888

网址:www.echocontrol.com

E-mailyqshichang@echocontrol.com




中国555

  • 精华:0帖
  • 求助:0帖
  • 帖子:3帖 | 861回
  • 年度积分:0
  • 历史总积分:7826
  • 注册:2009年3月08日
发表于:2012-11-12 08:49:38
1楼

modbus rtu通信协议串口通讯动态链接库DLL(以下简称DLL),是为满足工业通信需要,
针对工业领域要求上位机对PLC、工业仪表通讯实时采集与控制的组态编程而设计。
本DLL是采用Delphi语言开发的标准串口通讯库,具有以下特点:
1)、遵循modbus rtu串口通讯协议(施耐德、西门子、台达、永宏等品牌PLC及各类工业仪表等支持本协议);
2)、实时性、可靠性好,通用性强;
3)、适用于多PLC联网和上位机通信,满足多方面的需要(联网时可采用485总线式);
4)、函数接口功能全,操作简单,支持modbus的大部分读写功能函数;
5)、附加实用转换与读取函数,易于快速开发(VC等非RAD开发环境的开发);
6)、支持USB、PC扩展卡等扩展串口号;
7)、支持多种操作系统win9x/win2000/winXP(标注Win32 DLL);
8)、可在多种编程环境下使用,例如VB、VC、Delphi等开发环境。

9)、支持modbus rtu标准的功能代码01、02、03、04、05、06、15、16且对相关功能代码的读取和写如做了一些扩充更加符合工业自动化领域的工控软件的开发,是广大工控工程师的必备工具软件。

二、modbus rtu通讯协议简介

   Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)
和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集
中监控。此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请
求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共
格式。当在一Modbus网络上通信时,此协议决定了每个控制器须要知道它们的设备地址,识别按地址发来的消息,决定
要产生何种行动。如果需要回应,控制器将生成反馈信息并用Modbus协议发出。在其它网络上,包含了Modbus协议的消
息转换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。
1、在Modbus网络上转输
标准的Modbus口是使用一RS-232C兼容串行接口,它定义了连接口的针脚、电缆、信号位、传输波特率、奇偶校验。控制
器能直接或经由Modem组网。控制器通信使用主—从技术,即仅一设备(主设备)能初始化传输(查询)。其它设备(从设备)
根据主设备查询提供的数据作出相应反应。典型的主设备:主机和可编程仪表。典型的从设备:可编程控制器。主设备
可单独和从设备通信,也能以广播方式和所有从设备通信。如果单独通信,从设备返回一消息作为回应,如果是以广播
方式查询的,则不作任何回应。Modbus协议建立了主设备查询的格式:设备(或广播)地址、功能代码、所有要发送的数
据、一错误检测域。从设备回应消息也由Modbus协议构成,包括确认要行动的域、任何要返回的数据、和一错误检测域。
如果在消息接收过程中发生一错误,或从设备不能执行其命令,从设备将建立一错误消息并把它作为回应发送出去。
2、在其它类型网络上转输
在其它网络上,控制器使用对等技术通信,故任何控制都能初始和其它控制器的通信。这样在单独的通信过程中,控制
器既可作为主设备也可作为从设备。提供的多个内部通道可允许同时发生的传输进程。在消息位,Modbus协议仍提供了
主—从原则,尽管网络通信方法是“对等”。如果一控制器发送一消息,它只是作为主设备,并期望从从设备得到回应。
同样,当控制器接收到一消息,它将建立一从设备回应格式并返回给发送的控制器。
3、查询—回应周期
(1)、查询    
   查询消息中的功能代码告之被选中的从设备要执行何种功能。数据段包含了从设备要执行功能的任何附加信息。例
如功能代码03是要求从设备读保持寄存器并返回它们的内容。数据段必须包含要告之从设备的信息:从何寄存器开始读
及要读的寄存器数量。错误检测域为从设备提供了一种验证消息内容是否正确的方法。
(2)、回应    
   如果从设备产生一正常的回应,在回应消息中的功能代码是在查询消息中的功能代码的回应。数据段包括了从设备
收集的数据:象寄存器值或状态。如果有错误发生,功能代码将被修改以用于指出回应消息是错误的,同时数据段包含
了描述此错误信息的代码。错误检测域允许主设备确认消息内容是否可用。

3、两种传输方式
   控制器能设置为两种传输模式(ASCII或RTU)中的任何一种在标准的Modbus网络通信。用户选择想要的模式,包括串
口通信参数(波特率、校验方式等),在配置每个控制器的时候,在一个Modbus网络上的所有设备都必须选择相同的传输
模式和串口参数。
ASCII模式
  -------------------------------------------
  | 地址 | 功能代码 | 数据数量 | 数据1 ... 数据n | LRC高字节 | LRC低字节 | 回车 | 换行 |
  -------------------------------------------
RTU模式
  ------------------------------------
  | 地址 | 功能代码 | 数据数量 | 数据1 ... 数据n | CRC高字节 | CRC低字节 |
  ------------------------------------
   所选的ASCII或RTU方式仅适用于标准的Modbus网络,它定义了在这些网络上连续传输的消息段的每一位,以及决定
怎样将信息打包成消息域和如何解码。在其它网络上(象MAP和Modbus Plus)Modbus消息被转成与串行传输无关的帧。
   因ASCII模式通讯效率较低一多采用RTU模式,这里只对RTU模式进行详细介绍。

4、Modbus RTU模式

   当控制器设为在Modbus网络上以RTU(远程终端单元)模式通信,在消息中的每个8Bit字节包含两个4Bit的十六进制
字符。这种方式的主要优点是:在同样的波特率下,可比ASCII方式传送更多的数据。

代码系统

   8位二进制,十六进制数0...9,A...F
   消息中的每个8位域都是一个两个十六进制字符组成

每个字节的位

   1个起始位
   8个数据位,最小的有效位先发送
   1个奇偶校验位,无校验则无
   1个停止位(有校验时),2个Bit(无校验时)

错误检测域
   
    CRC(循环冗长检测)

地址域

   消息帧的地址域包含8Bit(RTU)。可能的从设备地址是0...247(十进制)。单个设备的地址范围是1...247。主设备通过
将要联络的从设备的地址放入消息中的地址域来选通从设备。当从设备发送回应消息时,它把自己的地址放入回应的地址域
中,以便主设备知道是哪一个设备作出回应。地址0是用作广播地址,以使所有的从设备都能认识。当Modbus协议用于更高
水准的网络,广播可能不允许或以其它方式代替。

如何处理功能域

   数据域是由两个十六进制数集合构成的,范围00...FF。根据网络传输模式,这可以是由一RTU字符组成。从主设备发给
从设备消息的数据域包含附加的信息:从设备必须用于进行执行由功能代码所定义的所为。这包括了象不连续的寄存器地址,
要处理项的数目,域中实际数据字节数。例如,如果主设备需要从设备读取一组保持寄存器(功能代码03),数据域指定了起
始寄存器以及要读的寄存器数量。如果主设备写一组从设备的寄存器(功能代码10十六进制),数据域则指明了要写的起始寄
存器以及要写的寄存器数量,数据域的数据字节数,要写入寄存器的数据。如果没有错误发生,从从设备返回的数据域包含
请求的数据。如果有错误发生,此域包含一异议代码,主设备应用程序可以用来判断采取下一步行动。在某种消息中数据域
可以是不存在的(0长度)。例如,主设备要求从设备回应通信事件记录(功能代码0B十六进制),从设备不需任何附加的信息。


三、DLL函数说明


modbus.DLL是王俊于2007年最新开发的基于施耐得modbus rtu 通讯协议的串口通讯链接库。modbus.DLL专业版实现了对保持寄存器40001~4XXXX区数据读写(FCN03:读、FCN16:写,FCN06写单个数据);对逻辑线圈00001~0XXXX的 读写(FCN01:读取一组线圈,FCN05:强置单线圈,FCN15强置多线圈);对输入状态10001~1XXXX的读(FCN02);对输入寄存器30001~3XXXX的读(FCN04)。

DLL中的主要函数:

ComOpen:打开串口

ComClose:关闭串口

FCN01:读取一组线圈(00001~0XXXX)

FCN02:取得一组开关输入状态数据(10001~1XXXX)

FCN03:读多个保持寄存器数据(40001~4XXXX)

FCN04:读多个输入寄存器数据(30001~3XXXX)

FCN05S:置位单线圈(00001~0XXXX)

FCN05R:复位单线圈(00001~0XXXX)

FCN06: 预置单保持寄存器数据(40001~4XXXX)

FCN15: 强置多线圈的通断数据(00001~0XXXX)

FCN16: 写多个保持寄存器数据(40001~4XXXX)

FCN16_xSet:单保持寄存器的0~15相应位的置位(40001.0-40001.15~4XXXX.0-4XXXX.15)

FCN16_xReset:单保持寄存器的0~15相应位的复位(40001.0-40001.15~4XXXX.0-4XXXX.15)

FCN16_xSetReset:单保持寄存器的0~15相应位的置复位(40001.0-40001.15~4XXXX.0-4XXXX.15),
                指使相应的位短时间通断一次(约通60ms)

ComTrue:读取DLL中的串口是否备有效打开

CinBin: 字中相应的位的状态抽取

1、打开串口

Function ComOpen(nport,BaudRate,DataBits,Parity,StopBits:longint;User:Pchar):longint;stdcall;

参数:nport: 打开串口号,取值为1~8,代表COM1~COM8;
     
     BaudRate:波特率,取值为:1200、2400、4800、9600、19200、38400;
   
     DataBits:数据位,取值为5、6、7、8;

     Parity:  校验位,取值1(代表Even)、取值2(代表Odd)、取值3(代表Mark)、取值4(代表Space)、取值5(代表None);
 
     StopBits:停止位,取值1(代表1位停止位)、取值2(代表2位停止位)、取值3(代表1.5位停止位);

     User:DLL授权用户名;

返回值:长整型,操作成功返回“1”或“2”;1表示注册授权用户,2表示用户未注册;

操作不成功返回为“0”时的原因:1)、串口不存在或被占用; 2)、DLL注册授权不正确。

注:本DLL用户不注册除了下面说明的功能限制外没有其他限制,未注册用户请使用特定用户名:wangjun。

   注册用户功能上无任何限制,且将得到永久的软件使用和更新升级服务;

使用举例:

Delphi:ComOpen(1,9600,8,1,1,Pchar(‘wangjun‘)) , 打开COM1口。

VB:ComOpen(1,9600,8,1,1,"wangjun") , 打开COM1口。(注:下面的示例都以VB调用形式给出)

2、关闭串口

Function ComClose(nport:longint):longint;stdcall;

参数:nport: 串口号,取值为1~8,代表COM1~COM8;

返回值:长整型,操作成功返回“1”,否则返回“0”;

使用举例:

ComClose(1) ,关闭打开的COM1口。

3、modbus相应功能码所对应的读取功能函数。

1)、01功能码位元件的读取(读取一组线圈)

Function FCN01(nport,node,address,Count:longint):Pchar;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从00001~0XXXX地址区(逻辑线圈)值(你要读标准modbus的00001地址这个值为0000,依次类推)

Count:   读取的位元件个数,一次最多读取1000个但不能超出寻址范围;

返回值: 16进制字符串数据,字符串数据的终止符为"@";

使用举例:

FCN01(1,1,19,37),由COM1读取modbus 1号从站00020~00056(标准modbus地址)的位状态值,返回值为“CD6BB20E1B@”

则表示27~20:CD, 35~28:6B, 43~36:B2, 51~44:0E, 56~52:1B;

字节值与实际的位状态值对应参考(其他位功能函数的说明不再重复本内容):
           
位地址:    | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 35 | 34 | 33 | 32 | 31 | 30 | 29 | 28 |
           -----------------------------------------
各位赋值:   | 1  | 1  | 0  | 0  | 1  | 1  | 0  | 1  | 0  | 1  | 1  | 0  | 1  | 0  | 1  | 1  |
           -----------------------------------------
16进制串:  |         C         |         D         |         6         |         B         |
           -----------------------------------------

不足8位的位组的状态值参考:

位地址:    | 56 | 55 | 54 | 53 | 52 |
           -------------
各位赋值:   | 0  | 1  | 0  | 1  | 1  |
           -------------
16进制串:  | 1  |         B         |
           -------------

在读取错误或不能读取的情况下返回“Error@”

注:没有注册的用户只能读取00001~00006范围的状态值;

2)、02功能码位元件的读取(取得一组开关输入状态数据)

Function FCN02(nport,node,address,Count:longint):Pchar;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从10001~1XXXX地址区(开关输入状态)值(你要读标准modbus的10001地址这个值为0000,依次类推)

Count:   读取的位元件个数,一次最多读取1000个但不能超出寻址范围;

返回值: 16进制字符串数据,字符串数据的终止符为"@";

使用举例:

FCN02(1,1,196,22),由COM1读取modbus 1号从站10197~10218(标准modbus地址)的位状态值,返回值为“ACDB35@”

则表示10204~10197:AC, 10212~10205:DB, 10218~10213:35;

在读取错误或不能读取的情况下返回“Error@”

注:没有注册的用户只能读取10001~10006范围的状态值;

3)、03功能码字元件的读取(读多个保持寄存器数据)

Function FCN03(nport,node,address,Count:longint):Pchar;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从40001~4XXXX地址区(保持寄存器数据)值(你要读标准modbus的40001地址这个值为0000,依次类推)

Count:   读取的位元件个数,一次最多读取60个但不能超出寻址范围;

返回值: 16进制字符串数据,字符串数据的终止符为"@";

使用举例:

FCN03(1,1,107,3),由COM1读取modbus 1号从站40108~40110(标准modbus地址)的字状态值,返回值为“022B00000064@”

则表示40108:022B, 40109:0000, 40110:0064;

在读取错误或不能读取的情况下返回“Error@”

注:没有注册的用户只能读取40001~40003范围的状态值;

4)、04功能码字元件的读取(读多个输入寄存器数据)

Function FCN04(nport,node,address,Count:longint):Pchar;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从30001~3XXXX地址区(输入寄存器数据)值(你要读标准modbus的30001地址这个值为0000,依次类推)

Count:   读取的位元件个数,一次最多读取60个但不能超出寻址范围;

 

4、modbus相应功能码所对应的写入功能函数

1)、05功能码线圈的置复位功能函数

   1、线圈置位
           
      Function FCN05S(nport,node,address:longint):longint;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从00001~0XXXX地址区(逻辑线圈)值(你要写标准modbus的00001地址这个值为0000,依次类推)

返回值: 长整数,操作成功返回1,不能写入或操作错误返回0;

使用举例:

FCN05S(1,12,15),由COM1将modbus 12号从站00013(标准modbus地址)的位状态值置1,返回值为1表示成功

注:没有注册的用户只能写入00001~00006范围的状态值;

      2、线圈复位
           
      Function FCN05R(nport,node,address:longint):longint;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从00001~0XXXX地址区(逻辑线圈)值(你要写标准modbus的00001地址这个值为0000,依次类推)

返回值: 长整数,操作成功返回1,不能写入或操作错误返回0;

使用举例:

FCN05R(1,12,15),由COM1将modbus 12号从站00013(标准modbus地址)的位状态值置0,返回值为1表示成功

注:没有注册的用户只能写入00001~00006范围的状态值;

2)、06功能码预置单保持寄存器数据功能函数

Function FCN06(nport,node,address:longint;Sendstr:pchar):longint;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从40001~4XXXX地址区(保持寄存器)值(你要写标准modbus的40001地址这个值为0000,依次类推)

Sendstr: 写入字值,该值为4个一组的16进制字符串组成其取值为0000~FFFF(整数值为0~65535);

返回值: 长整数,操作成功返回1,不能写入或操作错误返回0;

当要写入字值时依次排列即可。如给40001写值1000,先将1000转成16进制字符串03E8,则sendstr=03E8;

使用举例:

FCN06(1,2,2,"03E8"),由COM1给modbus 2号从站40003(标准modbus地址)的字单元写入1000(16进制03E8),返回值为1表示成功

注:没有注册的用户只能写入40001~40003范围的状态值;

(00001~0XXXX)

3)、15功能码强置多线圈的通断数据功能函数

Function FCN15(nport,node,address,Count:longint;Sendstr:pchar):longint;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从00001~0XXXX地址区(逻辑线圈)值(你要写标准modbus的00001地址这个值为0000,依次类推)

Count:  写入位元件个数,一次最多1000个但不能超出寻址范围;

Sendstr: 给位元件写入的值按8个为一组和成字节值在写入,该值为2个一组的16进制字符串组其取值为00~FF(整数值为0~255);

返回值: 长整数,操作成功返回1,不能写入或操作错误返回0;

                 ---------- - ~ - ------
写字符串序列如:  | 00 | FF | 10 | 64 |   ~    | 08 | 04 |
                 ---------- - ~ - ------

实际字符串与位地址的数值应如下表:  
         
位地址:    | 40 | 39 | 38 | 36 | 35 | 34 | 33 | 32 | 48 | 47 | 46 | 45 | 44 | 43 | 42 | 41 |
           -----------------------------------------
各位赋值:   | 0  | 1  | 1  | 0  | 0  | 1  | 0  | 0  | 0  | 1  | 0  | 1  | 0  | 0  | 0  | 0  |
           -----------------------------------------
16进制串:  |         6         |         4         |         5         |         0         |
           -----------------------------------------

使用举例:

FCN06(1,2,19,10,"CD01"),由COM1给modbus 2号从站00020~00029(标准modbus地址)10个位单元写如相应值,返回值为1表示成功

写入值的参考 27~20:CD; 29~28:01;

位地址:    | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | -- | -- | -- | -- | -- | -- | 29 | 28 |
           -----------------------------------------
各位赋值:   | 1  | 1  | 0  | 0  | 1  | 1  | 0  | 1  | 0  | 0  | 0  | 0  | 0  | 0  | 0  | 1  |
           -----------------------------------------
16进制串:  |         C         |         D         |         0         |         1         |
           -----------------------------------------

注:没有注册的用户只能写入00001~00006范围的状态值;

4)、16功能码写多个保持寄存器数据功能函数

Function FCN16(nport,node,address,Count:longint;Sendstr:pchar):longint;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从40001~4XXXX地址区(保持寄存器)值(你要写标准modbus的40001地址这个值为0000,依次类推)

Count:  写入字元件个数,一次最多60个但不能超出寻址范围;

Sendstr: 给字写入的值,该值为4个一组的16进制字符串组其取值为0000~FFFF(整数值为0~65535);

返回值: 长整数,操作成功返回1,不能写入或操作错误返回0;

当要写入多个字值时依次排列即可。如给40001与40002写值100和1000,先将100转成16进制字符串0064、1000转成16进制字符串03E8,

则sendstr=006403E8;一次最多写64个字即字符串长应小于等于256;

                           ---------- ----   ~  ---------
写字符串序列如:             | 0064 | 03E8 | 0010 | 6004 |   ~     | 0008 | 0400 |
                           ---------- ----   ~  ---------

使用举例:

FCN16(1,2,1,"000A0102"),由COM1给modbus 2号从站40002(标准modbus地址)的字单元写入给10(16进制000A)、40003(标准modbus地址)

的字单元写入给258(16进制0102)返回值为1表示成功;

注:没有注册的用户只能写入40001~40003范围的状态值;

5)、modbus功能码16的扩展功能函数

      1、单保持寄存器的0~15相应位的置位 (40001.0-40001.15~4XXXX.0-4XXXX.15)
           
      Function FCN16_xSet(nport,node,address,Bit:longint):longint;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从40001~4XXXX地址区(保持寄存器)值(你要写标准modbus的40001地址这个值为4000,依次类推)

Bit:     保持寄存器的位,取值0~15;

返回值: 长整数,操作成功返回1,不能写入或操作错误返回0;

使用举例:

FCN16_xSet(1,12,2,0),由COM1将modbus 12号从站40003(标准modbus地址)的第0个位状态值置1,返回值为1表示成功

注:没有注册的用户不能使用本功能;

       2、单保持寄存器的0~15相应位的复位 (40001.0-40001.15~4XXXX.0-4XXXX.15)
           
       Function FCN16_xReset(nport,node,address,Bit:longint):longint;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从40001~4XXXX地址区(保持寄存器)值(你要写标准modbus的40001地址这个值为4000,依次类推)

Bit:     保持寄存器的位,取值0~15;

返回值: 长整数,操作成功返回1,不能写入或操作错误返回0;

使用举例:

FCN16_xReset(1,10,3,12),由COM1将modbus 10号从站40004(标准modbus地址)的第12个位状态值置0,返回值为1表示成功

注:没有注册的用户不能使用本功能;

       3、单保持寄存器的0~15相应位的置复位 (40001.0-40001.15~4XXXX.0-4XXXX.15)指使相应的位短时间通断一次(接通约60ms)
           
       Function FCN16_xSetReset(nport,node,address,Bit:longint):longint;stdcall;

参数:

nport:   串口号,取值为1~8,代表COM1~COM8;

node:   modbus从站号,取值1~255;

address: 元件地址,取值范围从40001~4XXXX地址区(保持寄存器)值(你要写标准modbus的40001地址这个值为4000,依次类推)

Bit:     保持寄存器的位,取值0~15;

返回值: 长整数,操作成功返回1,不能写入或操作错误返回0;

使用举例:

FCN16_xSetReset(1,10,9,10),由COM1将modbus 10号从站40010(标准modbus地址)的第10个位状态值置1后约60ms再置0,返回值为1表示成功

注:没有注册的用户不能使用本功能;

四、DLL附加函数说明 (本段函数对未注册用户没有限制,完全可以使用。)

1、串口打开状态的读取

Function ComTrue(nport:longint):longint;stdcall;

参数:

noprt: 串口号,取值为1~8,代表COM1~COM8;

返回值:长整型,串口成功打开返回“1”,否则返回“0”;

这里读取是DLL有效取得了串口的控制权,如果其他程序占用(串口不存在)等原因仍返回“0”。

2、整数转换成16进制字符串 (为VC等非RAD开发环境所增设)

Function CIntToHex(Dcint,Digits:Longint):Pchar;stdcall;

参数:

Cint: 待转换整数,取值为(0~65535);

Digits: 转换的字符串位数,指定位数小于实际位数时按实际输出;

在参数错误等非法的情况下返回“Error@”

使用举例:

CIntToHex(200,2),则返回字符串“C8@”;
CIntToHex(200,4),则返回字符串“00C8@”;
CIntToHex(200,8),则返回字符串“000000C8@”;
CIntToHex(4500,4),则返回字符串“1194@”;
CIntToHex(4500,3),则返回字符串“1194@”,因为“194”不足以表示4500这个数所以按实际输出字符串“1194@”;

"@"为字符串数据的终止符。

3、16进制字符串转换成整数 (为VC等非RAD开发环境所增设)

Function CHexToInt(CHex:Pchar):Longint;stdcall;

参数:

CHex: 待转换字符串,取值为(0000~FFFF);

使用举例:

CHexToInt("03E8"),则返回整数1000;

注:在参数不正确等出错情况下返回值为“-1”。

4、抽取(0~65535)所示整数中(0~15)某个位的值

Function CinBin(CHex,Start:longint):longint;stdcall;

参数:

CHex: 待转换整数,取值为0~65535(0000~FFFF);

Start: 抽取的位,取值为(0~15);

使用举例:

CinBin(15,3),则返回值1;
CinBin(15,4),则返回值0;
CinBin(1000,6),则返回值1;

读取MB0组合成的字节值为“FC”(252)时,要读取M0.1的值时,则调用CinBin(252,1)返回值0表示M0.1的值为0。

注:在参数不正确等出错情况下返回值为“-1”。

5、返回字符串Text左边的Count个字符  (为VC等非RAD开发环境所增设)

Function CLeftStr(Text:Pchar;Count:longint):Pchar;stdcall;

参数:

Text: 字符串原型;

Count: 指定返回左侧字符串个数;

在参数错误等非法的情况下返回“Error@”

使用举例:

CleftStr("123456", 3) = "123@";

"@"为字符串数据的终止符。

6、返回字符串Text右边的Count个字符  (为VC等非RAD开发环境所增设)

Function CRightStr(Text:Pchar;Count:longint):Pchar;stdcall;

参数:

Text: 字符串原型;

Count: 指定返回右侧字符串个数

在参数错误等非法的情况下返回“Error@”

使用举例:

CRightStr("123456", 3) = "456@";

"@"为字符串数据的终止符。

7、返回字符串Text从Start开始的Count个字符 (为VC等非RAD开发环境所增设)

Function CMidStr(Text:Pchar;Start,Count:longint):Pchar;stdcall;

参数:

Text: 字符串原型;

Start: 指定返回字符串的起始位置;

Count: 指定返回字符串个数;

在参数错误等非法的情况下返回“Error@”

使用举例:

CMidStr("123456",2,3) = "234@";

"@"为字符串数据的终止符。

8、字符串Cstr开始于字符串Ostr的位置 (为VC等非RAD开发环境所增设)

Function Cinstr(Ostr,Ckstr:Pchar;Dcint:Longint):Longint;stdcall;

参数:

Ostr:  字符串原型;

Cstr:  查询的字符串;

Dcint: 设定查询字符串的起始位置,取值>=1,即最少从源字符串的第一个字符开始查询;

返回值:长整型;

使用举例:

CinStr("1Tfdg23456","2",2) = 6

注:在参数不正确等出错情况下返回值为“0”。

9、PC喇叭的报警过程函数;

Function MyBeep(SoundHz:longint):longint;stdcall;

参数:SoundHz:长整型;

返回值:长整型,操作成功返回“1”,否则返回“0”。

使用举例:

MyBeep(2000); 按2000的频率发出报警声。

DLL中关于传出字符串值的函数都以"@"为字符串函数值终止符,这是对多开发环境应用时方便用户正确读取返回字符串数据而设。


五、Delphi、VB、VC语言环境的开发使用说明

1、Delphi语言环境开发说明

在Delphi环境下将modbus.dll、serialmodbus.slip(许可文件)复制到应用程序目录下(即将上述文件与编译后的可执行文件方入同一文件内);

在工程文件的主程序窗体(pas)文件中声明:

 Function ComOpen(nport,BaudRate,DataBits,Parity,StopBits:longint;User:Pchar):longint;stdcall;External‘modbus.dll‘;
 Function ComClose(nport:longint):longint;stdcall;External‘modbus.dll‘;
 Function FCN01(nport,node,address,Count:longint):Pchar;stdcall;External‘modbus.dll‘;
 Function FCN02(nport,node,address,Count:longint):Pchar;stdcall;External‘modbus.dll‘;
 Function FCN03(nport,node,address,Count:longint):Pchar;stdcall;External‘modbus.dll‘;
 Function FCN04(nport,node,address,Count:longint):Pchar;stdcall;External‘modbus.dll‘;
 Function FCN05S(nport,node,address:longint):longint;stdcall;External‘modbus.dll‘;
 Function FCN05R(nport,node,address:longint):longint;stdcall;External‘modbus.dll‘;
 Function FCN06(nport,node,address:longint;Sendstr:pchar):longint;stdcall;External‘modbus.dll‘;
 Function FCN15(nport,node,address,Count:longint;Sendstr:pchar):longint;stdcall;External‘modbus.dll‘;
 Function FCN16(nport,node,address,Count:longint;Sendstr:pchar):longint;stdcall;External‘modbus.dll‘;
 Function FCN16_xSet(nport,node,address,Bit:longint):longint;stdcall;External‘modbus.dll‘;
 Function FCN16_xReset(nport,node,address,Bit:longint):longint;stdcall;External‘modbus.dll‘;
 Function FCN16_xSetReset(nport,node,address,Bit:longint):longint;stdcall;External‘modbus.dll‘;
 Function ComTrue(nport:longint):longint;stdcall;External‘modbus.dll‘;
 Function MyBeep(SoundHz:longint):longint;stdcall;External‘modbus.dll‘;

其它附加函数Delphi有实用函数,建议用Delphi自带函数,如需使用声明参照上例;

注:所有DLL的函数必须声明方能使用,建议本DLL的声明采用示例所示的静态声明方式。 声明后可以在程序中使用这些函数,附加函数

中除ComTrue、CinBin、MyBeep等Delphi系统自带有类似功能函数。通信时必须先使用ComOpen函数打开串口,在串口打开后可以有效操作

相关函数,为确保通信可在程序运行开始时打开串口,程序退出前关闭串口。应用程序退出之前请务必将关闭所有串口,如串口没有关闭

而退出程序将抛出异常错误。

确保应用程序在关闭释放前关闭打开的串口。解决方法,在form的OnDestroy事件中加入如下语句:

for i:=1 to 8 do
begin
 if ComTrue(i)=1 then ComClose(i);
end;

在Delphi中给中给DLL中的函数传pchar值问题,建议string型转换到Pchar型采用strPCopy()函数,Pchar型转换到string型采用straps()函数,

不推荐使用直接转换法即string到Pchar类型采用Mpchar=Pchar(str),Pchar到string采用str:=Mpchar (str为string类型、Mpchar为Pchar

类型)。上述可以详细参照DEMO程序。

2、VB语言环境开发说明

在VB环境下将modbus.dll、serialmodbus.slip(许可文件)复制到应用程序目录下(即将上述文件与编译后的可执行文件方入同一文件夹内);

函数说明中给出的是Delphi的函数原型,在VB中声明时只要注意一下类型的对应即可Delphi中的longint类型对应VB中的Long类型、

Delphi中的Pchar对应VB中的String类型,下面给出主要函数的声明:

PrivatedeclareFunction ComOpen Lib "modbus.dll" (ByVal nport As Long, ByVal BaudRate As Long, ByVal DataBits As Long, ByVal Parity As Long, ByVal StopBits As Long, ByVal User As String) As Long
PrivatedeclareFunction ComClose Lib "modbus.dll" (ByVal nport As Long) As Long
PrivatedeclareFunction FCN01 Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByValcountAs Long) As String
PrivatedeclareFunction FCN02 Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByValcountAs Long) As String
PrivatedeclareFunction FCN03 Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByValcountAs Long) As String
PrivatedeclareFunction FCN04 Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByValcountAs Long) As String
PrivatedeclareFunction FCN05S Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long) As Long
PrivatedeclareFunction FCN05R Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long) As Long
PrivatedeclareFunction FCN06 Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByVal Sendstr As String) As Long
PrivatedeclareFunction FCN15 Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByValcountAs Long, ByVal Sendstr As String) As Long
PrivatedeclareFunction FCN16 Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByValcountAs Long, ByVal Sendstr As String) As Long
PrivatedeclareFunction FCN16_xSet Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByVal Bit As Long) As Long
PrivatedeclareFunction FCN16_xReset Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByVal Bit As Long) As Long
PrivatedeclareFunction FCN16_xSetReset Lib "modbus.dll" (ByVal nport As Long, ByVal node As Long, ByVal address As Long, ByVal Bit As Long) As Long
PrivatedeclareFunction ComTrue Lib "modbus.dll" (ByVal nport As Long) As Long
PrivatedeclareFunction MyBeep Lib "modbus.dll" (ByVal SoundHz As Long) As Long
PrivatedeclareFunction CinBin Lib "modbus.dll" (ByVal CHex As Long, ByVal start As Long) As Long

其它附加函数VB有实用函数,建议用VB自带函数,如需使用声明参上面的例子给相应的函数声明;做完上述声明后,便可以在程序中使用

相关函数了。本DLL是串口通信库,通信时必须先使用ComOpen函数打开串口,在串口打开后可以有效操作相关函数,为保证通信可以在

程序运行开始时打开串口,程序退出前关闭串口。在应用程序关闭之前请务必将关闭所有串口,如您的程序串口没有关闭退出程序将抛

出异常。当出现这样的异常请更改您的程序,确保应用程序在关闭释放前关闭所打开的串口。

解决方法,在form的Unload事件中加入如下例:

If ComTrue(1)=1 then
 ComClose(1)
End if

为确保Unload事件有效执行程序中不应使用“End”语句,而尽量使用“Unload”语句释放所有窗体,因使用“End”语句系统不会执行

正常的窗体释放等事件而直接退出程序,如程序中有form1,form2两个窗体,则使用下面语句:

Unload  form1
Unload  form2

VB会在所有窗体关闭后释放所有占用资源。上述可以详细参照DEMO程序。当然也可在使用“End”语句前将串口关闭也是可以释放串口的。

3、VC语言环境开发说明

在VC环境下将modbus.dll、serialmodbus.slip(许可文件)复制到应用程序目录下(即将上述文件与编译后的可执行文件方入同一文件夹内);

在VC中使用DLL一般都是采用动态声明的方式,函数说明中给出的是Delphi的函数原型,在VC中声明时只要注意一下类型的对应即可

Delphi中的longint类型对应VC中的Long类型、Delphi中的Pchar对应VC中的char* 类型,下面给出主要函数的声明:

在工程主文件cpp中声明一个句柄:

HINSTANCE m_handle;

用来标识导入的动态链接库。

1)、导入动态链接库,如例所示:

  m_handle =:: LoadLibrary("modbus.dll");

2)、按下例说明声明相关各个函数:

typedef long (CALLBACK* pOpen)(long nport, long BaudRate, long DataBits, long Parity, long StopBits, char* User);
typedef long (CALLBACK* pClose)(long nport);
typedef char* (CALLBACK* pFCN01)(long nport, long node, long address, long Count);
typedef char* (CALLBACK* pFCN02)(long nport, long node, long address, long Count);
typedef char* (CALLBACK* pFCN03)(long nport, long node, long address, long Count);
typedef char* (CALLBACK* pFCN04)(long nport, long node, long address, long Count);
typedef long (CALLBACK* pFCN05S)(long nport, long node, long address);
typedef long (CALLBACK* pFCN05R)(long nport, long node, long address);
typedef long (CALLBACK* pFCN06)(long nport, long node, long address, char* Sendstr);
typedef long (CALLBACK* pFCN15)(long nport, long node, long address, long Count, char* Sendstr);
typedef long (CALLBACK* pFCN16)(long nport, long node, long address, long Count, char* Sendstr);
typedef long (CALLBACK* pFCN16_xSet)(long nport, long node, long address, long Bit);
typedef long (CALLBACK* pFCN16_xReset)(long nport, long node, long address, long Bit);
typedef long (CALLBACK* pFCN16_xSetReset)(long nport, long node, long address, long Bit);
typedef long (CALLBACK* pTrue)(long nport);
typedef char* (CALLBACK* pIntHex)(long Dcint,long Digits);
typedef long (CALLBACK* pHexInt)( char* CHex);
typedef long (CALLBACK* pBin)( long Chex, long Start);
typedef char* (CALLBACK* pLeft)( char* Text, long Count);
typedef char* (CALLBACK* pRight)( char* Text, long Count);
typedef char* (CALLBACK* pMid)( char* Text, long  Start, long Count);
typedef long (CALLBACK* pinstr)( char* Ostr, char* Ckstr, Long Dcint);
typedef long (CALLBACK* pBeep)( long SoundHz);

3)、声明并建立动态链接库中的函数与新函数名的对应关系,如下:

pOpen Copen = (pOpen)GetProcAddress(m_handle,"ComOpen");
pClose Cclose = (pClose)GetProcAddress(m_handle,"ComClose");
pFCN01 CFCN01 = (pFCN01)GetProcAddress(m_handle,"FCN01");
pFCN02 CFCN02 = (pFCN02)GetProcAddress(m_handle,"FCN02");
pFCN03 CFCN03 = (pFCN03)GetProcAddress(m_handle,"FCN03");
pFCN04 CFCN04 = (pFCN04)GetProcAddress(m_handle,"FCN04");
pFCN05S CFCN05S = (pFCN05S)GetProcAddress(m_handle,"FCN05S");
pFCN05R CFCN05R = (pFCN05R)GetProcAddress(m_handle,"FCN05R");
pFCN15 CFCN15 = (pFCN15)GetProcAddress(m_handle,"FCN15");
pFCN16 CFCN16 = (pFCN16)GetProcAddress(m_handle,"FCN16");
pFCN16_xSet CFCN16_xSet = (pFCN16_xSet)GetProcAddress(m_handle,"FCN16_xSet");
pFCN16_xReset CFCN16_xReset = (pFCN16_xReset)GetProcAddress(m_handle,"FCN16_xReset");
pFCN16_xSetReset CFCN16_xSetReset = (pFCN16_xSetReset)GetProcAddress(m_handle,"FCN16_xSetReset");
pTrue Ctrue = (pTrue)GetProcAddress(m_handle," ComTrue");
pIntHex Cinthex = (pIntHex)GetProcAddress(m_handle," CIntToHex");
pHexInt Chexint = (pHexInt)GetProcAddress(m_handle," CHexToInt");
pBin Cbin = (pBin)GetProcAddress(m_handle," CinBin");
pLeft Cleft = (pLeft)GetProcAddress(m_handle," CLeftStr");
pRight Cright = (pRight)GetProcAddress(m_handle," CRightStr");
pMid Cmid= (pMid)GetProcAddress(m_handle," CMidStr");
pinstr Cinstr=(pinstr)GetProcAddress(m_handle," CinStr");
pTrue CBeep = (pBeep)GetProcAddress(m_handle," MyBeep");

注:双引号中为动态链接库中的函数名。

4)、接下来就可以自由使用动态链接库中的函数了,如:

Copen(参数略);
Cclose(参数略);
CFCN01(参数略);
CFCN02(参数略);
CFCN03(参数略);
CFCN04(参数略);
CFCN05S(参数略);
CFCN05R(参数略);
CFCN15(参数略);
CFCN16(参数略);
CFCN16_xSet(参数略);
CFCN16_xReset(参数略);
CFCN16_xSetReset(参数略);
Ctrue(参数略);
Cinthex(参数略);
Chexint(参数略);
Cbin(参数略);
Cleft(参数略);
Cright(参数略);
Cmid(参数略);
Cinstr(参数略);
CBeep(参数略);

注:函数中用到了char*型参数,这里介绍下char*与Cstring的相互转换的函数:

(1)char*->CString

char* sz;
CString str;
str.Format("%s",sz);  //可以用此函数将读取的值转成字符串

(2) CString -> char*

CString str;
char* sz = str.GetBuffer(0);//可将字符串转成char*给函数赋值


5)、当不再需要使用DLL时记得关闭串口及释放动态链接库,如:

关闭串口

if cTrue(1)==1 then
{
 cClose(1);
}

6)、释放DLL

FreeLibrary(m_handle);

六、详细的DLL使用请参DEMO程序,相关DEMO程序和说明所使用的开发环境VB指的是VB6.0,Delphi指的是Delphi6.0/Delphi7.0,

VC指的是VC6.0。如果使用了高版本开发环境请根据开发软件更新后所兼容的声明方式进行声明调用。VC的串口调用没DEMO程序

请参照本手册的说明进行调用(本说明的方法经过测试是可行有效的)。

DLl已经过使用和测试具有很好的稳定性(测试平台为Win2000/WinXP),目前还没有用户方面返回的缺陷报告,如果你在使用过程中发现



返回值: 16进制字符串数据,字符串数据的终止符为"@";

使用举例:

FCN04(1,17,8,1),由COM1读取modbus 17号从站30009(标准modbus地址)的字状态值,返回值为“000A@”

则表示30009:000A;

在读取错误或不能读取的情况下返回“Error@”

注:没有注册的用户只能读取30001~30003范围的状态值;

豪哥

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 542回
  • 年度积分:202
  • 历史总积分:3735
  • 注册:2012年3月19日
发表于:2012-11-12 13:22:44
2楼

MD1000 RTU具有很高的处理和复杂的计算功能,可连接成802.4LAN网,并支持点对点通信功能。所以,一个RTU采集的数据可以被传送到另一个MD1000而组成一个更大的逻辑RTU。 

  2.2 作为数据集中器/协议转换器 

    MD1000 RTU可以配置为数据集中器/协议转换器,此时MD1000 RTU扫描多个RTURTU网络数据,并支持多种RTU的通信协议和多种通信方式。

    MD1000 RTU采集信息后,通过协议(DNP3,MODBUS,Conitel等)传送到一个或多个主控站。 

  2.3 作为前端处理装置 

MD1000 RTU作为前端处理装置能够执行通信协议的转换和其它功能。此时MD1000 RTU可以作为协议转换器并执行其它管理功能。MD1000 RTU也可以被配置为冗余结构。 

3. 硬件概述 

    MD1000 RTU是一系列模块组成的可插卡式RTU,可直接插到MD1000 RTU的后板上。作为最小配置,MD1000 RTU由处理器模块和电源模块组成。这些模块适合不同的插槽式机架,并能安装在一系列机箱或提供19英寸的机架中。

每个处理器驱动一个带6个以上I/O口或其它模块的MD1000 RTU插槽。 

  3.1 扩展性 

使用2M令牌总线LAN或通过可选的以太网卡可连接32个底板。 

3.2     处理器模块 

PM-121处理器模块是MD1000 RTU系统的核心,提供正确操作所必需的控制功能。PM-121是高性能处理平台,具有一对双绞线802.4MODEM和二个RS232的通信接口。 

3.2.1 技术指标:

MC68020 32位处理器。IEEE820.4 LAN接口(2MB令牌总线LAN)

16MHz时钟频率。2*RS232 接口

。存储器RAM:4MB可扩至6MB。ROM:128KB

。实时时钟。4*LED输出

4*DIL开关输入。看门狗时钟    

3.2.2 LAN接口

   处理器模块具有内置式802.4媒质访问控制器和一对双绞线网络接口,可用于组建大型RTU。LAN接口具有以下特性:

   。令牌总线控制器(MC68824)       。波特率2Mbit

   。热备冗余双绞线媒质              。长度达到200米

   。RS485                           。最多32个设备

   。多机隔离功能                

   3.2.3 通讯模块

   可选通讯模块提供给MD1000一个标准的以太网接口和一个提供4个端口的多串行通讯模块,端口可配置为RS232或RS485操作。一个MD1000 RTU机架配置6个通讯模块。  

   3.2.4 内存扩展

   可选安装的内存扩展模块提供附加内存,它可提供2MBEPROM和有源RAM。 

3.3     I/O模块 

MD1000 RTU包括一系列不同的I/O模块。

I/O模块主要分为两类:模拟模块和数字模块。模拟模块的处理分辨率为12位,所处理为一个数量值;数字模块支持数字位上的ON/OFF

除了上述的区别,模块还分为输入和输出两种,输入模块与外部设备连接,采集状态点和数值;输出模块用于控制或改变输出点和值,以使设备执行所需功能。

所有的I/O模块都具有调节和端子设备用于系统的电气隔离。端子模块具有抗冲击保护(高达5KV),使用变阻器使冲击电压降到0。冲击限度表示没有故障或灾难发生时允许在I/O终端和插槽之间产生的冲击电压。

通过标准地址技术,可进行I/O模块选择和控制扫描。允许模块槽号的检查和总线接口的集成。

每个I/O模块被分配一个模块标识符,当一个模块被选择时标识符将被返回。扫描软件校验标识符是否为所希望类型,并收集有效数据。

所有的模块都具有LED以显示被扫描和控制的数据的当前状态,直观反映该模块的操作状态。主要I/O模块有如下几种:  

      3.3.1 数字输入模块

DIM-102数字输入模块可监测16个数字状态点。寻址到数字输入模块将会停止数据的读取,以使得补码被校验。单独选择模块将读取新的数据。  

3.3.2 模拟输入模块

AIM-101能扫描8个输入的电流或电压的模拟数据通道。输入可以是单极性或双极性。模拟信号被转换为12位值。

AIM-105能扫描16个输入的电流或电压的模拟数据通道。输入可以是单极性或双极性,模拟信号被转换为12位值。通道彼此之间电气隔离。  

3.3.3 脉冲计数模块

脉冲计数模块有8个通道,每通道含有一个16位计数器用于计算输入脉冲。输入采用光隔离,极性采用桥整流器保护。  

3.3.4 数字输出模块

DOM-101是一个16通道输出模块,控制16个继电器。当系统操作失败时,如果处理器不周期性的刷新数据,看门狗将确保输出无效(打开)。

DOM-102是一个16通道输出模块,控制16个晶体管输出。当系统操作失败时,如果处理器不周期性的刷新数据,看门狗将确保输出无效(打开)。  

3.3.5 脉冲输出模块

脉冲输出模块提供16个常开的、高安全脉冲继电器输出。输出被分为两组,每组8个,分别与每组的公共部分相接处。

用一个带选择/检查/执行的三项开关来保证输出操作的正确性。在同一时间只有一种输出方式被执行。

  3.3.6 模拟输出模块

     模拟输出模块提供8通道12位模拟量。每个通道之间相互隔离。每个通道均可以输出电压或电流信号,并可以单独的调整输出范围。  

3.4     端子模块 

   端子模块提供输入保护和保险。以下是配置的终端类型:

l      螺旋隔离块

l      克朗绝缘置换块

l      带单独断开连结的螺旋终端块

3.5     电源模块 

   每个机架有一个单独电源。以下的输入范围是有效的:

   * 110V DC

   * 48V DC

   * 24V DC

   * 12V DC

   所有的电源在电子电路与机架地之间提供2.5千伏电压并且给机架地线提供5千伏脉冲保护。 

4.遥测功能 

  4.1 遥测接口 

   MD1000 RTU具有一系列通信接口模块(CIM)作为遥测接口。通信控制器包括一个与调制解调器相连的RS232串口,调制解调器对于以下通讯方式都有效:

l      拨号上网

l      租用线路

l      ISDN

l      无线电

l      卫星等 

4.2 协议 

   MD1000系统可以提供多种协议。作为标准MD1000支持DNP3MODBUS既为主协议又为从协议。当然,其它厂商的协议也被支持,例如:

   * Leed and Northrup Conitel

   * Wormald

   * Westinghouse

   * Asea Brown Boveri

   * Toshiba

   * GEC K Bus

iceboy851013

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 161回
  • 年度积分:0
  • 历史总积分:3733
  • 注册:2010年8月05日
发表于:2012-11-12 21:03:38
3楼

文中介绍了Modbus RTU通讯协议的特点,阐述了该协议在VC2005编程环境下申口调试软件的具体实现方法。并编制了相关的程序,该程序采用了模块化思想,结构清晰,操作简便,实现了良好的ModbusRTU报文储存及管理机制,使用多线程兼顾界面显示和数据通讯,完全兼容ModbuaRTU通讯协议,可用于自定义功能码的Modbus兼容设备的调试,克服了普通Modbus调试软件仅能用于Modbus标准功能码调试的不足。实践证明,该程序编制思想合理、运行稳定、操作简便易行,为工业自动化中Modbus设备的调试带来方便。


一、ModbusRTU通信协议简介
   Modbus通信协议是Modieon公司开发的一种通信协议,它采用主从问答方式工作,是一种真正开放、标准的、免收许可费的网络通信协议。广泛用于自动化控制器和测控仪表,现已成为一种公认的通用工业标准。如今Modbus协议已经成为我国工业自动化网络协议规范的国家标准之一。不同厂商生产的控制设备可以籍此连成工业网络。进行集中监控。该协议有2种传输模式,即RTU模式和ASCII模式。对于ASCII模式,一个信息帧中的每8位的字节作为2个ASCII字符传输;而对于RTU模式。信息帧中的8位数据作为2个4位16进制字符,相对于ASCII模式,RTU模式表达相同的信息需要较少的位数,且在相同通信速率下具有更大的数据流量。因此通常情况下,一般工业智能仪表仪器都是采用RTU模式的Modbus规约。

二、ModbusRTU传输过程
    信息传输为异步方式,并以字节为单位。在主站和从站之间传递的通讯报文的信息帧格式如表1所示。
    ModbusRTU采用主从方式,若主机设备发送一个信息,则可从一台从机设备返回一个响应,类似的,当一台从机设备接受信息时,它就组织一个从机设备的响应信息,并返回至原发送信息的主机设备。
   当通讯命令由主机发送至从机时,符合相应地址码的从机接收通讯命令,并根据功能码及相关要求读取信息,如果CRC校验无误,则执行相应的任务,然后把执行结果返送给主机。
三、基于ModbusRTU的串口调试软件实现
3.1主体架构
   软件采用两个线程,主线程显示主界面,用来设置数据。报文处理线程用来监听报文帧、分析报文、取出主界面设置的数据并打包作出回应【6l。
   对于各部分的功能用类进行封装处理,力求使程序简洁易懂、便于移植。程序中所用的各种模块如
下【7,8】:
   (1)线程问数据传送模块:用于主线程与子线程间传送主界面所设置的数据,采用全局变量进行线程间通信,使用互斥体(CMutex)进行线程同步。
   (2)串口数据收发模块:用于串口打开、关闭等常用操作及串口数据的收发,为保证串口收发模块的灵活性,模块中串口数据的收发程序采用了串口操作相关的WindowsAPI函数。
   (3)Modbus协议模块:对串口数据收发模块再次封装并实现了ModbusR,rU的各种报文规范。定义了报文格式的两种结构——PDU(协议数据单元)和ADU(应用数据单元),及两者相互转化的方法。并在
此基础上实现了对接受报文的判断解析和对欲发送报文组织打包。
   (4)CRC校验模块:用于生成发送报文的16位CRC校验码,并对接受的报文再次生成CRC校验码以便于与原校验码进行比对。
3.2报文数据的存储及管理
    为了存储报文中的数据,在内存中划分出来一个256Bytes大小的报文缓冲区。收到的报文和打包好的报文都暂存在该区域中。也就是说对报文的解析和打包就变成了对报文缓冲区的操作【9,10】。为了更好地管理报文缓冲区,定义了两个结构PDU一HANDLE模拟是PDU(报文数据单元),其中PDU—HANDLE模拟的是PDU(报文数据单元),ADU一CONTROI模拟的是ADU(协议数据单元)【11l。二者定义如下:
struet PDU—HANDLE
{
     unsignedchar*PDUBuffPtr;//PUD数据指针
     urlsigned
     char FunctionCode;//请求功能代码
     umigrled$l‘92rt PD‰h;//PDU字节长度
     unsigned
     char Exeeptiong硝e;//异常代码
};
Sta"uct ADU_CONTROL,
{
     unsigned char*ADUBuffPtr;//ADU缓冲区指针,指向报文缓冲区
unsigned char ADULength;//设备地址
unsigned short ADULength;//ADU字节长度
};

对PDU_HANDIE和ADU_CONTROL操作的函数主要有PackDU2PDU()、ClearPDUBuf()、PackP_DU2ADU()。其主要流程是:
    1)收到合法的报文后,对结构ADU-CONTROL进行填充。报文被存储在ADU—CoNTROL的成员AD切3uffPtr指向的内存单元中。报文其它相关信息(从机地址,报文长度)填充到ADU—CONTRoI.的剩余成员中。
    2)执行PackADU2PDU()。完成ADU向PDU的转换。此步主要完成CRCl6校验码比对,并依据ADU—CONTRoI的成员完成对PDU_HANDLE的填充,以便于后续对PDU内容的分析处理。
    3)执行ClearPDUBuf() ,清空PDU数据缓冲区内容。此时已经完成对接受报文的分析,要清空PDU数据缓冲区内容.以装填欲发送的PDU数据。
    4)执行PackPDU2ADU()。使PDU头部加上设备地址,尾部附加CRcl6校验码。此时封装成了完整的报文,以便发送。
 
3.3功能码及相应处理函数本程序对不同的功能码设置了不同的处理函数。
    出了部分标准功能码及相应的处理函数。Modbus调试软件一般作为从机。对主机发来的符合Modbus协议的报文进行解析回应。普通的Modbus调试软件一般只能对上述四种标准功能码进行解析回应。但是对于实际的Modbus设备来说。这四种功能码是远远不够的,更多的时候需要自定义功能码来完成相关的功能。为了完成对自定义功能码的调试。可以在调试软件中加入自定义功能码处理函数。这样便可以使此程序有更强的针对性【7】。

功能码对应函数功能描述
0x01
ReadCoils
读线圈
0x02
ReadDiscretlnputs
读离散输入量
0x03
ReadHoldReg
读保持继存器
0x04ReadInputReg读输入继存器
四、结束语
    利用上述方法,在VC2005环境下编制的基于ModbusRTU的串口调试软件,在某自动化企业小型PLC研发项目的上位机与下位机通信调试中得到应用。既能对标准Modbus功能码进行调试,也可对自定义功能码进行调试。实践证明程序运行稳定、可靠,操作简便、易行。为自定义功能码的Modbus RTU串口调试提供了一条简洁、可行的解决方法。


 

PLC酷客

  • [版主]
  • 精华:9帖
  • 求助:31帖
  • 帖子:1460帖 | 7990回
  • 年度积分:457
  • 历史总积分:59176
  • 注册:2004年7月13日
发表于:2012-11-12 21:12:53
4楼

通过GPRS对PLC/RTU进行远程下载的方法

1234本文主要介绍通过GPRS方式,对北京安控科技发展有限公司生产的RTU及PLC产品,进行远程下载的方法。

关键字:2135GPRS、RTU、PLC、DTU

  一、前言

  通过GPRS通讯方式,可以对安控公司的SuperE 系列 RTU和Rock E20系列 PLC产品,进行远程下载。
  安控公司的RTU和PLC产品,还支持通过拨号Modem、数传电台和局域网进行远程下载,具体方法可参见其他相关说明。
  EchoBUS通讯协议和ModBUS RTU和ModBUS ASCII协议兼容。EchoBUS命令提供远程规划和诊断能力,支持远程下载,可以参见《ELadder 2.0 使用手册》附录E。
  文章介绍的方法,主要应用于PLC或RTU作为数据采集站点,而无控制要求的远程站点。这是因为,当远程站点有控制要求且控制点连接完好时,进行远程下载,因控制器初始化所有输出为0,引起现场控制设备产生相应动作,若无操作员在场,可能会造成损失。
  以往方法,大多是通过虚拟串口的方式,来通过GPRS进行远程下载。虚拟串口程序,大部分都存在使用不稳定,数据监视不方便。最关键的是,虚拟串口数据的接收及发送的延时时间无法改变,从而就不可避免的会出现在下载时数据包被拆分,造成下位机无法解析,而没有应答,引起通讯失败。
  本文的方法,采用数据通过实时实际串口转发,再通过监视串口数据的接收以及发送情况,了解数据包长度和延时时间的关系,最后调节数据包的长度以及串口接收数据的延时时间来使其达到一个平衡,保证数据包不被拆分,解决由于数据包被拆分而引起的通讯失败和数据传输错误等问题。

  二、下载准备(以RTU为例,PLC例同)

  计算机一台(带2个串口)或者两台(每台带一个串口),
  RTU一台,
  DTU一台(深圳宏电产品为例),
  RS232连接线一根,
  可以拨号上网的电话线一根或设置成拨号方式的DTU一台。

  三、下载方法

  步骤1:连接
  方式1(下载计算机带有2个串口):根据各自使用的DTU厂家提供的方式,组建好GPRS网络,确保从站DTU与中心通讯正常。在此,我采用计算机拨号上网,DTU指向拨号上网所分配的IP地址,即指向中心,来进行从站DTU与中心站进行数据交换。DTU通过其自带的串口连接线和RTU的COM口相连。
  用RS232连接线将计算机的两个串口连接在一起。如下图所示:

  方式2(采用2台计算机,各带1个串口):根据各自使用的DTU厂家提供的方式,组建好GPRS网络,确保从站DTU与中心通讯正常。在此,我采用1 台计算机拨号上网,DTU指向拨号上网所分配的IP地址,即指向中心,来进行从站DTU与中心站进行数据交换。DTU通过其自带的串口连接线和RTU的 COM口相连。
  用RS232连接线将拨号计算机(PC1)的串口和下载计算机(PC2)的串口连接在一起。如下图所示:



  步骤2:中心站软件设置
  连接完毕,确保GPRS通讯正常。
  在中心站计算机上,采用深圳宏电的串口转发程序进行配置。下图为串口转发程序主界面。


  选择『控制』菜单下的『启动服务』选项,或点击第一个快捷图标 ,则其无线数据服务中心服务开启。
  在右下的信息显示框中,会显示中心站的IP地址,以及检测到的DTU是否在线的信息。
  在左上的信息显示框中的"在线DTU"项的下面会显示中心站检测到的在线的DTU的号码。
  注意:若无线数据中心没有检测到有DTU在线,则应重新设置DTU,直至无线据中心检测到DTU在线。

  步骤3:建立连接
  无线数据中心检测到DTU在线,在此基础上,通过软件设置将中心接收到的数据转发给计算机上的实际串口(如COM1)。
  方法:选择『控制』菜单下的『建立连接』选项,弹出"建立连接"对话框:

  在『转发端口』单选框中,选择『本地串口』。在『本地串口』下拉框中选中计算机上实际存在的串口,如COM1。在弹出的『波特率』、『数据位』等下拉框中,不作选择,默认其缺省值。
  在『DTU』复选框的『DTU号码(11位)』下拉框中,选择将要对他对应的RTU进行程序下载的DTU的号码,其他的设置默认其缺省值。点击『创建』按钮,至此,建立连接完成。

  步骤4:下载
  连接已建立,选择『控制』菜单下的『启动连接』选项,将已建立的连接启动。则中心将接收到的RTU的信息转发到了计算机的实际串口COM1,实际串口 COM1又通过RS232连接线将数据传输到COM2(或将数据转发到通过COM1连接的另一台计算机的COM口上)。
  选择无线服务中心右下方的『数据监控』,可以监视到从COM口转到中心,以及中心接收到从站DTU再转到COM口的数据。
  无线服务中心右上的显示框中的"COM à DTU"列,显示的是无线服务中心将COM口数据转发到DTU的字节数,"DTU à COM"列,显示的是无线服务中心将DTU返回的数据转发到COM口的字节数。
  这时,假若连接方式为1,则我们可以通过在ELadder中将PC机串口选择COM2来对RTU进行远程下载。操作方法等同于通过COM2口直接和RTU相连时的操作方法。具体操作可参见《ELadder 2.0 使用手册》。
  假若连接方式为2,则我们可以通过在ELadder中将PC机串口选择COM1来对RTU进行远程下载。操作方法等同于通过COM1口直接和RTU相连时的操作方法。具体操作可参见《ELadder 2.0 使用手册》。

  注意:在下载C程序时,数据包的长度不应该超过180。

勇者_1

  • 精华:0帖
  • 求助:0帖
  • 帖子:16帖 | 2756回
  • 年度积分:442
  • 历史总积分:30819
  • 注册:2007年7月13日
发表于:2012-11-13 07:18:42
5楼
Modbus rtu 通信协议串口通讯动态链接库DLL(以下简称DLL),是为满足工业通信需要, 针对工业领域要求上位机对PLC、工业仪表通讯实时采集与控制的组态编程而设计。 本DLL 是采用Delphi 语言开发的标准串口通讯库,具有以下特点: 1)、遵循 modbus rtu 串口通讯协议(施耐德、西门子、台达、永宏等品牌 PLC 及各类工业仪表等支持本协议); 2)、实时性、可靠性好,通用性强; 3)、适用于多PLC 联网和上位机通信,满足多方面的需要(联网时可采用485 总线式); 4)、函数接口功能全,操作简单,支持modbus 的大部分读写功能函数; 5)、附加实用转换与读取函数,易于快速开发(VC 等非RAD 开发环境的开发); 6)、支持USB、PC 扩展卡等扩展串口号; 7)、支持多种操作系统win9x/win2000/winXP(标注Win32 DLL); 8)、可在多种编程环境下使用,例如VB、VC、Delphi 等开发环境。 9)、支持modbus rtu 标准的功能代码01、02、03、04、05、06、15、16 且对相关功能代码的读取和写如做了一些扩充更加符合工业自动化领域的工控软件的开发,是广大工控工程师的必备工具软件。 二、modbus rtu 通讯协议简介 Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网) 和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集 中监控。此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请 求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共 格式。当在一Modbus 网络上通信时,此协议决定了每个控制器须要知道它们的设备地址,识别按地址发来的消息,决定 要产生何种行动。如果需要回应,控制器将生成反馈信息并用 Modbus 协议发出。在其它网络上,包含了Modbus 协议的消 息转换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。 1、在Modbus 网络上转输 标准的Modbus 口是使用一RS-232C 兼容串行接口,它定义了连接口的针脚、电缆、信号位、传输波特率、奇偶校验。控制 器能直接或经由Modem 组网。控制器通信使用主—从技术,即仅一设备(主设备)能初始化传输(查询)。其它设备(从设备) 根据主设备查询提供的数据作出相应反应。典型的主设备:主机和可编程仪表。典型的从设备:可编程控制器。主设备 可单独和从设备通信,也能以广播方式和所有从设备通信。如果单独通信,从设备返回一消息作为回应,如果是以广播 方式查询的,则不作任何回应。Modbus 协议建立了主设备查询的格式:设备(或广播)地址、 www.plcworld.cn 功能代码、所有要发送的数 据、一错误检测域。从设备回应消息也由 Modbus 协议构成,包括确认要行动的域、任何要返回的数据、和一错误检测域。 如果在消息接收过程中发生一错误,或从设备不能执行其命令,从设备将建立一错误消息并把它作为回应发送出去。 2、在其它类型网络上转输 在其它网络上,控制器使用对等技术通信,故任何控制都能初始和其它控制器的通信。这样在单独的通信过程中,控制 器既可作为主设备也可作为从设备。提供的多个内部通道可允许同时发生的传输进程。在消息位,Modbus 协议仍提供了 主—从原则,尽管网络通信方法是“对等”。如果一控制器发送一消息,它只是作为主设备,并期望从从设备得到回应。 同样,当控制器接收到一消息,它将建立一从设备回应格式并返回给发送的控制器。 3、查询—回应周期 (1)、查询 查询消息中的功能代码告之被选中的从设备要执行何种功能。数据段包含了从设备要执行功能的任何附加信息。例如功能代码03 是要求从设备读保持寄存器并返回它们的内容。数据段必须包含要告之从设备的信息:从何寄存器开始读及要读的寄存器数量。错误检测域为从设备提供了一种验证消息内容是否正确的方法。 (2)、回应 如果从设备产生一正常的回应,在回应消息中的功能代码是在查询消息中的功能代码的回应。数据段包括了从设备收集的数据:象寄存器值或状态。如果有错误发生,功能代码将被修改以用于指出回应消息是错误的,同时数据段包含了描述此错误信息的代码。错误检测域允许主设备确认消息内容是否可用。 3、两种传输方式 控制器能设置为两种传输模式(ASCII 或RTU)中的任何一种在标准的Modbus 网络通信。

yanwen0227

  • 精华:2帖
  • 求助:50帖
  • 帖子:578帖 | 9385回
  • 年度积分:0
  • 历史总积分:0
  • 注册:1900年1月01日
发表于:2012-11-26 09:56:47
6楼

学习了,不错的好资料!

sdzhibohui

  • 精华:5帖
  • 求助:46帖
  • 帖子:1765帖 | 7713回
  • 年度积分:0
  • 历史总积分:44752
  • 注册:2011年12月19日
发表于:2012-11-26 12:20:43
7楼
S7-1200 MODBUS RTU 的通信方式

S7-1200 作为 MODBUS RTU 主站的通信方式是由 DATA_ADDR 和 MODE 参数来选
择 Modbus 功能类型的。
DATA_ADDR(从站中的起始 Modbus 地址): 指定要在 Modbus 从站中访问的数
据的起始地址。MB.master使用 MODE 输入而非功能代码输入。 MODE 和 Modbus 地
址范围一起确定实际 Modbus 消息中使用的功能代码。
下表列出了 MB_MASTER 参数 MODEModbus 功能代码和 Modbus 地址范围之间

的对应关系。


3: MB.master MODBUS 功能

5.S7-1200 与 PAC3200 进行 MODBUS RTU 的通信组态

我们通过一个实例来介绍如何在 Step7 Basic V10.5 中组态 S7-1214C 和 PAC3200

的 MODBUS RTU 通信。

在硬件配置中,添加 CPU1214C 和通信模块 CM1241 RS485 模块,如图 2 所示。


PAC3200 参数设置
 
在SENTRON PAC 电力监测设备的主菜单中,调用“设置”>“RS485 模块”,出现下
面的设置画面:
1. 地址的设置范围:1-247。本例中设为 8。
2. 波特率的设置范围:4800,9600,19200,38400。本例中设为 38400。
3. 设置外部通信的数据位、奇偶校验位及停止位:
? 8E1=8 个数据位,奇偶校验位为even, 1 个停止位
 
? 8O1=8 个数据位,奇偶校验位为odd,
? 8N2=8 个数据位,无奇偶校验位,
? 8N1=8 个数据位,无奇偶校验位,
 
1 个停止位
2 个停止位
1 个停止位
 
本例中根据S7-1200 MODBUSmaster的参数设置为 8N1。
4. 协议的设置:可选项为:SEABUS,MODBUS RTU。
本例中设为 MODBUS RTU。
5.响应时间的设置:注意与波特率的设置相匹配,本例中设为 10mS。
6.S71200 与 PAC3200 的 MODBUS RTU 通信原理与编程的实现
6. 1 S7 1200 PLC 与 PAC3200 通过 MODBUS RTU 通信的基本原理
S7 1200 提供了专用的 MODBUS 库进行 MODBUS 通信,如下图所示

西门子 PLC S7-1200 的模块 CM1241 RS232 和 CM1241 RS485 都可以实现 MODBUS
RTU 的通信,本例中采用 CM1241 RS485 模块来实现与仪表 PAC3200 的 MODBUS RTU
的通信。
S7-1200 的 MODBUS RTU 通信的基本原理是:
首先 S7-1200 PLC 的程序调用一次 MODBUS 库中的功能块 MB_COMM_LOAD 来组态
CM1241 RS232 和 CM1241 RS485 模块上的端口,对端口的参数进行配置。
其次调用 MODBUS 库中的功能块 MB.master或者 MB_SLAVE 作为 MODBUS 主站
或者从站与支持 MODBUS 协议的设备进行通信。
S7-1200 PLC 作为 MODUBUS 主站 与 PAC3200 进行 MODBUS RTU 通信的控制原理
如下图所示

S7-1200 PLC 还可以作为 MODBUS 子站与作为 MODBUS 主站之间的 PLC 进行
MODBUS RTU 通信,其控制原理如下图所示:

每个 S7-1200 CPU 最多可带 3 个通信模块,而每个 CM1241 RS485 通信模块理论上最

多支持 247 MODBUS 子站。但是在实际应用时需要考虑 CPU 的性能以及轮循 MODBUS

子站的时间

6. 2 S7 1200 PLC 与 PAC3200 通过 MODBUS RTU 通信的编程

1.MODBUS RTU 通信接口参数的编程

MB_COMM_LOAD 功能块用于组态点对点 (PtP, Point-to-Point) CM 1241RS485 或CM 1241 RS232 模块上的端口,以进行 Modbus RTU 协议通信。

程序开始运行时,调用一次 MB_COMM_LOAD 功能块,来实现对 MODBUS RTU 模块的初始化组态。MB_COMM_LOAD 执行一次的编程方式采用如下图所示时钟位 M10.0 来完成。


MB_COMM_LOAD 功能块的编程如下图所示。

   PORT:指的是通过哪个通信模块进行 MODBUS RTU 通信。

BAUD:指的是和 MODBUS 子站进行通信的速率。

通信端口的波特率。取值范围为 300,600,1200,2400,4800,9600,19200,

38400,57600,76800,115200。

注意:仪表 PAC3200 的波特率的设置范围:4800,9600,19200,38400。因此上 S7-

1200 的波特率的设置一定要和仪表 PAC3200 的波特率的设置相一致。

MB_DB:对 MB.master或 MB_SLAVE 指令所使用的背景数据块的引用。 在用户程序中放置

MB_SLAVE 或 MB.master后,DB标识符会出现在 MB_DB 功能框连接的助手下拉列表

中。如“MB_MASTER_DB”或“MB_SLAVE_DB”。

STATUS:端口状态代码。具体含义如下表所示。

sdzhibohui

  • 精华:5帖
  • 求助:46帖
  • 帖子:1765帖 | 7713回
  • 年度积分:0
  • 历史总积分:44752
  • 注册:2011年12月19日
发表于:2012-11-26 12:38:09
8楼
未完  待续  占个位

wallboard

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 2回
  • 年度积分:0
  • 历史总积分:22
  • 注册:2012年11月27日
发表于:2012-12-03 08:37:21
9楼

分享一个plc和pc串口通信的例子

 

由于具有编程方法简单易学、功能强、性能价格比高、可靠性高、抗干扰能力强、体积小、能耗低、硬件配套齐全、设计调试安装维护方便等突出优点,可编程逻辑控制器(PLC)已经广泛地应用在发达国家所有的工业部门,主要应用在数字逻辑控制、运动控制、闭环过程控制、数据处理和联网通信等方面。在联网通信方面,PLC 与其他智能控制设备一起,可以组成“集中管理、分散控制”的分布式控制系统。在这种工业控制系统中,为了避免通信各方争用通信线路,PC 与PLC 之间的通信一般采用主从方式,通常采用计算机(PC)作为上位机负责完成数据分析、处理和存储、设备状态显示和打印输出等功能以实现对分布在工业现场的被控制系统进行集中的实时监测与控制;PLC 作为下位机使用,承担执行上位机的输出指令、现场数据采集和设备运转状态识别等任务。本文研究了在自由端口模式下PC 与S7-200 型PLC 之间的通信,并采用Visual Basic 编程来实现上位机与下位机之间的通信。

 

PLC 与PC 的电缆连接和电缆的切换时间
S7-200 的通信接口为RS-485,PC 可以采用RS-232 通信接口,RS-232/PPI 多主站电缆可以连接PC 与S7-200型PLC,实现S7-200 CPU 与PC 的通信。由于使用RS-232/PPI 电缆,因此在S7-200 CPU 的用户程序中应考虑电缆的切换时间,切换时间因波特率的不同而不同,例如,如果采用9600bit/s 的波特率,则电缆的切换时间为2ms,电缆上DIP 开关设置为010,如果采用19200bit/s 的波特率,则电缆的切换时间为1ms。S7-200 CPU接收到RS-232 设备的请求报文后,到它发送响应报文的延迟时间必须大于电缆的切换时间。在程序中,可以用中断实现切换延时。同理,如果S7-200 CPU 发送请求报文,在接收到RS-232 设备的响应报文后,S7-200 CPU下一次发出报文的延时时间也必须大于电缆的切换时间。在中断程序中,必须考虑电缆的切换时间,例如当采用19200bit/s 的波特率时,通过定时5ms 来提供PPI 电缆接收/发送模式的切换时间,用 MOVB 5,SMB34 来实现定时5ms。

 

通信数据单元的结构

在自由口模式下,通信协议是由用户自己定义的,由梯形图程序控制。PC 与PLC 通信的基本单元为“帧”。PC 通过串口将指令数据帧发送到PLC 的PORT0(或PORT1)口,PLC 通过RCV 指令或字符中断来控制接收指令数据帧,然后对指令数据帧进行译码,译码调用相应的读/写子程序实现指令要求的相关操作,比如启动或停止等,并返回指令执行的状态信息。
需要指定PLC 的接收缓冲区、译码区、发送缓冲区和用于存放BCC 码等的缓冲区。当PC 发指令时,指令数据写入指定的目标寄存器。当PLC 返回信息时,可以从数据区读取事先写入的数据。此外我们必须规定数据帧的结构,包括PC 的指令格式和PLC 的反馈信息格式,PC 与PLC 在发送和接收数据时应采用相同的数据帧格式。
例如,PC 的指令格式为:起始字符+指令类型(读/写)+目标PLC 站地址+目标寄存器地址+读/写字节数M+要写入的数据+BCC 校验码+结束字符,每个部分的字节长度是固定。起始字符标志着指令的开始,用ASCII 码小写字符表示,结束字符标志着指令的结束,用ASCII 码大写字符表示,比如分别用"j"和"J",各占1 个字节;指令类型分写操作和读操作2 种,分别向PLC 写入和读出数据;在PLC 内部可以用4 个字节来表示一个寄存器的地址,由于采用ASCII 码表示,所以需要8 个字节;读/写字节数M,对于读操作,一般是读回从目标寄存器开始的连续的固定字节数(比如8 个)的数据,对于写操作,需要由PC 指定,但不超过事先指定的最大字节数;要写入的数据区必须填满,但只有前M 个字节的数据会被写入目标寄存器;BCC 校验码用于判断传输的正确性,BCC 校验码的方法就是将要传送的字符串(从指令类型到要写入的数据的最后)的ASCII 码以字节为单位作异
或和,并将此异或和作为指令的一部分传送出去。
PLC 的反馈信息格式为:起始字符+状态信息+数据区+BCC 校验码+结束字符,其中状态信息为指令执行的状态信息,用来说明读/写是否正确、BCC 码错误、指令格式错误。
通信数据帧中,一般要使用ASCII 码。如果直接采用数据原来的格式传输,就可能与指令中的控制字发生混淆。对于本例,结束字符为"J",ASCII 码为4AH,如果传输的十进制数据为74,表示为十六进制也是4AH,PLC 会因为接收到了数据中的4AH 而停止接收,这样PLC 接收到的指令将是一个不完整的非法指令,很可能造成PLC 的误动作。
为了避免这种情况的发生,我们可以对要传输的每个字节的数据进行ASCII 编码,得到2 个字节的ASCII编码。例如:对数据4AH 进行ASCII 编码,得到2 个字节:34H 和41H。因为要传输的数据为实际的十进制数,在PC 中表示为十六进制,任意的1 个字节可以用0~9,A~F 中的2 个表示,余下的字符作为控制字符使用,控制字符直接用ASCII 码表示,而组成数据的0~9,A~F 用ASCII 码表示,这样就可以避免上述情况的发生。

 

 

PLC 程序及其执行过程
在自由端口模式下,通信协议完全可以由用户程序控制。只有当CPU 处于RUN 模式时,才能使用自由端口模式,这可以通过特殊存储器位SM0.7 来控制自由端口模式的进入。
PLC 程序主要有主程序、初始化子程序、接收完成中断程序、校验子程序、写操作子程序、读操作子程序和发送完成中断程序等组成。主程序负责控制被控设备的运转,通过调用PLC 的初始化子程序,对端口及RCV接收指令进行初始化和BCC 码寄存器清零。以下是初始化子程序的一段和相应的注释:
LD SM0.0 //该位总是ON
MOVB 9, SMB30 //用通信口0 "9600,N,8,1"

 MOVB 16#EC, SMB87 //允许接收、检测起始和结束字符、超时检测
MOVB 106, SMB88 //设置起始字符为"j",ASCII 码值为106
MOVB 74, SMB89 //设置结束字符为"J"
MOVB +800, SMW92 //设置接收超时为800 ms
MOVB 35, SMB94 //设置接收的最大字符数目为35,根据帧的长度来定<255
R SM87.2, 1 //设置若超过SMW92 的时间则结束接收
ATCH RCVok, 23 //口0 接收完成产生中断,调用RCVok
ATCH XMTok, 9 //口0 发送完成产生中断,调用XMTok
ENI //中断用户允许
MOVB 2, VB197 //本机站地址为2,装入寄存器VB197,用于判断接收初始化完成后,运行RCV 指令使端口处于接收状态。RCV 以"j"开头"J"结尾的指令数据保存到接收缓冲区,并产生接收完成中断。接收完成中断程序负责将收到的ASCII 编码还原成原来的数据存入译码区,并调用校验子程序计算BCC 校验码,如果BCC 码不一致,则向PC 反馈BCC 码错误、指令格式错误信息。
触发写操作子程序需同时依次满足指令中的站地址与本机站地址相符、指令类型为写指令和BCC 检验码正确,写操作子程序负责将指令中的ASCII 码还原成数据写入目标寄存器,并向PC 发送表示写入正确的反馈信息。触发读操作子程序需同时依次满足指令中的站地址与本机站地址相符、指令类型为读指令和BCC 检验码正确,读操作子程序根据指令的要求,将数据转换成十六进制ASCII 码,并写入发送缓冲区、调用校验子程序计算BCC 校验码、使用XMT 指令向PC 发送反馈信息。写操作子程序和读操作子程序中必须禁止RCV,避免在处理过程中继续接收数据而改变缓冲区。
完成ASCII 码与十六进制码互相转换的指令为ATH 和HTA,使用实例为:
ATH VB103, VB134, 2 //将接收缓冲区的VB103 起2 个字节的ASCII 转换成十六进制存入译码区的VB134;HTA *VD135, VB156, 16 //将*VD135 指针指向目标寄存器的数据连续转换成16 个字节ASCII 码,从发送缓冲区的VB156 连续存入。
一般地,PLC 收到一条指令后,应该向PC 发送反馈信息,PC 根据反馈信息采取相应的措施,例如PLC 接收错误,PC 必须重新发送指令。发送反馈信息完成时,会产生发送完成中断,调用发送完成中断程序用来处理发送完成一些中断事件,包括复位标志位;允许RCV;寄存器清零;重新装入地址指针等。

 

用VB 实现指令的发送和数据的接收
Visual Basic 是可视化、面向对象的程序设计语言,具有结构化的事件驱动编程模式、编程效率高等特点。利用VB6.0 提供的串行通信控件MSComm,只需要设置和监视该控件的属性和事件,就可以方便快捷地实现串行
通信。其中主要的属性有:
CommPort:设置并返回通信端口号。
Settings:以字符串形式设置并返回波特率、奇偶校验、数据位和停止位。
PortOpen:设置并返回通信端口的状态,设置True 则打开,设置False 则关闭。
此外还有Input、Output、InputMode、InBufferCount、OutBufferCount、InputLen、RThreshold、CommEvent等属性。下面代码是串口通信参数的初始化:
With MSComm1 ‘串行通信控件名称为MSComm1
.CommPort = 1 ‘根据具体情况选择串口号
.Settings = "9600,n,8,1" ‘对应的PLC 程序为MOVB 9, SMB30
.InputLen = 0 ‘读出接收缓冲区中的所有内容
.PortOpen = True ‘打开串口1
.InputMode = comInputModeBinary ‘以二进制格式读取接收缓冲区
.RThreshold = 1 ‘接收到大于等于1 个字符就会产生接收事件
.InBufferCount = 0 ‘清空接收缓冲区
.OutBufferCount = 0 ‘清空发送缓冲区
End With
发送程序负责向某地址编号的PLC 发送指令,例如采用前面所述的指令格式,即:起始字符+指令类型(读/写)+目标PLC 站地址+目标寄存器地址+读/写字节数M+要写入的数据+BCC 校验码+结束字符,由程序生成指令数据帧,包括计算数据的BCC 码和数据转换为ASCII 码,以字符串形式存放于数组变量,不妨假设为SentB 中,最后用语MSComm1.Output = SentB 实现报文的发送。
PLC 只有在接收到PC 发送的指令后才会发送回反馈信息,串行通信控件接收到大于等于1 个字符就会产生接收事件,触发串行通信控件的OnComm 事件,只要在该事件子程序 Private Sub MSComm1_OnComm()中编写接收数据的代码即可。接收数据的程序根据反馈信息中起始字符和结束字符判断接收的开始和结束,将接收到的ASCII 码还原成数据,计算BCC 码,处理数据等工作。
计算机的VB编程的关键之处在于,保证与PLC程序完全一致地采用事先规定好的指令帧格式和反馈帧格式,特别是BCC 码的计算方法和所计算的数据段要完全一致。

_gongkong

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 3回
  • 年度积分:0
  • 历史总积分:33
  • 注册:2012年2月09日
发表于:2012-12-03 21:50:48
10楼
RTU、PLC在串口编程方面表现的不一样,RTU主要是远程测控为主,对串口编程能力要求强一些,支持的也多些,可以通过选择串口自定义协议进行编程,与现场仪表、设备通信。串口自定义主要先了解对方设备的通信格式、通信参数。特别要注意的是浮点数的处理。还有通信参数的设定,如果同时通信2台不同协议、通信参数的设备,对RTU要求就比较高了,串口必须支持在线更改参数。北京安控生产的RTU都支持串口自定义编程,而且支持在线更改串口参数。

北京的海

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 127回
  • 年度积分:0
  • 历史总积分:167
  • 注册:2011年5月27日
发表于:2012-12-04 20:40:33
11楼

俺公司曾经用过安控的产品做过一个石油相关的项目,过去很长时间啦!做过的项目中通讯方式大都是直接用,很少自己编写,很多年前用单片机的时候曾经还自己来编写通讯协议,现在PLC大都是直接调用驱动,接上线就能通讯。

编写通讯协议主要主要发送数据位数和接收数据位数,波特率,校验位,长距离传输还要注意信号的衰减,短距离传输用电压信号传输即可,长距离传输很容易有干扰和信号衰减问题。


热门招聘
相关主题

官方公众号

智造工程师