Modbus既然是一种通信プロトコル,那它就应该有规定的通信形式用于在デバイス之间的指令受信与识别。
本記事就着重讲讲Modbusプロトコル的RTUフレーム和ASCIIフレーム。
Modbusフレーム在串行链路上的格式如下:

在上图的格式中:
1)アドレス域:指代的是子节点アドレス。合法的子节点アドレス为 0 – 247。 每个子デバイス被赋予 1 – 247 範囲中的アドレス。主节点経由将子节点的アドレス放到报文的アドレス域对子节点寻址。当子节点戻る应答时, 它将自己的アドレス放到应答报文的アドレス域以让主节点知道哪个子节点在回答。
2)function code:指明サーバー·サーバー要执行的动作。
3)Anti-counterfeiting verification:機能コード后面的有表示含有リクエスト和レスポンス参数的データ。
4)エラー检验:是对报文内容执行 "冗余チェック" 的計算结果。根据不同的传输モード (RTU or ASCII)使用两种不同的計算方法。
上面説明了Modbus的フレーム形式,是一种规定的データパッキング的规约。
Modbus中有两种串行传输モード: RTU モード 和 ASCII モード。它定义了报文域的内容オンライン路上串行的传送。它确定了信息如何パッキング为报文和解码。
全装備。必须実装 RTU モード,ASCII モード是备选项。
1、Modbus RTUフレームモード
RTUフレーム指的是什么呢?简单而言就是报文中的每バイト単位。都是用十六进制表示的。
RTUフレーム中的每个Bytesのデータ的格式定义如下:
每バイト単位。为8bit
报文中每个 8 位バイト含有2つ 4 位十六进制文字(0–9, A–F)
Bits per Byte:
1 スタート地点。
8 data bit,首先送信最低有效位
1 位作为パリティ検査
1 stop bit
注 : 使用検証なし。要求 2 个ストップ·ビット。
每バイト単位。为8bit报文中每个 8 位バイト含有2つ 4 位十六进制文字(0–9, A–F)Bits per Byte: 1 スタート地点。8 data bit,首先送信最低有效位1 位作为パリティ検査1 stop bit注 : 使用検証なし。要求 2 个ストップ·ビット。
文字的传送流是LSB先送信,最后才是MSB,如下:
有パリティ検査的:
パリティなし的:

重点来了,RTU的报文フレーム形式: 
Modbus RTUフレーム的最大長さ为256バイト単位。。
2、Modbus ASCIIフレームモード
Modbus ASCIIフレーム中规定报文的每个Bytesのデータ以2つASCII文字进行送信。
怎么理解呢?
例 : 有一个データバイト为 0X5B,它会被编码为2つ文字 : 0x35 和 0x42 (ASCII Coding 0x35 ="5", 0x42 ="B" )。
ASCII モード节每バイト単位。 (10 位 ) 为的格式为 :
报文中每个 ASCII 文字含有 1 个十六进制文字
Bits per Byte:
1 スタート地点。
7 data bit, 首先送信最低有效位
1 位作为パリティ検査
1 stop bit
注 : 使用検証なし。要求 2 个ストップ·ビット。
报文中每个 ASCII 文字含有 1 个十六进制文字Bits per Byte: 1 スタート地点。7 data bit, 首先送信最低有效位1 位作为パリティ検査1 stop bit注 : 使用検証なし。要求 2 个ストップ·ビット。
文字是如何串行传送的:
有パリティ検査的:
パリティなし的:

Modbus ASCII的报文フレーム形式:

ASCII报文フレーム与RTU报文フレーム有很大的不同,ASCII报文フレーム中是带有开头和结束标识符的,这对デバイス受信报文フレーム很方便。デバイス可以很方便的知道一个新报文フレーム的开头,并且知道报文什么时候结束了。
RTU报文フレーム中并ない这样的标识符,所以在受信报文フレーム的时候就需要做些処理,方能判断报文是否完成了一フレームデータ的受信。
ASCII报文フレーム中用冒号(:)(ASCII的十六进制为0x3A)作为起始,用回车换行(CR LF)(ASCII的十六进制为0x0D 0x0A)作为结束。
由于ASCIIモード下每个文字バイト需要用2つ文字编码,所以为了确保 ASCII モード 和 RTU モード在 Modbus 应用级兼容,ASCIIデータ域最大データ長さ为 (2x252) 是 RTU Anti-counterfeiting verification (252) 的两倍。因此,ModbusASCII フレーム的最大尺寸为 513 个文字。
3、RTUフレーム与ASCIIフレーム的传输区别
前面已经分析了RTU报文フレーム和ASCII报文フレーム違いはありません,RTU报文フレーム是不带开始和结束标识符的,而ASCII报文フレーム中带有开始和结束标识符。所以在デバイス受信RTUフレーム和ASCIIフレーム的时候処理方式就会有所不同。
(1)RTUフレーム的报文传输
现在思考一个問題:RTUフレーム中因为ない开始和结束的标识符,デバイス要怎么知道已经受付完了。了一フレーム报文了呢?
为了能够確認报文被完全受信,不至于受信到不完全的报文就进行メッセージの解析和処理,所以必须要想办法去確認一フレーム报文已经完成受信,然后再去処理。
在RTUモード中,为了标识不同的报文フレーム,在报文フレーム之间插入一个空闲時間の間隔,在两フレーム报文之间用至少3.5个文字的暇なとき间来区分不同的フレーム,同时标识一フレーム是否已经完成受信。这个时间也称为t3.5時間の間隔。
这样的操作方式看下图进行理解:

もし前面开始了一次报文フレーム的传输,受信デバイス从空闲ステータス中被唤起,就需要多受信进行一个タイムアウト计时机制,用以確認报文フレーム是否已经受付完了。。就如上图中的フレーム1和フレーム2之间もし間隔的时间等于或者超过了t3.5所设定的空闲待機中时间,就可以认为前面的フレーム1已经受付完了。,后面再过来的データ就属于フレーム2的データ。
在RTUフレーム中还有一个讲究的地方:因为报文フレーム本质是用文字流进行送信的,所谓为了区分不同的报文フレーム就需要用到t3.5的文字間隔。但是报文フレーム中的每个文字要怎么確認是连续的呢?
所以为了確認文字流的送信连续,就要使用到t1.5文字の時間。看下图: 
从上图中可以清晰看到:もし2つ文字之间的空闲間隔大于 1.5 个文字の時間,则报文フレーム被认为不完全应该被受信节点丢弃。小于或者等于1.5个文字的时间则认普通のために。
上面说的t1.5和t3.5这2つ时间,其实并ではない一定应用的。なぜか。呢?
因为时间项目应用中,很多时候多报文フレーム的受信都会涉及到中断,特别是在通信速率很高的情况下,会频繁的快速中断,对cpu的负担是很重的,这个时候这t1.5和t3.5的时间就会变得很短暂,并ではない很好処理。
所以,t1.5和t3.5这2つ时间一般是在通信速率在19200Bps或以下的时候才需要去严格约定。
(2)ASCIIフレーム的报文传输
由于ASCII报文フレーム与RTU报文フレーム有着很大的不同,ASCII报文フレーム是有起始和结束标识符的,而RTUフレームない这样的标识。所以ASCII报文フレーム的受信就简单方便多了,也必要なし。什么t3.5的フレーム間隔时间。
但是呢,为了保证受信的报文フレーム连续,まだ可以约定文字间的传输时间的。一般认为,报文中的文字時間の間隔可以达到一秒,もし超过了这个時間の間隔,就认为发生了エラー,要废弃掉这一フレーム报文データ,再スタート。受信。
4、RTUフレーム和ASCIIフレーム的传输ステータス分析
(1)RTUフレーム的传输ステータス:

上面ステータス图可以取得的信息:
1)从 "初始" 态到 “空闲” 态转换需要 t 3.5 定时タイムアウト,用以保证フレーム间延迟。
2)“空闲” 态是ない送信和受信报文要処理的正常ステータス。
3)在 RTU モード, 当ない活动的传输的時間の間隔达 3.5 个文字长时,通信链路被认为在 “空闲”态。
4)当链路暇なとき, 在链路上检测到的任何传输的文字被识别为 フレーム起始。 链路变为 "活动" status。然后, 当链路上ない文字传输的时间间个达到 t3.5 后,被识别为 フレーム结束。
5)检测到フレーム结束后,Complete CRC calculation和检验。然后,分析アドレス域以确定フレーム是否发往此デバイス,もしではない,则丢弃此フレーム。 为了减少受信処理时间,アドレス域可以在一接到就分析,而必要なし。等到整个フレーム结束。这样,CRC calculation只需要在フレーム寻址到该节点 (包括广播フレーム) 时进行。
(2)ASCIIフレーム的传输ステータス

上面ステータス图可以得到的信息:
1)“空闲” 态是ない送信和受信报文要処理的正常ステータス。
2)每次受信到 ":" 文字表示新的报文的开始。もし在一个报文的受信过程中收到该文字,则当前地报文被认为不完全并被丢弃。而一个新的受信バッファ。被重新分配。
3)检测到フレーム结束后,Complete LRC 計算和检验。然后,分析アドレス域以确定フレーム是否发往此デバイス,もしではない,则丢弃此フレーム。 为了减少受信処理时间,アドレス域可以在一接到就分析,而必要なし。等到整个フレーム结束。
Leave a Reply