如何做百度推廣的網(wǎng)站寫文章免費的軟件
設備必須要有RTU協(xié)議!這是Modbus協(xié)議上規(guī)定的,且默認模式必須是RTU,ASCII作為選項。(也就是說,一般的設備只有RTU這個協(xié)議,ASCII一般很少)所以說,一般學習Modbus協(xié)議,只需要了解RTU的協(xié)議,ASCII作為學習的了解就足夠了。
modbus- TCP 和 ?modbus-RTU的區(qū)別?
1 modbus- TCP 不需要校驗碼, modbus-RTU需要crc16算法校驗碼
2 modbus- TCP 請求幀有事務處理標識符 協(xié)議號 長度等字節(jié),但是modbus-RTU沒有事務處理標識符 協(xié)議號 長度等字節(jié)
modbus- TCP 請求幀:00 ?03 | ?00 00 | ?00 06 | ?01 | 03 | 00 01 | 00 01?
modbus-RTU 請求幀:?01| 03 | 00 01 ?|00 01 |D5 CA
?modbus- ASCII 和 modbus-RTU的區(qū)別?
1 modbus- ASCII校驗碼的算法采用的是LRC校驗算法, modbus-RTU采用的crc16校驗算法
2 modbus- ASCII發(fā)送的字節(jié)轉(zhuǎn)成字符串格式, ? ? ? modbus-RTU發(fā)送的是字節(jié)格式
modbus - ASCII 請求幀 :010300000001FB
1設備地址 01
2功能碼 讀取03
3寄存器地址 00 00
4 寄存器個數(shù) 00 01
5 lrc校驗碼 F B
string s2 = Tools.GetRequestFrame(new byte[] { 01,03,00,00,00,10});
封裝 modbus-ascii使用的方法?
internal static class Tools
{/// <summary>/// 把傳遞過來字節(jié)數(shù)組 通過lrc算法生成校驗碼/// </summary>/// <param name="data"> 字節(jié)數(shù)組</param>/// <returns>校驗碼</returns>/// Tools.CalcLRC([01,03,00,00,00,01 F B]) 采用工具算出的校驗碼是FB/// public static string CalcLRC(byte[] data){//1 獲取字節(jié)數(shù)組每一個元素相加的和uint sum = (uint)data.Sum(x => x);//計算每個元素的和//2 把sum進行取反操作,再加1,再和0xff進行與運算 ,//~110 = 001 取反操作uint res = (~sum + 1) & 0xff;return res.ToString("X2");}/// <summary>/// [01,03,00,00,00,01 ] 轉(zhuǎn)成 ":01030000001FB\r\n"/// </summary>/// <param name="data">轉(zhuǎn)換的字節(jié)數(shù)組</param>/// <returns> 轉(zhuǎn)成ascii字符串</returns>public static string GetRequestFrame(byte[] data){//1 算lrc校驗碼string jym = CalcLRC(data);string requestData = "";// 2 遍歷字節(jié)數(shù)組foreach (byte item in data){requestData += item.ToString("X2");}//3 拼接校驗碼string value = ":" + requestData + jym + "\r\n";return value;}//:0103025AC0E0/// <summary>/// :0103025AC0E0 轉(zhuǎn)成對應的ushort數(shù)組 [5A,C0]/// </summary>/// <param name="s"> ascii字符串</param>/// <param name="valueCount"> 寄存器個數(shù) 1個時候2字節(jié),2個4字節(jié)</param>/// <param name="startIndex"> 從哪個位置開始截取</param>/// <returns></returns>public static ushort[] StringToUshort(string s,int valueCount,int startIndex=7){//如果寄存器個數(shù)*4+開始截取數(shù)據(jù)的位置>整體字符串長度 證明沒有數(shù)據(jù)部分if (valueCount * 4 + startIndex > s.Length){throw new ArgumentException("字符串的長度不滿足最小的解析要求");}//正常的響應幀格式//定義長度為寄存器個數(shù)數(shù)組//:010302 5AC0 5AC0 5AC0 E0ushort[] bs = new ushort[valueCount];for (int i = 0; i < valueCount; i++){string value = s.Substring(startIndex, 4);startIndex += 4;bs[i] = Convert.ToUInt16(value,16);}return bs;}}