Modbus ASCII是Modbus的一种消息帧,相比RTU,ASCII的传输是按照字符传的,传输的数据量会比RTU更多,所以数据量大的时候一般使用的RTU,数据量小的时候才会用ASCII,然后ASCII协议帧里面添加了起始和结束,更换了校验算法,下面详细介绍ASCII协议

帧格式

Modbus ASCII 模式下的通讯帧格式如下:

名称长度 (字节)描述
Start1以冒号 : 开头,ASCII 十六进制值为 3A
Address2十六进制节点地址,字符表示
Function2十六进制功能码,字符表示
Datan x 2n 是数据字节数,它取决于功能码
LRC2LRC冗余检验码
End2CR / LF

注:地址、功能、数据和 LRC 都是表示 8 位值 (0-255) 的大写十六进制可读字符对;即:在 Modbus ASCII 中,每个数据字节被分割成表示十六进制值中的两个 ASCII 字符的两个字节。

组件描述字符数ASCII表示
Start消息开始1 CHAR:
Address节点地址(十六进制表示)2 CHARS
Function功能码(十六进制表示)2 CHARS
Data数据(根据功能码变化,十六进制表示)n CHARS
LRC CHECK纵向冗余检验码(LRC)2 CHARS
END消息结束,回车换行2 CHARSCRLF

在 ASCII 模式下,Modbus 消息的每个部分都以特定的字符数和格式出现,如下所示:

:AA BB CC...DD EE<CRLF>
  • : – 消息的开始符号。
  • AA – 节点地址,十六进制表示。
  • BB – 功能码,十六进制表示。
  • CC...DD – 数据字段,根据功能码和需要传输的数据长度变化。
  • EE – LRC 校验码,用于错误检测。
  • <CRLF> – 消息的结束符号,代表回车和换行(Carriage Return Line Feed)。
Modbus ASCII数据报文结构详解插图1

ASCII帧的传输状态

Modbus ASCII数据报文结构详解插图3

上面状态图可以得到的信息:

1)“空闲” 态是没有发送和接收报文要处理的正常状态。

2)每次接收到 “:” 字符表示新的报文的开始。如果在一个报文的接收过程中收到该字符,则当前地报文被认为不完整并被丢弃。而一个新的接收缓冲区被重新分配。

3)检测到帧结束后,完成 LRC 计算和检验。然后,分析地址域以确定帧是否发往此设备,如果不是,则丢弃此帧。 为了减少接收处理时间,地址域可以在一接到就分析,而不需要等到整个帧结束。

ASCII帧的报文传输

由于ASCII报文帧与RTU报文帧有着很大的不同,ASCII报文帧是有起始和结束标识符的,而RTU帧没有这样的标识。所以ASCII报文帧的接收就简单方便多了,也不需要什么t3.5的帧间隔时间。

但是呢,为了保证接收的报文帧连续,还是可以约定字符间的传输时间的。一般认为,报文中的字符时间间隔可以达到一秒,如果超过了这个时间间隔,就认为发生了错误,要废弃掉这一帧报文数据,重新开始接收。

功能码

ASCII 模式下最常用的功能代码与 RTU 模式下的功能代码定义相同。以下是一些基本的功能码及其描述:

访问地址映射地址描述功能R/W
1 ~ 10000address-1Coils01/05/15R/W
10001 ~ 20000address-10001Discrete Inputs02R
30001 ~ 40000address-30001Input Registers04R
40001 ~ 50000address-40001Holding Registers03/06/16R/W

ASCII传输示例

例如,要读取地址 0x20C1 的两个寄存器,需要发送以下 ASCII 消息:

:010420C1000218<CRLF>

请求:

  • : – 消息开始 – 0x3A
  • 01 – 从站地址 – 0x01
  • 04 – 功能码 (读取输入寄存器) – 0x04
  • 20C1 – 要读取的寄存器地址 – 0x20C1
  • 0002 – 要读取的寄存器长度 (必须是 2) – 0x0002
  • 18 – LRC 校验码
  • <CRLF> – 消息结束,回车换行 – 0x0D0A

响应:

:01040400001234B1<CRLF>

响应:

  • : – 消息开始 – 0x3A
  • 01 – 从站地址 – 0x01
  • 04 – 功能码 (读取输入寄存器) – 0x04
  • 04 – 读取数据长度 (4 字节) – 0x04
  • 00001234 – 从 VAR1 读取的值 – 0x00001234
  • B1 – LRC 校验码
  • <CRLF> – 消息结束,回车换行 – 0x0D0A

常用功能码操作

以下是 Modbus 的常用功能码及其请求和响应示例:

功能 01(01H)读线圈

  • 请求:读取从机中线圈的 ON/OFF 状态。
Modbus ASCII数据报文结构详解插图5
  • 响应:线圈状态响应消息被打包为数据字段的每比特表示一个线圈。
Modbus ASCII数据报文结构详解插图7

功能 02(02H)读离散输入

  • 请求:读取从机中离散输入的 ON/OFF 状态。
Modbus ASCII数据报文结构详解插图9
  • 响应:离散输入状态响应消息的构造与线圈状态相同。
Modbus ASCII数据报文结构详解插图11

功能 03(03H)读保持寄存器

  • 请求:读取从机中保持寄存器的二进制内容。
Modbus ASCII数据报文结构详解插图13
  • 响应:保持寄存器数据在每个寄存器中打包为两个字节。
Modbus ASCII数据报文结构详解插图15

功能 04(04H)读输入寄存器

  • 请求:读取从机中输入寄存器的二进制内容。
Modbus ASCII数据报文结构详解插图17
  • 响应:读输入寄存器数据的响应消息的构造与读取保持寄存器相同。
Modbus ASCII数据报文结构详解插图19

功能 05(05H)写单线圈

  • 请求:将单个线圈写入 ON 或 OFF。
Modbus ASCII数据报文结构详解插图21
  • 响应:正常的响应是请求的回显。
Modbus ASCII数据报文结构详解插图23

功能 06(06H)写单个保持寄存器

  • 请求将一个值写入单个保持寄存器中。当广播时,该函数在所有附加的从机上设置相同的寄存器引用。请求消息指定要写入的寄存器引用(指定地址和数值)。
Modbus ASCII数据报文结构详解插图25
  • 响应

    正常的响应是请求的回显,在写入保持寄存器内容之后返回。

Modbus ASCII数据报文结构详解插图27

功能 15(0FH)写多个线圈

  • 请求:将一个线圈序列中的每个线圈写入 ON 或 OFF。
Modbus ASCII数据报文结构详解插图29
  • 响应:正常响应返回从地址、功能代码、起始地址和写入的线圈数量。
Modbus ASCII数据报文结构详解插图31

功能 16(10H)写多个保持寄存器

  • 请求:将值写入到一个保持寄存器序列中。
Modbus ASCII数据报文结构详解插图33
  • 响应:正常响应返回从地址、功能代码、起始地址和写入的寄存器数量。
Modbus ASCII数据报文结构详解插图35

LRC校验

LRC 校验码的计算方法如下:

unsigned char ucMBLRC( unsigned char * pucFrame, unsigned short usLen )
{
    unsigned char ucLRC = 0;  /* LRC char initialized */

    while( usLen-- )
    {
        ucLRC += *pucFrame++;   /* Add buffer byte without carry */
    }

    /* Return twos complement */
    ucLRC = ( UCHAR ) ( -( ( CHAR ) ucLRC ) );
    return ucLRC;
}

相关新闻

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

邮箱

cloud@modbus.cn

QQ
QQ
微信
微信
分享本页
返回顶部