ModBUS协议通讯的应用

发布者:数据之翼最新更新时间:2012-06-09 来源: 中国传动网关键字:ModBUS协议  RTU模式  CRC校验 手机看文章 扫描二维码
随时随地手机看文章

引言

    在燃气蓄热式窑炉控制系统中,不仅需要将温度、压力、流量等模拟参数进行采集、计算控制输出至执行器,同时还应将火焰状态、电磁阀状态、换相阀状态进行采集,随时控制点火器点火,并进行周期性换相,换相周期会根据温度的不同而变化。面对众多参量的采集控制,需要建立时变系统和非线性系统的状态空间表达式进行复杂的多相关变量的运算,得到稳定输出以控制相关变量。事实上,取得大量数据,建立相应数据库,进行数据分析,单靠低端的数字控制设备难以完成。通常的做法是信号的数据采集、滤波、简单PID运算、输出量、及输出量的互锁由低端控制器完成。为了完成上述功能,我们采用ABB公司生产的PLC,配置如下:

       名称               数量                    描述

     07KT51               1块                     50CPU,8DI,6DO

     XM06B5              2块                     Extension I/O,4AI,2AO

     XK08F1              1块                     Extension I/O,4DI,6DO

    PLC软件采用AC31 SOFTWARE,上位机程序用VB编制,实现与上位工控机通讯的过程中需要使用MODBUS协议。本文重点介绍其通讯实现的过程。

一、 MODBUS简介

    MODBUS协议是应用于电子控制器的一种通讯语言。利用这个协议,控制器相互之间(例如485、232C等),控制器通过网络(例如以太网)和其他设备之间进行通讯。它定义了一种控制器能认识使用的消息结构,而不管它们是通过何种网络实现;描述的是控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦错并记录;制定了消息域格局和内容的公共格式。

    MODBUS通讯实现有两种传输模式(ASCII或RTU),ABB公司的50系列PLC产品采用的是RTU(远程终端单元)模式,在消息中的每个8Bit字节包含两个4Bit的十六进制字符。这种方式的主要优点是:在同样的波特率下,可比ASCII方式传送更多的数据。

1、代码系统:

    ·   8位二进制,十六进制数0...9,A...F

    ·   消息中的每个8位域都是一个两个十六进制字符组成每个字节的位

    ·   1个起始位

    ·   8个数据位,最小的有效位先发送

    ·   1个奇偶校验位,无校验则无

    ·   1个停止位(有校验时),2个Bit(无校验时)

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

2、基于RS485的RTU模式MODBUS通讯格式为:


    它定义了在这些网络上连续传输的消息段的每一位,以及决定怎样将信息打包成消息域和如何解码。

3、其查询回应周见下图:


    (1)查询    查询消息中的功能代码告之被选中的从设备要执行何种功能。数据段包含了从设备要执行功能的任何附加信息。例如功能代码03是要求从设备读保持寄存器并返回它们的内容。数据段必须包含要告之从设备的信息:从何寄存器开始读及要读的寄存器数量。错误检测域为从设备提供了一种验证消息内容是否正确的方法。[page]

    (2)回应    如果从设备产生一正常的回应,在回应消息中的功能代码是在查询消息中的功能代码的回应。数据段包括了从设备收集的数据:象寄存器值或状态。如果有错误发生,功能代码将被修改以用于指出回应消息是错误的,同时数据段包含了描述此错误信息的代码。错误检测域允许主设备确认消息内容是否可用。

二、通讯的实现:

1、PLC端设置:

    07KT51在出厂时拥有默认设置:该中心单元为从设备,波特率为19200,1位停止位,8位数据位,无校验位。有关数据采集的端口、传输变量的物理地址的计算,功能代码的涵义,校验等等,在AC31说明书上已有了详尽的介绍,在此不复赘述。事实上,由于AC31对MODBUS的封装,使我们的通讯工作变的异常简单,有了通讯参数,调用通讯功能模块,无须进行通讯过程的代码描述。下面是一个取地址的例子:

    定义一个输出量O 62.15和内存变量M 232.01的地址为:

    O 62.15=4096+(16*62)+15=5103

    M 232.01=8192+(16*232)+1=11905

    当然,根据AC31提供的地址表进行推算,使过程显得更容易。

2、  工控机的设置:

    (1)、进行端口的配置。端口采用MOXA公司生产的Transio 53智能型RS232与RS422/485双向转换器,充分利用其传输速率: 50 bps~ 921.6 Kps带宽,内建终端电阻的特性,保证长达1000米的通讯不受干扰。特别是当 2 个信号在 RS-422/485 端短接在一起时,具有电流过载保护功能;浪涌保护:(25 KV ESD ),光电隔离(2 KV)等特性,为系统长期可靠运行提供了硬件保障。软件利用VB 实现,在VB中通过Timer控件定时引用Mscomm控件实现串口通讯,利用窗体加载事件对其初始化:

Private Sub From_Load( )

        Timer1.Enabled=True

        Timer1.Interval=500                              ‘定时传输间隔为500毫秒

        Mscomm1.Commport=1                        ‘通讯串口选择Com1

        Mscomm1.Settings=”19200,n,8,1”        ‘通讯参数设置

        Mscomm1.OutBufferSize=0                 ‘清除缓冲区

        Mscomm1.InputMod=1                         ‘采用二进制通讯

End Sub

(2)、Modbus的CRC校验:

    使用RTU模式,消息包括了一基于CRC方法的错误检测域。 CRC域是两个字节,包含一16位的二进制值,它由传输设备计算后加入到消息中。接收设备重新计算收到消息的CRC,并与接收到的CRC域中的值比较,如果两值不同,则有误。

    CRC校验运算需要对位操作,根据Modbus的相关介绍用VC++做一个动态连接库函数checkCRC。

CRC简单函数如下:

unsigned short CRC16(puchMsg, usDataLen)

unsigned char *puchMsg ; /* 要进行CRC校验的消息 */

unsigned short usDataLen ; /* 消息中字节数 */

unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */

unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */

unsigned uIndex ; /* CRC循环中的索引 */

while (usDataLen——) /* 传输消息缓冲区 */

uIndex = uchCRCHi ︿ *puchMsg++ ; /* 计算CRC */

uchCRCHi = uchCRCLo ︿ auchCRCHi[uIndex} ;

uchCRCLo = auchCRCLo[uIndex] ;

return (uchCRCHi << 8 | uchCRCLo) ;

/* CRC 高位字节值表 */

static unsigned char auchCRCHi[] = {

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40

} ; [page]

/* CRC低位字节值表*/

static char auchCRCLo[] = {

0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,

0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,

0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,

0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,

0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,

0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,

0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,

0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,

0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,

0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,

0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,

0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,

0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,

0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,

0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,

0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,

0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,

0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,

0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,

0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,

0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,

0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,

0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,

0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,

0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,

0x43, 0x83, 0x41, 0x81, 0x80, 0x40

} ; 


(3)、Modbus消息帧:

    传输设备将Modbus消息转为有起点和终点的帧,这就允许接收的设备在消息起始处开始工作,读地址分配信息,判断哪一个变量被选中,判知何时信息已完成。部分消息也能侦测到错误并且能设置为返回结果。使用RTU模式,消息发送至少要以3.5个字符时间的停顿间隔开始。传输的第一个域是变量地址。可以使用的传输字符是十六进制的0...9,A...F。网络设备不断侦测网络总线,包括停顿间隔时间内。当第一个域(地址域)接收到,每个设备都进行解码以判断是否发往自己的。在最后一个传输字符之后,一个至少3.5个字符时间的停顿标定了消息的结束。一个新的消息可在此停顿后开始。

    整个消息帧必须作为一连续的流转输。如果在帧完成之前有超过1.5个字符时间的停顿时间,接收设备将刷新不完整的消息并假定下一字节是一个新消息的地址域。同样地,如果一个新消息在小于3.5个字符时间内接着前个消息开始,接收的设备将认为它是前一消息的延续。这将导致一个错误,因为在最后的CRC域的值不可能是正确的。所以在通讯端口初始化时,Timer1定时间隔设置为500ms(根据PLC传输字的延迟时间决定)。

(4)、代码实现过程:

    在公共模块做下面函数声明:

    Declare Function W_checkCRC Lib "checkCRC.dll" (ByVal data0 As String,_ & ByVal data1 As Integer ) As String

    以下是设置/读取开关量状态:

    Private Sub Timer1_Timer()

    Dim inbyte() As Byte, outbyte() As Byte

    Dim  ReturnB As Boolean

       If ReturnB Then

        ReturnB = False

        If MSComm1.InBufferCount > 0 Then

            inbyte = MSComm1.Input

            n = UBound(inbyte)

            If n >= 1 and inbyte(3)>”03” Then ‘判断是否有有数据读取及功能代码是否含有错误

                If inbyte(5) and 1 then ‘开关量位处理

                If inbyte(5) and 2 then ‘开关量位处理 

                If inbyte(5) and 4 then ‘开关量位处理

                  ……

            End If

        End If

       Else

        ‘发送主设备查询消息

        ReDim outbyte(6)

        outbyte(0) = addr1      ‘设备地址

        outbyte(1) = option        ‘功能代码

        outbyte(2) = 1              ‘数据量

        outbyte(3) = data1         ‘数据

    ‘以下是校验码

    outbyte(4) = left(W_checkCRC(add1 & add2 & option & “1” _ &  & data1,2)

outbyte(5) = Mid(W_checkCRC(add1 & add2 & option & “1” _&  & data1,3,2)

        MSComm1.InBufferCount = 0

        MSComm1.Output = outbyte

    End If

End Sub

三、结束语

    ModBus协议在工业控制系统中已经应用十分广泛,但在多数系统中使用的是由专业供应商提供的组态软件,有时候使用组态软件提供的数据格式并不能达到要求,直接使用ModBus协议进行数据通讯是十分有用的。

参考书目:

    1、AC31 SOFTWARE  www.abb.com/lowvoltage
    2、《VB开发人员指南》  Eric Brierley 1999-01  机械工业出版社

关键字:ModBUS协议  RTU模式  CRC校验 引用地址:ModBUS协议通讯的应用

上一篇:CAN总线及其在UPS网络监控系统中的应用
下一篇:现场总线在联动线系统中的应用

推荐阅读最新更新时间:2024-05-02 22:06

基于STM32的CRC校验说明
///***************************************************************************** //下面是test.c里面的函数 ///***************************************************************************** ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[单片机]
基于STM32的<font color='red'>CRC</font><font color='red'>校验</font>说明
鼎实主站网关在东北大乙烯中的应用
随着经济的发展,中国将是全球炼油和石化产能增长最快的地区之一,即将成为世界上最大的石化市场。目前,由于国内石化行业难以满足市场经济和社会发展的需要,主要矛盾由过去的总体数量不足转变为总体数量和质量不足并存,随着时间的推移,质量不足的矛盾会逐渐上升为主要矛盾(北京的雾霭天气可见端倪), 因此结构调整是当前中国石化的重要任务。为此石化企业结构调整必须加快技术改造步伐。乙烯项目的建设应尽量顺应现有自动化技术发展的趋势,使用主流的控制系统,从而能够节省建设投资,缩短施工周期。                                       图1 工厂外景                                  
[嵌入式]
基于AVR128的简单Modbus协议实现
Modbus通讯协议是由Modicon公司在1979年开发的,应用于工业现场控制的总线协议。Modbus通讯系统包括带有可编程控制的芯片节点和公共传输线组成,其目的是用于多节点数据的采集和监控。Modbus协议采用主从模式,通讯系统中有一个主机对多个节点从机进行监控,从机节点最多支持247个。每个从机均有自己独立的从机地址,而且改地址能够被主机识别。 能够支持Modbus协议的通讯系统有RS-232,RS-422,RS-485等。同时Modbus协议具有标准、开放、免费、帧格式简单等特点而被广大工程师所采用。 Modbus协议中数据传输采用ASCII和RTU两种模式。其中ASCII传输方式表示的数据通俗易懂,便于和PC机直
[单片机]
基于AVR128的简单<font color='red'>Modbus协议</font>实现
PIC单片机与触摸屏串行通信的MODBUS协议实现
摘要:介绍一种在PIC单片机与触摸屏之间采用Modbus协议实现异步串行通信的方法。简单介绍了Modbus通信协议,给出了硬件电路连接图、程序流程图以及用PIC单片机C语言编写的部分通信程序。实际使用证明该方法数据传输稳定可靠,并提供了良好的人机交互环境。 关键词:触摸屏 PIC单片机 Modbus协议 通信 工控中经常需要观察系统的运行状态或者修改运行参数。触摸屏能够直观、生动地显示运行参数和运行状态,而且通过触摸屏画面可以直接修改系统运行参数,人机交互性好。单片机广泛应用于工控领域中,与触摸屏配合,可组成良好的人机交互环境。触摸屏和单片机通信,需要根据触摸屏采用的通信协议为单片机编写相应的通信程序。Modbus协议是美国M
[单片机]
Modbus协议下单片机与eView触摸屏的通信方法
Modbus协议由于其具有开放性、透明性、成本低、易于开发等特点,已成为当今工业领域通信协议的首选。 本文介绍了一种基于Modbus通信协议的eView触摸屏与常用的51单片机的通信方法。该方法通过C51编程实现Modbus通信,在51系列单片机上具有通用性,有一定的借鉴作用。 工业控制中经常需要观察系统的运行状态或者修改运行参数。触摸屏能够直观、生动地显示运行参数和运行状态,而且通过触摸屏画面可以直接修改系统运行参数,人机交互性好。单片机广泛应用于工控领域中,与触摸屏配合,可组成良好的人机交互环境。 触摸屏与单片机通信,需要根据触摸屏采用的通信协议为单片机编写相应的通信程序。Modbus协议是美国Modicon公司推出的,
[电源管理]
<font color='red'>Modbus协议</font>下单片机与eView触摸屏的通信方法
小广播
最新嵌入式文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved