using System;
using System.IO.Ports;
using System.Windows.Forms;
using System.Threading;
using HardwareConfig;
using BaseLibRWFile;
namespace BaseLibComm
{
public class ModbusRTU
{
public static ModbusRTU Ins = new ModbusRTU();
//private SerialPort MyCom;//定义串口类对象
//private int CurrentAddr;//定义当前通讯设备的地址
//private byte[] bReceiveData = new byte[1024];//最大接受的1024个字节
//private string mTempStr;
//private byte ReceiveByte;
private int mReceiveByteCount;
//private bool bCommWell;
private byte CRCHi = 0xFF;
private byte CRCLo = 0xFF;
//定义超时定时器 250mm
private System.Timers.Timer tmrTimeOut = new System.Timers.Timer(500);//实例化Timer类,设置间隔时间为10000毫秒;
//public string strErrMsg;//错误信息
//public string strReceivCommandData, strSendCommandData;//定义发送及接收数据字符串
//public bool RtuRunFlag = true;
public long iWordStartAddr, iBitStartAddr;//保持寄存器及输出线圈的起始地址
public int WordLength, iBitLen;//保持寄存器及输出线圈长度
//public short[,] WordValueArray = new short[16, 256];//定义最大保持寄存器二维数组,1维表示设备站号,二维表示数据
//public bool[,] BitVaueArray = new bool[16, 256];//定义输出线圈二维数组,1维表示设备站号,二维表示数据
//public bool[] bComRunNomalFlag = new bool[16];//false 通讯正常 true 通讯异常 最大16个设备
//public bool comBusying; //串口忙
//public bool isOpend; //串口打开状态
public ModbusRTU()
{
//MyCom = new SerialPort();
//RtuRunFlag = true;
//throw new System.NotImplementedException();
}
// LRC CHECK FROM CSDN MODIFY
#region
private string LRC(string strLRC)
{
int d_lrc = 0;
string h_lrc = "";
int l = strLRC.Length;
for (int c = 0; c < l; c = c + 2)
{
string c_data = strLRC.Substring(c, 2);
d_lrc = d_lrc + (Int32)Convert.ToByte(c_data, 16);
//d_lrc = d_lrc + Convert.ToInt32(c_data);
}
if (d_lrc >= 255)
d_lrc = d_lrc % 0x100;
h_lrc = Convert.ToInt32(~d_lrc + 1).ToString("X");
if (h_lrc.Length > 2)
h_lrc = h_lrc.Substring(h_lrc.Length - 2, 2);
return h_lrc;
}
#endregion
//CRC校验 FROM Google
#region
private static readonly byte[] aucCRCHi = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
private static readonly byte[] aucCRCLo = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
private void Crc16(byte[] pucFrame, int usLen)
{
int i = 0;
CRCHi = 0xFF;
CRCLo = 0xFF;
UInt16 iIndex = 0x0000;
while (usLen-- > 0)
{
iIndex = (UInt16)(CRCLo ^ pucFrame[i++]);
CRCLo = (byte)(CRCHi ^ aucCRCHi[iIndex]);
CRCHi = aucCRCLo[iIndex];
}
}
#endregion
//设置串口并打开串口
public bool OpenMyCom(StSerialPort st)
{
try
{
for (int i = 0; i <= 15; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].bComRunNomalFlag[i] = false;
}
//先关闭已经打开的串口
if (st.serialPort.IsOpen)
{
st.serialPort.Close();
}
st.serialPort.ReceivedBytesThreshold = 1;
st.serialPort.DataReceived += new SerialDataReceivedEventHandler(MyCom_DataReceived);//DataReceived事件委托
//打开串口
st.serialPort.Open();
//设置超时定时器属性
tmrTimeOut.Elapsed += new System.Timers.ElapsedEventHandler(commTimeOut);//到达时间的时候执行事件;
tmrTimeOut.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
tmrTimeOut.Enabled = false;//是否执行System.Timers.Timer.Elapsed事件;
st.comBusying = false;
SerialPortManager.DicSerialPort[st.serialPort.PortName] = st;
//bCommWell = false;
return true;
}
catch (Exception ex)
{
string str = "Modbus串口打开失败:";
Msg.Show($"{str}\r\n{ex}", $"{str}\r\nModbus serial port opening failed:\r\n{ex}",
$"{str}\r\nKhông mở được cổng nối tiếp Modbus:\r\n{ex}", "Error", msgicon: MessageBoxIcon.Error);
return false;
}
finally
{
}
}
public void CloseMyCom(StSerialPort st)
{
st.serialPort.Close();
}
//DataReceived事件委托方法 每个协议都需重写DataReceived
private void MyCom_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
SerialPort sp = sender as SerialPort;
int i;
string mTempStr;
mReceiveByteCount = 0;
//循环接收数据
while (SerialPortManager.DicSerialPort[sp.PortName].serialPort.BytesToRead > 0)
{
SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[mReceiveByteCount] = (byte)SerialPortManager.DicSerialPort[sp.PortName].serialPort.ReadByte();
mReceiveByteCount = mReceiveByteCount + 1;
//缓冲区溢出复位
if (mReceiveByteCount >= 1024)
{
mReceiveByteCount = 0;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
return;
}
}
if (SerialPortManager.DicSerialPort[sp.PortName].SeriesType==SeriesTypeEnum.ModbusRTU)//RTU接受方式
{
//输入寄存器 功能码0x04
if (mReceiveByteCount >= (WordLength * 2 + 5) && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1 && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[1] == 0x04)
{
mTempStr = "";
for (i = 0; i < (WordLength * 2 + 5); i++)
{
mTempStr = mTempStr + " " + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[i].ToString("X2");
}
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
//bCommWell = true;//通讯GOOD
}
//保持寄存器 功能码0x03
if (mReceiveByteCount >= (WordLength * 2 + 5) && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1 && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[1] == 0x03)
{
mTempStr = "";
for (i = 0; i < (WordLength * 2 + 5); i++)
{
mTempStr = mTempStr + " " + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[i].ToString("X2");
}
//赋值给全局MW变量 从起始地址开始
int nDownPos;
nDownPos = 0;
for (i = 0; i < WordLength; i++)
{
SerialPortManager.DicSerialPort[sp.PortName].WordValueArray[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, nDownPos] = (Int16)(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[3 + 2 * i] * 256 + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[3 + 2 * i + 1]);
nDownPos = nDownPos + 1;
}
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
//bCommWell = true;//通讯GOOD
}
//输出线圈 功能码0x01
if (mReceiveByteCount >= (iBitLen + 5) && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1 && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[1] == 0x01)
{
mTempStr = "";
for (i = 0; i < (iBitLen + 5); i++)
{
mTempStr = mTempStr + " " + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[i].ToString("X2");
}
//赋值给全局变量
for (i = 0; i < SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[2]; i++)
{
ByteToBoolArray(SerialPortManager.DicSerialPort[sp.PortName],SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[3 + i], SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, i * 8);
}
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
//bCommWell = true;//通讯GOOD
}
//输入线圈 功能码0x02
if (mReceiveByteCount >= (iBitLen + 5) && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1 && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[1] == 0x02)
{
mTempStr = "";
for (i = 0; i < (iBitLen + 5); i++)
{
mTempStr = mTempStr + " " + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[i].ToString("X2");
}
for (i = 0; i < SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[2]; i++)
{
ByteToBoolArray(SerialPortManager.DicSerialPort[sp.PortName],SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[3 + i], SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, i * 8);
}
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
//bCommWell = true;//通讯GOOD
}
}
else //ASCII协议解析
{
//保持寄存器 功能码0x03
string strTmpAddr, strTmpFun;
strTmpAddr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 1, 2);
strTmpFun = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 3, 2);
if (SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == ':' && mReceiveByteCount >= (WordLength * 4 + 11) && strTmpAddr == (SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1).ToString("X2") && strTmpFun == "03")
{
mTempStr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 0, WordLength * 4 + 11);
//赋值给全局MW变量 从起始地址开始
int nDownPos;
nDownPos = 0;
byte bTmpHi, bTmpLo;
string tmpData;
for (i = 0; i < WordLength; i++)
{
tmpData = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 7 + i * 4, 2);
bTmpHi = Convert.ToByte(tmpData, 16);
tmpData = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 9 + i * 4, 2);
bTmpLo = Convert.ToByte(tmpData, 16);
SerialPortManager.DicSerialPort[sp.PortName].WordValueArray[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, nDownPos] = (Int16)(bTmpHi * 256 + bTmpLo);
nDownPos = nDownPos + 1;
}
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
//bCommWell = true;//通讯GOOD
}
//输入寄存器04
if (SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == ':' && mReceiveByteCount >= (WordLength * 4 + 11) && strTmpAddr == (SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1).ToString("X2") && strTmpFun == "04")
{
mTempStr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 0, WordLength * 4 + 11);
//赋值给全局MW变量 从起始地址开始
//int nDownPos;
//nDownPos = 0;
//byte bTmpHi, bTmpLo;
//string tmpData;
//for (i = 0; i < iMWordLen; i++)
//{
// tmpData = System.Text.Encoding.ASCII.GetString(bData, 7 + i * 4, 2);
// bTmpHi = Convert.ToByte(tmpData, 16);
// tmpData = System.Text.Encoding.ASCII.GetString(bData, 9 + i * 4, 2);
// bTmpLo = Convert.ToByte(tmpData, 16);
// MWordVaue[CurrentAddr, nDownPos] = (UInt16)(bTmpHi * 256 + bTmpLo);
// nDownPos = nDownPos + 1;
//}
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
//bCommWell = true;//通讯GOOD
}
//输出线圈 功能码0x01
if (SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == ':' && mReceiveByteCount >= (iBitLen * 2 + 11) && strTmpAddr == (SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1).ToString("X2") && strTmpFun == "01")
{
byte bDataValue;
string tmpData;
mTempStr = "";
mTempStr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 0, iBitLen * 2 + 11);
//赋值给全局变量
for (i = 0; i < iBitLen; i++)
{
tmpData = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 7 + i * 2, 2);
bDataValue = Convert.ToByte(tmpData, 16);
ByteToBoolArray(SerialPortManager.DicSerialPort[sp.PortName], bDataValue, SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, i * 8);
}
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
//bCommWell = true;//通讯GOOD
}
//输入线圈 功能码0x02
if (SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == ':' && mReceiveByteCount >= (iBitLen * 2 + 11) && strTmpAddr == (SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1).ToString("X2") && strTmpFun == "02")
{
//byte bDataValue;
//string tmpData;
mTempStr = "";
mTempStr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 0, iBitLen * 2 + 11);
////赋值给全局变量
//for (i = 0; i < iMBitLen; i++)
//{
// tmpData = System.Text.Encoding.ASCII.GetString(bData, 7 + i * 2, 2);
// bDataValue = Convert.ToByte(tmpData, 16);
// ByteToBArray(bDataValue, CurrentAddr, i * 8);
//}
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
//bCommWell = true;//通讯GOOD
}
}
}
catch (Exception ex)
{
string str = "串口接收数据错误:";
Msg.Show($"{str}\r\n{ex}", $"{str}\r\nSerial port receiving data error:\r\n{ex}",
$"{str}\r\nCổng nối tiếp nhận dữ liệu lỗi:\r\n{ex}", "Error", msgicon: MessageBoxIcon.Error);
}
}
// MODBUS读保持寄存器 iAddress 开始地址(0开始),iLength 寄存器数量
//主站请求:01 03 00 00 00 06 70 08
//地址 1字节
//功能码 1字节 0x03
//起始寄存器地址 2字节 0x0000~0x0005
//寄存器数量 2字节 0x01~0x06
//CRC校验 2字节
///
/// MODBUS读保持寄存器
///
/// 从站站号
/// 开始地址
/// 寄存器数量
public void ReadKeepReg(StSerialPort st, int iStation, long iAddress, int iLength, ref string str)
{
try
{
int i;
iWordStartAddr = iAddress;
WordLength = iLength;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);//如果前一次接收没完成,则comBusing为true,则延时250ms
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x03;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
SendCommand[5] = (byte)(iLength % 256);
Crc16(SendCommand, 6);
SendCommand[6] = CRCLo;
SendCommand[7] = CRCHi;
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
for (i = 0; i < 8; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
}
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
Thread.Sleep(200);
str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void ReadKeepRegAscii(StSerialPort st, int iStation, long iAddress, int iLength)
{
try
{
int i;
string strLRC;
string strSendCommand;
iWordStartAddr = iAddress;
WordLength = iLength;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x03;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
SendCommand[5] = (byte)(iLength % 256);
strSendCommand = "";
for (i = 0; i < 6; i++)
{
strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
}
strLRC = LRC(strSendCommand);
strSendCommand = ":" + strSendCommand + strLRC;
strSendCommand = strSendCommand + "\r" + "\n";
System.Diagnostics.Trace.WriteLine(strSendCommand);
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// MODBUS读输入寄存器 iAddress 开始地址(0开始),iLength 寄存器数量
//主站请求:01 04 00 00 00 06 70 08
//地址 1字节
//功能码 1字节 0x04
//起始寄存器地址 2字节 0x0000~0x0005
//寄存器数量 2字节 0x01~0x06
//CRC校验 2字节
///
/// MODBUS读输入寄存器(三菱PLC用不到)
///
/// 从站站号
/// 开始地址
/// 寄存器数量
public void ReadInputReg(StSerialPort st, int iStation, long iAddress, int iLength)
{
try
{
int i;
iWordStartAddr = iAddress;
WordLength = iLength;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x04;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
SendCommand[5] = (byte)(iLength % 256);
Crc16(SendCommand, 6);
SendCommand[6] = CRCLo;
SendCommand[7] = CRCHi;
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
for (i = 0; i < 8; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
}
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void ReadInputRegAscii(StSerialPort st, int iStation, long iAddress, int iLength)
{
try
{
int i;
string strLRC;
string strSendCommand;
iWordStartAddr = iAddress;
WordLength = iLength;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x04;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
SendCommand[5] = (byte)(iLength % 256);
strSendCommand = "";
for (i = 0; i < 6; i++)
{
strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
}
strLRC = LRC(strSendCommand);
strSendCommand = ":" + strSendCommand + strLRC;
strSendCommand = strSendCommand + "\r" + "\n";
System.Diagnostics.Trace.WriteLine(strSendCommand);
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// MODBUS读输出状态 iAddress 开始地址(0开始),iLength 输出位数量
//主站请求:01 01 00 00 00 07 70 08
//地址 1字节
//功能码 1字节 0x01
//起始寄存器地址 2字节 0x0000~0x0005
//寄存器数量 2字节 0x01~0x06
//CRC校验 2字节
///
/// MODBUS读输出线圈状态
///
/// 从站站号
/// 开始地址
/// 输出位数量
public void ReadOutputStatus(StSerialPort st, int iStation, long iAddress, int iLength, ref string str)
{
try
{
int i;
//一个字节代表8个位状态
//一个字节代表8个位状态
if (iLength % 8 == 0)
{
iBitLen = iLength / 8;
}
else
{
iBitLen = iLength / 8 + 1;
}
iBitStartAddr = iAddress;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x01;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
SendCommand[5] = (byte)(iLength % 256);
Crc16(SendCommand, 6);
SendCommand[6] = CRCLo;
SendCommand[7] = CRCHi;
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
for (i = 0; i < 8; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
}
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
Thread.Sleep(200);
str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void ReadOutputStatusAscii(StSerialPort st, int iStation, long iAddress, int iLength)
{
try
{
int i;
//一个字节代表8个位状态
//一个字节代表8个位状态
if (iLength % 8 == 0)
{
iBitLen = iLength / 8;
}
else
{
iBitLen = iLength / 8 + 1;
}
string strLRC;
string strSendCommand;
iBitStartAddr = iAddress;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x01;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
SendCommand[5] = (byte)(iLength % 256);
strSendCommand = "";
for (i = 0; i < 6; i++)
{
strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
}
strLRC = LRC(strSendCommand);
strSendCommand = ":" + strSendCommand + strLRC;
strSendCommand = strSendCommand + "\r" + "\n";
System.Diagnostics.Trace.WriteLine(strSendCommand);
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// MODBUS读输入状态 iAddress 开始地址(0开始),iLength 输入位数量
//主站请求:01 02 00 00 00 07 70 08
//地址 1字节
//功能码 1字节 0x02
//起始寄存器地址 2字节 0x0000~0x0005
//寄存器数量 2字节 0x01~0x06
//CRC校验 2字节
///
/// MODBUS读输入状态
///
/// 从站站号
/// 开始地址
/// 输入位数量
public void ReadInputStatus(StSerialPort st, int iStation, long iAddress, int iLength, ref string str)
{
try
{
int i;
//一个字节代表8个位状态
//一个字节代表8个位状态
if (iLength % 8 == 0)
{
iBitLen = iLength / 8;
}
else
{
iBitLen = iLength / 8 + 1;
}
iBitStartAddr = iAddress;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x02;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
SendCommand[5] = (byte)(iLength % 256);
Crc16(SendCommand, 6);
SendCommand[6] = CRCLo;
SendCommand[7] = CRCHi;
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
for (i = 0; i < 8; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
}
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
Thread.Sleep(200);
str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void ReadInputStatusAscii(StSerialPort st, int iStation, long iAddress, int iLength)
{
try
{
int i;
//一个字节代表8个位状态
if (iLength % 8 == 0)
{
iBitLen = iLength / 8;
}
else
{
iBitLen = iLength / 8 + 1;
}
string strLRC;
string strSendCommand;
iBitStartAddr = iAddress;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x02;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
SendCommand[5] = (byte)(iLength % 256);
strSendCommand = "";
for (i = 0; i < 6; i++)
{
strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
}
strLRC = LRC(strSendCommand);
strSendCommand = ":" + strSendCommand + strLRC;
strSendCommand = strSendCommand + "\r" + "\n";
System.Diagnostics.Trace.WriteLine(strSendCommand);
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// MODBUS强制单线圈 iAddress 开始地址(0开始)
//主站请求:01 05 00 00 FF 00 70 08
//地址 1字节
//功能码 1字节 0x05
//起始寄存器地址 2字节 0x0000~0x0005
//寄存器数量 2字节 0x01~0x06
//CRC校验 2字节
///
/// MODBUS强制单线圈
///
/// 从站站号
/// 开始地址
public void ForceOn_Circle(StSerialPort st, int iStation, long iAddress, ref string str)
{
try
{
int i;
iWordStartAddr = iAddress;
//iMWordLen = 0;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x05;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = 0xff;
SendCommand[5] = 0x00;
Crc16(SendCommand, 6);
SendCommand[6] = CRCLo;
SendCommand[7] = CRCHi;
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
for (i = 0; i < 8; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
}
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
Thread.Sleep(200);
str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void ForceOnAscii(StSerialPort st, int iStation, long iAddress)
{
try
{
int i;
string strSendCommand, strLRC;
iWordStartAddr = iAddress;
//iMWordLen = 0;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x05;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = 0xff;
SendCommand[5] = 0x00;
strSendCommand = "";
for (i = 0; i < 6; i++)
{
strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
}
strLRC = LRC(strSendCommand);
strSendCommand = ":" + strSendCommand + strLRC;
strSendCommand = strSendCommand + "\r" + "\n";
//System.Diagnostics.Trace.WriteLine(strSendCommand);
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// MODBUS复位单线圈 iAddress 开始地址(0开始)
//主站请求:01 05 00 00 00 00 70 08
//地址 1字节
//功能码 1字节 0x05
//起始寄存器地址 2字节 0x0000~0x0005
//寄存器数量 2字节 0x01~0x06
//CRC校验 2字节
public void ForceOff_Circle(StSerialPort st, int iStation, long iAddress, ref string str)
{
try
{
int i;
iWordStartAddr = iAddress;
//iMWordLen = 0;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x05;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = 0x00;
SendCommand[5] = 0x00;
Crc16(SendCommand, 6);
SendCommand[6] = CRCLo;
SendCommand[7] = CRCHi;
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
for (i = 0; i < 8; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
}
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
Thread.Sleep(200);
str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void ForceOffAscii(StSerialPort st, int iStation, long iAddress)
{
try
{
int i;
string strSendCommand, strLRC;
iWordStartAddr = iAddress;
//iMWordLen = 0;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x05;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = 0x00;
SendCommand[5] = 0x00;
strSendCommand = "";
for (i = 0; i < 6; i++)
{
strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
}
strLRC = LRC(strSendCommand);
strSendCommand = ":" + strSendCommand + strLRC;
strSendCommand = strSendCommand + "\r" + "\n";
//System.Diagnostics.Trace.WriteLine(strSendCommand);
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// MODBUS预置单字寄存器 iAddress 开始地址(0开始),iHiValue 数据
//主站请求:01 06 00 00 00 06 70 08
//地址 1字节
//功能码 1字节 0x06
//起始寄存器地址 2字节 0x0000~0x0005
//寄存器数量 2字节 0x01~0x06
//CRC校验 2字节
///
/// MODBUS预置单字寄存器
///
/// 从站地址
/// 开始地址
/// 值
public void PreSetKeepReg(StSerialPort st, int iStation, long iAddress, UInt16 SetValue, ref string str)
{
try
{
int i;
iWordStartAddr = iAddress;
//iMWordLen = 0;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x06;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((SetValue - SetValue % 256) / 256); ;
SendCommand[5] = (byte)(SetValue % 256); ;
Crc16(SendCommand, 6);
SendCommand[6] = CRCLo;
SendCommand[7] = CRCHi;
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
for (i = 0; i < 8; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
}
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
Thread.Sleep(200);
str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void PreSetKeepRegAscii(StSerialPort st, int iStation, long iAddress, UInt16 SetValue)
{
try
{
int i;
string strSendCommand, strLRC;
iWordStartAddr = iAddress;
//iMWordLen = 0;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[8];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x06;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = (byte)((SetValue - SetValue % 256) / 256); ;
SendCommand[5] = (byte)(SetValue % 256); ;
strSendCommand = "";
for (i = 0; i < 6; i++)
{
strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
}
strLRC = LRC(strSendCommand);
strSendCommand = ":" + strSendCommand + strLRC;
strSendCommand = strSendCommand + "\r" + "\n";
//System.Diagnostics.Trace.WriteLine(strSendCommand);
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// MODBUS预置双字寄存器 iAddress 开始地址(0开始)
//主站请求:01 06 00 00 00 10 70 08
//地址 1字节
//功能码 1字节 0x10
//起始寄存器地址 2字节 0x0000~0x0005
//寄存器数量 2字节 0x01~0x06
//CRC校验 2字节
///
/// MODBUS预置双字寄存器
///
/// 从站站号
/// 开始地址
/// 值
public void PreSetFloatKeepReg(StSerialPort st, int iStation, long iAddress, float SetValue, ref string str)
{
try
{
int i;
byte[] bSetValue = new byte[4];
bSetValue = BitConverter.GetBytes(SetValue);
//bSetValue = &SetValue;
iWordStartAddr = iAddress;
//iMWordLen = 0;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[13];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x10;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = 0x00;
SendCommand[5] = 0x02;
SendCommand[6] = 0x04;
SendCommand[7] = bSetValue[1];
SendCommand[8] = bSetValue[0];
SendCommand[9] = bSetValue[3];
SendCommand[10] = bSetValue[2];
Crc16(SendCommand, 11);
SendCommand[11] = CRCLo;
SendCommand[12] = CRCHi;
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 13);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
for (i = 0; i < 13; i++)
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
}
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
Thread.Sleep(200);
str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void PreSetFloatKeepRegAscii(StSerialPort st, int iStation, long iAddress, float SetValue)
{
try
{
int i;
string strSendCommand, strLRC;
byte[] bSetValue = new byte[4];
bSetValue = BitConverter.GetBytes(SetValue);
//bSetValue = &SetValue;
iWordStartAddr = iAddress;
//iMWordLen = 0;
if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
byte[] SendCommand = new byte[13];
SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
SendCommand[0] = (byte)iStation;
SendCommand[1] = 0x10;
SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
SendCommand[3] = (byte)(iAddress % 256);
SendCommand[4] = 0x00;
SendCommand[5] = 0x02;
SendCommand[6] = 0x04;
SendCommand[7] = bSetValue[1];
SendCommand[8] = bSetValue[0];
SendCommand[9] = bSetValue[3];
SendCommand[10] = bSetValue[2];
strSendCommand = "";
for (i = 0; i < 11; i++)
{
strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
}
strLRC = LRC(strSendCommand);
strSendCommand = ":" + strSendCommand + strLRC;
strSendCommand = strSendCommand + "\r" + "\n";
//System.Diagnostics.Trace.WriteLine(strSendCommand);
//发送指令。
SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
mReceiveByteCount = 0;
//strUpData = "";
SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
tmrTimeOut.Enabled = true;//启动超时检测定时器
SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
//bCommWell = false;//设置本次通讯标志
}
catch (Exception ex)
{
//strErrMsg = ex.Message.ToString();
MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
//字节变量返回8为二进制字符串
///
/// 字节变量返回8位二进制字符串
///
/// 字节变量值
///
public string ByteToBinary(byte bValue)
{
string strTemp;
int i, strLen;
strTemp = System.Convert.ToString(bValue, 2);
if (strTemp.Length < 8)
{
strLen = strTemp.Length;
for (i = 0; i < 8 - strLen; i++)
{
strTemp = "0" + strTemp;
}
}
return strTemp;
}
//字节变量赋值给bool型全局数组
///
/// 字节变量赋值给bool型全局数组
///
/// 字节变量值
/// 从站地址
/// 赋值开始数组索引值
public void ByteToBoolArray(StSerialPort st, byte bValue, int iAddr, int pos)
{
string strBinary;
strBinary = ByteToBinary(bValue);
for (int i = 0; i < 8; i++)
{
if (strBinary.Substring(7 - i, 1) == "1")
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].BitVaueArray[iAddr, pos + i] = true;
}
else
{
SerialPortManager.DicSerialPort[st.serialPort.PortName].BitVaueArray[iAddr, pos + i] = false;
}
}
}
//定时器超时事件
public void commTimeOut(object source, System.Timers.ElapsedEventArgs e)
{
SerialPort sp = source as SerialPort;
//if (bCommWell == false)
{
SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = true;//设置本地址通讯故障
SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = "";
}
tmrTimeOut.Enabled = false;
SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//设置串口忙标志
}
}
}