資源簡介
一個類解決通訊問題
using System;
using System.Collections.Generic;using System.IO.Ports;
using System.Text;
namespace MODBUS_通訊助手
{
public class ModbusHple
{
//新建一個串口對象
public static SerialPort sp = new SerialPort();
//查詢結果
public byte[] bytes = new byte[1024];
/// <summary>
/// 獲取可用的串口
/// </summary>
/// <returns></returns>
public List<string> GetCOM() {
List<string> list = new List<string>();
//檢測串口是否存在
for (int i = 0; i < 30; i )
{
try
{
SerialPort sp = new SerialPort("COM" (i 1).ToString());
sp.Open();
sp.Close();
list.Add("COM" (i 1).ToString());
}
catch
{
continue;
}
}
return list;
}
/// <summary>
/// 設施串口參數并綁定事件
/// </summary>
private void setPortProperty(string cbxcomport, string cbxbaudrate, string cbxdatabit, string cbxstopbit, string cbxparity)
{
sp = new SerialPort();
sp.PortName = cbxcomport;//設置串口名
sp.BaudRate = Convert.ToInt32(cbxbaudrate); //設置波特率
sp.DataBits = Convert.ToInt32(cbxdatabit); //設置數據位
float f = Convert.ToSingle(cbxstopbit); //設置停止位
if (f == 0)
sp.StopBits = StopBits.None;
if (f == 1)
sp.StopBits = StopBits.One;
if (f == 1.5)
sp.StopBits = StopBits.OnePointFive;
if (f == 2)
sp.StopBits = StopBits.Two;
string property = cbxparity; //校驗位設置
if (property == "無校驗")
sp.Parity = Parity.None;
if (property == "奇校驗")
sp.Parity = Parity.Odd;
if (property == "偶校驗")
sp.Parity = Parity.Even;
sp.ReadTimeout = -1;
sp.RtsEnable = true;
//定義Recevied事件
sp.DataReceived = new SerialDataReceivedEventHandler(sp_DataRecevied);
sp.Open();
}
/// <summary>
/// 串口控件接收事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void sp_DataRecevied(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(100);//延時100ms,等待接收數據完成
Byte[] ReceviedData = new Byte[sp.BytesToRead];
sp.Read(ReceviedData, 0, ReceviedData.Length);
//結果復制給全局變量
bytes = ReceviedData;
}
/// <summary>
/// 打開串口
/// </summary>
/// <param name="cbxcomport">串口 (例:COM1)</param>
/// <param name="cbxbaudrate">波特率 (例:9600)</param>
/// <param name="cbxdatabit">數據位 (例:8)</param>
/// <param name="cbxstopbit">停止位 (例:1)</param>
/// <param name="cbxparity">校驗位 (例:無效驗)</param>
public bool OpenPort(string cbxcomport, string cbxbaudrate, string cbxdatabit, string cbxstopbit, string cbxparity) {
#region 驗證參數
if (cbxcomport==""|| cbxcomport == null ||
cbxbaudrate == "" || cbxcomport == null ||
cbxdatabit == "" || cbxdatabit == null ||
cbxstopbit == "" || cbxstopbit == null ||
cbxparity == "" || cbxparity == null)
{
return false;
}
#endregion
if (sp.IsOpen == false)
{
setPortProperty(cbxcomport, cbxbaudrate, cbxdatabit, cbxstopbit, cbxparity);
}
return sp.IsOpen;
}
/// <summary>
/// 獲取數據(獲取10個值)
/// </summary>
/// <param name="strstationnum1">站號</param>
/// <returns></returns>
public bool 獲取數據(string strstationnum1)
{
#region 驗證參數
if (strstationnum1 == "" || strstationnum1 == null|| sp.IsOpen == false)
{
return false;
}
#endregion
//站號
string strstationnum = strstationnum1;
//模式
string strfunctioncode = "03";
//起始位
string straddress = "0000";
//數量位
string straddrsize = "000A";
string senddatas1 = "";
string senddatas2 = "";
int len1 = straddress.Length;
int len2 = straddrsize.Length;
string addr1 = "";
string addrsize1 = "";
for (int a = 0; a < len1; a = a 2) //地址加上空格
{
string addr2 = straddress.Substring(a, 2);
addr1 = addr1 " " addr2;
}
for (int a = 0; a < len2; a = a 2) //地址數量加上空格
{
string addrsize2 = straddrsize.Substring(a, 2);
addrsize1 = addrsize1 " " addrsize2;
}
//模式
senddatas2 = strstationnum " " strfunctioncode addr1 addrsize1;
//MODBUS RTU模式CRC校驗計算
string[] datas = senddatas2.Split(' '); //去掉空格
List<byte> bytedata = new List<byte>();
foreach (string str in datas)
{
bytedata.Add(byte.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier));
}
byte[] crcbuf = bytedata.ToArray();
//計算并填寫CRC校驗
int crc = 0xffff;
int len = crcbuf.Length;
for (int n = 0; n < len; n )
{
byte i;
crc = crc ^ crcbuf[n];
for (i = 0; i < 8; i )
{
int tt;
tt = crc & 1;
crc = crc >> 1;
crc = crc & 0x7fff;
if (tt == 1)
{
crc = crc ^ 0xa001;
}
crc = crc & 0xffff;
}
}
string[] redata = new string[2];
redata[1] = Convert.ToString((byte)((crc >> 8) & 0xff), 16);
redata[0] = Convert.ToString((byte)((crc & 0xff)), 16);
if (redata[0].Length == 1)
{
redata[0] = "0" redata[0];
}
if (redata[1].Length == 1)
{
redata[1] = "0" redata[1];
}
senddatas1 = senddatas2 " " redata[0] " " redata[1];
//發送hex
string strSend = senddatas1;
string sendBuf = strSend;
string sendnoNull = sendBuf.Trim();
string sendNOComma = sendnoNull.Replace(',', ' '); //去掉英文逗號
string sendNOComma1 = sendNOComma.Replace(',', ' '); //去掉中文逗號
string strSendNoComma2 = sendNOComma1.Replace("0x", ""); //去掉0x
strSendNoComma2.Replace("0X", ""); //去掉0X
string[] strArray = strSendNoComma2.Split(' ');
int byteBufferLength = strArray.Length;
for (int i = 0; i < strArray.Length; i )
{
if (strArray[i] == "")
{
byteBufferLength--;
}
}
byte[] byteBuffer = new byte[byteBufferLength];
int ii = 0;
for (int i = 0; i < strArray.Length; i )
{
Byte[] bytesOfStr = Encoding.Default.GetBytes(strArray[i]);
int decNum = 0;
if (strArray[i] == "")
{
continue;
}
else
{
decNum = Convert.ToInt32(strArray[i], 16);
}
try
{
byteBuffer[ii] = Convert.ToByte(decNum);
}
catch
{
return false;
}
ii ;
}
sp.Write(byteBuffer, 0, byteBuffer.Length);
return true;
}
/// <summary>
/// 修改數據(修改10個值)
/// </summary>
/// <param name="strstationnum1">站號</param>
/// <param name="strdatas1">數據</param>
/// <returns></returns>
public bool 修改數據(string strstationnum1,string strdatas1)
{
#region 參數驗證
if (strstationnum1==""|| strstationnum1==null||
strdatas1==""|| strdatas1==null||
strdatas1.Length!=40 || sp.IsOpen == false)
{
return false;
}
#endregion
//站號
string strstationnum = strstationnum1;
//模式
string strfunctioncode = "10";
//起始位
string straddress = "0000";
//數量位
string straddrsize = "000A";
//字節數
string strbytenum = "14";
//數據
string strdatas = strdatas1;
string senddatas1 = "";
string senddatas2 = "";
int len1 = straddress.Length;
int len2 = straddrsize.Length;
int len3 = strdatas.Length;
int len4 = strbytenum.Length;
string addr1 = "";
string addrsize1 = "";
string datas1 = "";
string bytenum1 = "";
for (int a = 0; a < len1; a = a 2) //地址加上空格
{
string addr2 = straddress.Substring(a, 2);
addr1 = addr1 " " addr2;
}
for (int a = 0; a < len2; a = a 2) //地址數量加上空格
{
string addrsize2 = straddrsize.Substring(a, 2);
addrsize1 = addrsize1 " " addrsize2;
}
for (int a = 0; a < len3; a = a 2) //數據加上空格
{
string datas2 = strdatas.Substring(a, 2);
datas1 = datas1 " " datas2;
}
for (int a = 0; a < len4; a = a 2) //字節數加上空格
{
string bytenum2 = strbytenum.Substring(a, 2);
bytenum1 = bytenum1 " " bytenum2;
}
//模式
senddatas2 = strstationnum " " strfunctioncode addr1 addrsize1 bytenum1 datas1;
//MODBUS RTU模式CRC校驗計算
string[] datas = senddatas2.Split(' '); //去掉空格
List<byte> bytedata = new List<byte>();
foreach (string str in datas)
{
bytedata.Add(byte.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier));
}
byte[] crcbuf = bytedata.ToArray();
//計算并填寫CRC校驗
int crc = 0xffff;
int len = crcbuf.Length;
for (int n = 0; n < len; n )
{
byte i;
crc = crc ^ crcbuf[n];
for (i = 0; i < 8; i )
{
int tt;
tt = crc & 1;
crc = crc >> 1;
crc = crc & 0x7fff;
if (tt == 1)
{
crc = crc ^ 0xa001;
}
crc = crc & 0xffff;
}
}
string[] redata = new string[2];
redata[1] = Convert.ToString((byte)((crc >> 8) & 0xff), 16);
redata[0] = Convert.ToString((byte)((crc & 0xff)), 16);
if (redata[0].Length == 1)
{
redata[0] = "0" redata[0];
}
if (redata[1].Length == 1)
{
redata[1] = "0" redata[1];
}
senddatas1 = senddatas2 " " redata[0] " " redata[1];
//發送hex
string strSend = senddatas1;
string sendBuf = strSend;
string sendnoNull = sendBuf.Trim();
string sendNOComma = sendnoNull.Replace(',', ' '); //去掉英文逗號
string sendNOComma1 = sendNOComma.Replace(',', ' '); //去掉中文逗號
string strSendNoComma2 = sendNOComma1.Replace("0x", ""); //去掉0x
strSendNoComma2.Replace("0X", ""); //去掉0X
string[] strArray = strSendNoComma2.Split(' ');
int byteBufferLength = strArray.Length;
for (int i = 0; i < strArray.Length; i )
{
if (strArray[i] == "")
{
byteBufferLength--;
}
}
byte[] byteBuffer = new byte[byteBufferLength];
int ii = 0;
//對獲取的字符做相加運算
for (int i = 0; i < strArray.Length; i )
{
Byte[] bytesOfStr = Encoding.Default.GetBytes(strArray[i]);
int decNum = 0;
if (strArray[i] == "")
continue;
decNum = Convert.ToInt32(strArray[i], 16);
try
{
byteBuffer[ii] = Convert.ToByte(decNum);
}
catch
{
return false;
}
ii ;
}
sp.Write(byteBuffer, 0, byteBuffer.Length);
return true;
}
/// <summary>
/// 通用發送
/// </summary>
/// <param name="strstationnum">站號</param>
/// <param name="tbxfunctioncode">模式(01:獲取數據 02:獲取數據 03:獲取數據 05:置位 06:置位 10:設置數據 0F:設置數據)</param>
/// <param name="straddress">起始位(雙字節4位)</param>
/// <param name="straddrsize">數量位(雙字節4位)</param>
/// <param name="strbytenum">字節數(單字節2位)</param>
/// <param name="strdatas">數據位(多字節 數量位*4 )</param>
/// <returns></returns>
public bool 通用發送(string strstationnum,string tbxfunctioncode,string straddress,string straddrsize,string strbytenum,string strdatas)
{
#region 參數驗證
int nsfasgf = (Convert.ToInt32(straddrsize, 16) * 4);
if (sp.IsOpen == false||tbxfunctioncode.Length!=2|| straddress.Length!=4
|| straddrsize.Length != 4 || strbytenum.Length != 2
|| strdatas.Length != (Convert.ToInt32(straddrsize, 16) * 4))
{
return false;
}
#endregion
string senddatas1 = "";
string senddatas2 = "";
int len1 = straddress.Length;
int len2 = straddrsize.Length;
int len3 = strdatas.Length;
int len4 = strbytenum.Length;
string addr1 = "";
string addrsize1 = "";
string datas1 = "";
string bytenum1 = "";
for (int a = 0; a < len1; a = a 2) //地址加上空格
{
string addr2 = straddress.Substring(a, 2);
addr1 = addr1 " " addr2;
}
for (int a = 0; a < len2; a = a 2) //地址數量加上空格
{
string addrsize2 = straddrsize.Substring(a, 2);
addrsize1 = addrsize1 " " addrsize2;
}
for (int a = 0; a < len3; a = a 2) //數據加上空格
{
string datas2 = strdatas.Substring(a, 2);
datas1 = datas1 " " datas2;
}
for (int a = 0; a < len4; a = a 2) //字節數加上空格
{
string bytenum2 = strbytenum.Substring(a, 2);
bytenum1 = bytenum1 " " bytenum2;
}
if (tbxfunctioncode == "01" | tbxfunctioncode == "02" | tbxfunctioncode == "03") //
{
senddatas2 = strstationnum " " tbxfunctioncode addr1 addrsize1;
}
if (tbxfunctioncode == "05" | tbxfunctioncode == "06") //置位
{
senddatas2 = strstationnum " " tbxfunctioncode addr1 datas1;
}
if (tbxfunctioncode == "0F" | tbxfunctioncode == "10")
{
senddatas2 = strstationnum " " tbxfunctioncode addr1 addrsize1 bytenum1 datas1;
}
//MODBUS RTU模式CRC校驗計算
string[] datas = senddatas2.Split(' '); //去掉空格
List<byte> bytedata = new List<byte>();
string str1 = "";
foreach (string str in datas)
{
bytedata.Add(byte.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier));
str1 = str;
}
byte[] crcbuf = bytedata.ToArray();
//計算并填寫CRC校驗
int crc = 0xffff;
int len = crcbuf.Length;
for (int n = 0; n < len; n )
{
byte i;
crc = crc ^ crcbuf[n];
for (i = 0; i < 8; i )
{
int tt;
tt = crc & 1;
crc = crc >> 1;
crc = crc & 0x7fff;
if (tt == 1)
{
crc = crc ^ 0xa001;
}
crc = crc & 0xffff;
}
}
string[] redata = new string[2];
redata[1] = Convert.ToString((byte)((crc >> 8) & 0xff), 16);
redata[0] = Convert.ToString((byte)((crc & 0xff)), 16);
if (redata[0].Length == 1)
{
redata[0] = "0" redata[0];
}
if (redata[1].Length == 1)
{
redata[1] = "0" redata[1];
}
senddatas1 = senddatas2 " " redata[0] " " redata[1];
//發送hex
string strSend = senddatas1;
string sendBuf = strSend;
string sendnoNull = sendBuf.Trim();
string sendNOComma = sendnoNull.Replace(',', ' '); //去掉英文逗號
string sendNOComma1 = sendNOComma.Replace(',', ' '); //去掉中文逗號
string strSendNoComma2 = sendNOComma1.Replace("0x", ""); //去掉0x
strSendNoComma2.Replace("0X", ""); //去掉0X
string[] strArray = strSendNoComma2.Split(' ');
int byteBufferLength = strArray.Length;
for (int i = 0; i < strArray.Length; i )
{
if (strArray[i] == "")
{
byteBufferLength--;
}
}
byte[] byteBuffer = new byte[byteBufferLength];
int ii = 0;
//對獲取的字符做相加運算
for (int i = 0; i < strArray.Length; i )
{
Byte[] bytesOfStr = Encoding.Default.GetBytes(strArray[i]);
int decNum = 0;
if (strArray[i] == "")
continue;
decNum = Convert.ToInt32(strArray[i], 16); //atrArray[i] == 12時,temp == 18
try //防止輸錯,使其只能輸入一個字節的字符
{
byteBuffer[ii] = Convert.ToByte(decNum);
}
catch
{
return false;
}
ii ;
}
sp.Write(byteBuffer, 0, byteBuffer.Length);
return true;
}
}
}
代碼片段和文件信息
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件???????20191??2020-05-12?11:23??ModbusHple.txt
-----------?---------??----------?-----??----
?????文件???????20191??2020-05-12?11:23??ModbusHple.txt
- 上一篇:C# 攝像頭拍照
- 下一篇:HalconDotNet數字識別
評論
共有 條評論
相關資源
- libmodbus-3.0.6.tar.gz(modbus協議源碼)
- C#IEEE754協議 modbus 4位byte轉float
- MODBUS-CSharp socket測試小程序。MODBUS協議
- VirtualSerialPortDriver 虛擬串口
- MODBUS C#串口通訊
- ModbusMonitor VS2010 winform Csharp 開發的一
- NModbus 用C#實現的modbus協議源碼
- MODBUS C#寫了一款上位機監控軟件
- TDNET3.3 Teigha_NET 3.03官方幫助文檔
- Modbus 用C#實現ModBus讀寫功能
- CSharp_Serial_Modbus C# 串口例子
- MODBUS(RTU)
- Modbus C# 寫的串口通信程序源碼
- NModbus4 Modbus是一個C#實現Modbus協議。
- Modbus 一個modbus訪問包
- C#幫助文檔
- vb.netC#和PLC通過Modbus——TCP通訊代碼
- MODBUS C# CRC16校驗碼計算工具 源碼--看
- ModBus協議發送數據——從機和主機程
- C# 串口源碼Modbus
- c# modbus tcp
- MODBUS/TCP 協議源代碼 c#.net
- C#Modbus通訊幫助類庫(串口下的Modbu
- c# modbus 上位機 測試程序 tcp ascii rtu
- 用C#編的永宏通訊協議類,通俗易懂,
- MODBUS TCP C# 源碼 -- 測試過匯川PLC
- 視覺項目-LabViewHalcon;
- C# Modbus通訊及CRC校驗計算
- WPF 虛擬鍵盤 (Virtual KEYBOARD)
- ModbusTcpMasterPro和ModbusTcpSlavePro