zoukankan      html  css  js  c++  java
  • RS485转RS232

    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;
            }
        
        }
    }
  • 相关阅读:
    栈 队列 递归 算法的GO语言实现
    数组与链表算法
    树算法的GO语言实现
    排序算法的GO语言实现
    如何抵抗记忆的衰退
    C程序运行的背后(2)
    C程序运行的背后(1)
    Shell脚本:“syntax error:unexpected end of file”
    电线的粗细与电流的大小怎么算?电流的大小与电器的功率有什么关系? 如何根据电流的大小选择铜质电线的粗细
    Word2019发布文章到博客园
  • 原文地址:https://www.cnblogs.com/qq1151219115/p/10937022.html
Copyright © 2011-2022 走看看