Modbusプロトコル学習

Modbusのは何ですか?

 

Modbusプロトコルは、共通言語上の電子制御装置に適用されますこのプロトコルによって、コントローラ間、コントローラは、ネットワーク(例えば、イーサネット(登録商標))および他のデバイスを介して通信することができます。Modbusプロトコルは、コントローラが認識されるであろうメッセージの構造を定義し、それらがどのネットワークを介して通信しているかどうかの使用。これは、もし他の機器からの要求に応じ、同様に検出して記録する方法エラー、コントローラ要求は、他のデバイスへのアクセス方法を記述しています。これは、メッセージのドメイン構造とのコンテンツ開発の共通フォーマットを

MODBUSは、要求/応答プロトコルであります

Modbusの

Modbusのは、熱的に図に分解されて、次の。

 画像

 

Modbusのメッセージフレーム

 

それを理解するには、シリアル通信の明確な理解を持つことになります!

画像

ユニバーサルメッセージフレーム

画像

 

ASCIIメッセージフレーム  (メッセージの各バイトは、2つのASCII文字として伝送される8ビット)

進、ASCII文字0 ... 9、A ... F

メッセージ各ASCII文字は16進数文字です

各バイトのビット

スタートビット

n個のデータビットを、送信された最下位ビット

パリティビット、パリティなしなし

1(パリティなし)、ストップビット(チェック)、ビット2

エラー検出ドメイン

LRC(縦に長いテスト)

ASCIIメッセージフレーム

ビットシーケンス(ASCII)

RTUメッセージフレーム

バイナリ8ビットの16進数0 ... 9、A ... F

各8ビットのメッセージフィールドは、2つの16進文字であります

各バイトのビット

スタートビット

8データビット、最下位ビットが送信

パリティビット、パリティなしなし

1(パリティなし)、ストップビット(チェック)、ビット2

エラー検出ドメイン

CRC(巡回冗長検出)

RTUメッセージフレーム

ビットシーケンス(RTU)

CRCチェック(http://baike.baidu.com/view/1664507.htm

コードをコピー
public static string CRCCheck(string val)
        {
            val = val.TrimEnd(' ');
            string[] spva = val.Split(' ');
            byte[] bufData = new byte[spva.Length + 2];
            bufData = ToBytesCRC(val);
            ushort CRC = 0xffff;
            ushort POLYNOMIAL = 0xa001;
            for (int i = 0; i < bufData.Length - 2; i++)
            {
                CRC ^= bufData[i];
                for (int j = 0; j < 8; j++)
                {
                    if ((CRC & 0x0001) != 0)
                    {
                        CRC >>= 1;
                        CRC ^= POLYNOMIAL;
                    }
                    else
                    {
                        CRC >>= 1;
                    }
                }
            }
            return Maticsoft.DBUtility.HLConvert.ToHex(System.BitConverter.GetBytes(CRC));
        }
        /// <summary>
        /// 例如把如下字符串转换成字节数组
        /// AA AA AA AA 0A 00 68 00 06 03 04 54 21 28 22 E5 F3 16 BB BB BB BB   转换为字节数组
        /// </summary>
        /// <param name="hex">十六进制字符串</param>
        /// <returns></returns>
        public static byte[] ToBytesCRC(string hex)
        {
            string[] temp = hex.Split(' ');
            byte[] b = new byte[temp.Length + 2];

            for (int i = 0; i < temp.Length; i++)
            {
                b[i] = Convert.ToByte(temp[i], 16);
            }

            return b;
        }
        /// <summary>
        /// 将字节数据转换为十六进制字符串,中间用 “ ”分割 如:AA AA AA AA 0A 00 68 00 06 03 04 54 21 28 22 E5 F3 16 BB BB BB BB
        /// </summary>
        /// <param name="vars">要转换的字节数组</param>
        /// <returns></returns>
        public static String ToHex(byte[] vars)
        {
            return BitConverter.ToString(vars).Replace('-', ' ').Trim();
        }
コードをコピー

CS校验(累加和)

コードをコピー
public static string CSCheck(string str)
        {
            if (str.Length == 0) return "";
            else str = str.Trim();
            byte[] sss = ToBytes(str);
            int n = 0;
            for (int i = 0; i < sss.Length; i++)
            {
                n += sss[i];
            }
            return ToHex(n);
        }
        /// <summary>
        /// AB CD 12 3B     转换为字节数组
        /// </summary>
        /// <param name="hex">十六进制字符串</param>
        /// <returns></returns>
        public static byte[] ToBytes(string hex)
        {
            string[] temp = hex.Split(' ');
            byte[] b = new byte[temp.Length];

            for (int i = 0; i < temp.Length; i++)
            {
                if (temp[i].Length > 0)
                    b[i] = Convert.ToByte(temp[i], 16);
            }

            return b;
        }
        /// <summary>
        /// 转换为符合本程序的十六进制格式
        /// </summary>
        /// <param name="var">1 2 3 等。</param>
        /// <returns>返回十六进制字符串,如果是1-9的话,前面带零</returns>
        /// <example>例如: 5  ="05"  12 ="0C" 无论何时,都是两位数。  </example>
        public static string ToHex(int var)
        {
            int cs = var;
            string tmp = "";
            if (cs == 0) { tmp = "00"; }
            while (cs > 0)
            {
                int ys;
                cs = Math.DivRem(cs, 256, out ys);
                tmp = tmp.Insert(0, string.Format(" {0}", Right("00" + Convert.ToString(ys, 16), 2).ToUpper()));
            }
            return tmp.Trim();
        }
        public static string Right(string str, int Length)
        {
            if ((Length <= 0) || (str == null))
            {
                return "";
            }
            int length = str.Length;
            if (Length >= length)
            {
                return str;
            }
            return str.Substring(length - Length, Length);
        }
コードをコピー

LRC校验(LRC错误校验用于ASCII模式)

コードをコピー
/// <summary>
        /// 取模FF(255)
        /// 取反+1
        /// </summary>
        /// <param name="writeUncheck"></param>
        /// <returns></returns>
        public static string LRCheck(string writeUncheck)
        {
            char[] hexArray = new char[writeUncheck.Length];
            hexArray = writeUncheck.ToCharArray();
            int decNum = 0, decNumMSB = 0, decNumLSB = 0;
            int decByte, decByteTotal = 0;

            bool msb = true;

            for (int t = 0; t <= hexArray.GetUpperBound(0); t++)
            {
                if ((hexArray[t] >= 48) && (hexArray[t] <= 57))

                    decNum = (hexArray[t] - 48);

                else if ((hexArray[t] >= 65) & (hexArray[t] <= 70))
                    decNum = 10 + (hexArray[t] - 65);

                if (msb)
                {
                    decNumMSB = decNum * 16;
                    msb = false;
                }
                else
                {
                    decNumLSB = decNum;
                    msb = true;
                }
                if (msb)
                {
                    decByte = decNumMSB + decNumLSB;
                    decByteTotal += decByte;
                }
            }

            decByteTotal = (255 - decByteTotal) + 1;
            decByteTotal = decByteTotal & 255;

            int a, b = 0;

            string hexByte = "", hexTotal = "";
            double i;

            for (i = 0; decByteTotal > 0; i++)
            {
                b = Convert.ToInt32(System.Math.Pow(16.0, i));
                a = decByteTotal % 16;
                decByteTotal /= 16;
                if (a <= 9)
                    hexByte = a.ToString();
                else
                {
                    switch (a)
                    {
                        case 10:
                            hexByte = "A";
                            break;
                        case 11:
                            hexByte = "B";
                            break;
                        case 12:
                            hexByte = "C";
                            break;
                        case 13:
                            hexByte = "D";
                            break;
                        case 14:
                            hexByte = "E";
                            break;
                        case 15:
                            hexByte = "F";
                            break;
                    }
                }
                hexTotal = String.Concat(hexByte, hexTotal);
            }
            return hexTotal;
        }

        public void LRCheck(byte[] code)
        {
            int sum = 0;
            foreach (byte b in code)
            {
                sum += b;
            }
            sum = sum % 255;//取模FF(255)
            合計=〜合計+ 1 ; // 取反+1 
             LRC = Convert.ToString(合計16 )。
            返すLRCを。
        }
コードをコピー

 

 

カスタムのModbusデータシート

 

Modbusのカスタムデータテーブルの例:

情報を読み取る関連機器:

画像

コマンドメッセージ情報分析:

画像

カスタムのModbusデータテーブル定義は注意してください

 

シリアルデバッグツール

 

シリアル使用デバッグツール。

画像

 

+ RS485シリアルデバッグツールになります「の章をデバッグ」を参照してください。詳細な説明を使用する方法、ハードウェア上のデータを読み込み、ハードウェアに要求することができます。

画像 画像

ネットワークのデバッグアシスタント:

       デバッグツールでアシスタントプリンシパルまたはTCPプロトコル通信をデバッグします

 画像

おすすめ

転載: blog.csdn.net/luoyajingfeng2/article/details/80249195