哪位大神有C#Rs485通讯代码?
2个回答
展开全部
我有!我是用485转232的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace serial
{
public class ModBus
{
/// <summary>
/// modbus状态
/// </summary>
public static string modbusStatus;
/// <summary>
/// 定义SerialPort变量
/// </summary>
public static SerialPort Port = new SerialPort();
/// <summary>
/// 打开串口
/// </summary>
/// <param name="m_Port">串口号</param>
/// <param name="BaudRate">波特率</param>
/// <param name="m_dataBits">数据位</param>
/// <param name="m_Parity">奇偶校验</param>
/// <param name="m_StopBits">停止位</param>
/// <returns>返回BOOL型,True为成功,False为失败</returns>
public static bool OpenPort(string m_Port, int BaudRate, int m_dataBits, Parity m_Parity, StopBits m_StopBits)
{
if (Port.IsOpen)
{
return true;
}
else
{
Port.PortName = m_Port;
Port.BaudRate = BaudRate;
Port.DataBits = m_dataBits;
Port.Parity = m_Parity;
Port.StopBits = m_StopBits;
Port.Open();
if (Port.IsOpen)
{
return true;
}
else
{
return false;
}
}
}
/// <summary>
/// 关闭串口
/// </summary>
/// <returns>返回BOOL型,True为成功,False为失败</returns>
public static bool PortClose()
{
if (Port.IsOpen)
{
Port.Close();
return true;
}
else
{
return false;
}
}
public static void GetCRC(byte[] message, byte[] CRC)
{
//Function expects a modbus message of any length as well as a 2 byte CRC array in which to
//return the CRC values:
ushort CRCFull = 0xFFFF;
byte CRCHigh = 0xFF, CRCLow = 0xFF;
char CRCLSB;
for (int i = 0; i < (message.Length) -2; i++)
{
CRCFull = (ushort)(CRCFull ^ message[i]);
for (int j = 0; j < 8; j++)
{
CRCLSB = (char)(CRCFull & 0x0001);
CRCFull = (ushort)((CRCFull >> 1) & 0x7FFF);
if (CRCLSB == 1)
CRCFull = (ushort)(CRCFull ^ 0xA001);
}
}
CRC[1] = CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
}
/// <summary>
/// CRC16算法
/// </summary>
/// <param name="te">原始数组</param>
/// <param name="message">保存变量</param>
public static void BuildMessage(byte[] te, ref byte[] message)
{
//Array to receive CRC bytes:
byte[] CRC = new byte[2];
for (int i = 0; i < te.Length; i++)
{
message[i] = te[i];
}
GetCRC(message, CRC);
message[message.Length - 2] = CRC[0];
message[message.Length - 1] = CRC[1];
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="m_date">需写入的数据</param>
/// <param name="type">操作类型0为多输出口控制与open参数不共用,1为单控制口输出open为255时线圈闭合0时线圈释放</param>
/// <param name="open">1为单控制口输出open为255时线圈闭合0时线圈释放</param>
/// <returns>返回True或false</returns>
public static bool SendMessage(byte m_date,int type,bool open=true)
{
if (!Port.IsOpen)
{
return false;
}
else
{
switch (type)
{
case 0://多个DO输出控制数据位{ 地址, 功能, 线圈起始地址前位, 线圈起始地址后位, 线圈结束地址前位, 线圈结束地址后位, 数据字节, 线圈状态 };
byte[] data = new byte[10];
byte[] dd = { 1, 15, 0, 0, 0, 8, 1, m_date };
ModBus.BuildMessage(dd, ref data);
Port.Write(data, 0, data.Length);
break;
case 1://单个控制输出{ 地址, 功能, 线圈起始地址前位, 需控制的线圈地址, 开关状态255为开0为关, 线圈开关后位 };
byte[] data_one = new byte[8];
byte temp0;
if (open)
{ temp0 = 255; }
else
{ temp0 = 0; }
byte[] dd1 = { 1, 5, 0, m_date, temp0, 0 };
ModBus.BuildMessage(dd1, ref data_one);
Port.Write(data_one, 0, data_one.Length);
break;
case 2:
byte[] getsig = new byte[8];
byte[] getsige = { 1, 2, 0, 0, 0, m_date };
ModBus.BuildMessage(getsige, ref getsig);
Port.Write(getsig, 0, getsig.Length);
break;
case 3:
break;
}
return true;
}
}
#region Check Response
private static bool CheckResponse(byte[] response)
{
//Perform a basic CRC check:
byte[] CRC = new byte[2];
GetCRC(response, CRC);
if (CRC[0] == response[response.Length - 2] && CRC[1] == response[response.Length - 1])
return true;
else
return false;
}
#endregion
#region Get Response
private static void GetResponse(ref byte[] response)
{
//There is a bug in .Net 2.0 DataReceived Event that prevents people from using this
//event as an interrupt to handle data (it doesn't fire all of the time). Therefore
//we have to use the ReadByte command for a fixed length as it's been shown to be reliable.
for (int i = 0; i < response.Length; i++)
{
response[i] = (byte)(Port.ReadByte());
}
}
#endregion
public static bool GetModbusData(ref byte[] values)
{
if (Port.IsOpen)
{
int count = Port.BytesToRead;
if (count > 0)
{
byte[] readBuffer = new byte[count];
GetResponse(ref readBuffer);
// CRC 验证
if (CheckResponse(readBuffer))
{
//显示输入数据
values = readBuffer;
Port.DiscardInBuffer();
return true;
}
else
{
Port.DiscardInBuffer();
return false;
}
}
else return false;
}
else return false;
}
}
}
2015-06-06 · 知道合伙人软件行家
关注
追问
整个Debug,没有源代码。
追答
自己反编译下就不行了吗
下个Telerik JustDecompile 免费的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询