• 大小: 3.05KB
    文件类型: .zip
    金币: 1
    下载: 0 次
    发布日期: 2020-12-14
  • 语言: C#
  • 标签: Modbus  RTU  帮助  通讯  

资源简介

一个类解决通讯问题


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

评论

共有 条评论