RS485串口通讯

using System.IO.Ports;
namespace RamonCWQY
{
class RS485Service
{
public static SerialPort SerialPort = null;
public int[] responseArry = null; //返回的数据

    /// <summary>
    /// 打开串口
    /// </summary>
    /// <param name="comName">串口名称</param>
    /// <param name="baud">比特率</param>
    /// <returns></returns>
    public static SerialPort OpenPort(string comName, int baud)
    {
        try
        {
            //串口未打开
            if (SerialPort == null || !SerialPort.IsOpen)
            {
                SerialPort = new SerialPort();
                //串口名称
                SerialPort.PortName = comName;
                //波特率
                SerialPort.BaudRate = baud;
                //数据位
                SerialPort.DataBits = 8;
                //停止位
                SerialPort.StopBits = StopBits.One;
                //校验位
                SerialPort.Parity = Parity.None;
                //打开串口
                SerialPort.Open();

                //串口数据接收事件实现
                //SerialPort.DataReceived += new SerialDataReceivedEventHandler(ReceiveData);

                return SerialPort;
            }
            return SerialPort;
        }
        catch (System.Exception)
        {
            throw;
        }
    }

    /// <summary>
    /// 关闭端口
    /// </summary>
    public static void ClosePort()
    {
        SerialPort.Close();
        SerialPort = null;
    }

    #region 读数据

    /// <summary>
    /// 根据参数编号进行读取
    /// </summary>
    /// <param name="iParamNo">要读参数的代号(十进制)</param>
    /// <param name="iDevAdd">仪表地址参数值</param>
    /// <param name="response">返回的值</param>
    /// <returns></returns>
    public static int[] ReadParam(byte iParamNo, byte iDevAdd)
    {
        try
        { 

            if (SerialPort == null || !SerialPort.IsOpen)
            {
                OpenPort("COM3", 9600);
            }

            //第一步:拼接报文
            ByteArray byteArray = new ByteArray();
            byteArray.Add((byte)(128 + iDevAdd));
            byteArray.Add((byte)(128 + iDevAdd));
            byteArray.Add(82);
            byteArray.Add(iParamNo);
            byteArray.Add(new byte[] { 0, 0 });
            byteArray.Add(GetSendParity(iParamNo, iDevAdd));

            //第二步: 发送报文  
            SerialPort.Write(byteArray.array, 0, byteArray.array.Length);

            System.Threading.Thread.Sleep(200);

            //第3步:获取数据
            int n = SerialPort.BytesToRead;
            byte[] original = new byte[n];
            SerialPort.Read(original, 0, n);

            //第4步:解析数据
            if (original == null || original.Length <10)
            {
                return null;
            }
            int [] response = TranslateInfo(original); 
            return response;
        }
        catch (System.Exception)
        {
            throw;
        } 
    }
     
    /// <summary>
    /// 读校验码
    /// </summary>
    /// <param name="iParamNo">要读参数的代号</param>
    /// <param name="iDevAdd">仪表地址参数值</param>
    /// <returns></returns>
    private static byte[] GetSendParity(byte iParamNo, byte iDevAdd)
    {
        int Res = iParamNo * 256 + 82 + iDevAdd;
        byte[] crc = new byte[2];
        crc[0] = (byte)(Res % 256);
        crc[1] = (byte)(Res / 256);
        return crc;
    }
    #endregion


    #region 写数据
    /// <summary>
    /// 根据编号的数字写入参数
    /// </summary>
    /// <param name="iParamNo"></param>
    /// <param name="iValue"></param>
    /// <param name="iDevAdd"></param>
    /// <returns></returns>
    public static int[] SetParam(byte iParamNo, int iValue, byte iDevAdd)
    {
        //第一步:拼接报文 
        ByteArray byteArray = new ByteArray();
        byteArray.Add((byte)(128 + iDevAdd));
        byteArray.Add((byte)(128 + iDevAdd));
        byteArray.Add(67);
        byteArray.Add((byte)iParamNo);
        byteArray.Add((byte)(iValue % 256));
        byteArray.Add((byte)(iValue / 256));
        byteArray.Add(GetReceiveParity(iParamNo, iValue, iDevAdd));
          
        //第二步: 发送报文  
        SerialPort.Write(byteArray.array, 0, byteArray.array.Length);

        System.Threading.Thread.Sleep(200);

        //第3步:获取数据
        int n = SerialPort.BytesToRead;
        byte[] original = new byte[n];
        SerialPort.Read(original, 0, n);

        //第4步:解析数据
        if (original == null)
        {
            return null;
        } 
        int [] response = TranslateInfo(original);
        return response;
    }

    /// <summary>
    /// 写校验码
    /// </summary>
    /// <param name="iParamNo">要写参数的代号</param>
    /// <param name="iValue">要写的参数值</param>
    /// <param name="iDevAdd">仪表地址参数值</param>
    /// <returns></returns>
    private static byte[] GetReceiveParity(byte iParamNo, int iValue, byte iDevAdd)
    {
        int Res = iParamNo * 256 + 67 + iValue + iDevAdd;
        byte[] crc = new byte[2];
        crc[0] = (byte)(Res % 256);
        crc[1] = (byte)(Res / 256);
        return crc;
    }
    #endregion


    /// <summary>
    /// 解析报文
    /// </summary>
    /// <param name="result"></param>
    /// <returns></returns>
    public static int[] TranslateInfo(byte[] result)
    {
        if (result.Length <10)
        {
            return null;
        }
        int[] resultArray = new int[3];
        resultArray[0] = (result[1] * 256 + result[0])/10;
        resultArray[1] = (result[3] * 256 + result[2])/10;
        return resultArray;
    } 
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值