在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → Modbus通讯 串口通讯

Modbus通讯 串口通讯

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:0.17M
  • 下载次数:114
  • 浏览次数:694
  • 发布时间:2021-01-08
  • 实例类别:C#语言基础
  • 发 布 人:李钊闻
  • 文件格式:.zip
  • 所需积分:5
 相关标签: Modbus 串口通讯 OD 串口 通讯

实例介绍

【实例简介】Modbus通讯 串口通讯
【实例截图】from clipboard

【核心代码】



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;



namespace COMTool
{
    
    public partial class SetCOMtool : Form
    {
        public int PortNum;
        public int BaudRate;
        public byte ByteSize;
        public byte BParity; // 0-4=no,odd,even,mark,space   

        /*
         * 1. even 每个字节传送整个过程中bit为1的个数是偶数个(校验位调整个数)
         * 2. odd 每个字节穿送整个过程中bit为1的个数是奇数个(校验位调整个数)
         * 3. noparity没有校验位
         * 4. space 校验位总为0
         * 5. mark 校验位总为1*/
        public byte BStopBits; // 0,1,2 = 1, 1.5, 2   
        public int ReadTimeout;

       
        bool  BPortSet = true, BIpSet = false, BPortSetMode = false, BIpSetMode = false,BPortSetRead = false, BIpSetRead = false;
        public SetCOMtool()
        {
            InitializeComponent();
            //信息显示
            this.lMessage.Columns.Add("状态信息");
            this.lMessage.Columns[0].Width = 200;
            this.lMessage.View = System.Windows.Forms.View.Details;
            this.lMessage.BeginUpdate();   //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度
            this.lMessage.Items.Add("软件启动");
            this.lMessage.EnsureVisible(this.lMessage.Items.Count - 1);
            this.lMessage.EndUpdate();  //结束数据处理,UI界面一次性绘制。
            //委托
            serialPort1.DataReceived = new SerialDataReceivedEventHandler(serialPort_DataReceived);
            //获取端口 初始化下拉列表
           

        }
        private void Form1_Load(object sender, EventArgs e)
        {
            List<string> LBaudRate = new List<string>();//300、600、1200、2400、4800、9600、19200、38400、43000、56000、57600、115200
            LBaudRate.Add("1200");
            LBaudRate.Add("2400");
            LBaudRate.Add("4800");
            LBaudRate.Add("9600");
            LBaudRate.Add("14400");
            LBaudRate.Add("19200");
            LBaudRate.Add("38400");
            LBaudRate.Add("57600");
            LBaudRate.Add("115200");
            cBaudRate.DataSource = LBaudRate;
            List<string> LParity = new List<string>();
            LParity.Add("None");
            LParity.Add("Odd");
            LParity.Add("Even");
            //   LParity.Add("Mark");
            //   LParity.Add("Space");
            cParity.DataSource = LParity;
          

            List<string> LDataBits = new List<string>();
            LDataBits.Add("7");
            LDataBits.Add("8");
         

            LDataBits.Clear();
            LDataBits.Add("8");
            LDataBits.Add("7");
            cDataBits.DataSource = LDataBits;

            List<string> LStopBits = new List<string>();
            LStopBits.Add("1");
            LStopBits.Add("2");
            //   LStopBits.Add("1.5");
            cStopBits.DataSource = LStopBits;
           
         

            List<string> LString = new List<string>();
            LString.Add("兼容远程配置");
            LString.Add("不兼容远程配置");
         
            LString.Clear();

            LString.Add("TCP");
            LString.Add("UDP");
         
            LString.Clear();

            string[] str = System.IO.Ports.SerialPort.GetPortNames();
            if (str.Length == 0)
            {
                MessageBox.Show("未找到本机串口", "提示");
                return;
            }
            cPortName.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            cPortName.SelectedIndex = 0;

        }

        private void BOpenPort_Click(object sender, EventArgs e)
        {
            if (BOpenPort.Text == "打开串口")
            {
                if (OpenPort())
                {
                    BOpenPort.Text = "关闭串口";
                    cPortName.Enabled = false;
                    cParity.Enabled = false;
                    cBaudRate.Enabled = false;
                    cDataBits.Enabled = false;
                    cStopBits.Enabled = false;

                    SetMessage("打开串口!");

                    if (!BPortSetRead&BPortSet)
                    {
                        BPortSetRead = true;
                        gen_read(0xFE,0x03, 0x00,0x1A,8);
                    }
                    else if (!BIpSetRead & BIpSet)
                    {
                        BIpSetRead = true;
                        gen_read(0xFE, 0x03, 0x1B, 0xD1, 8);
                    }
                }
                else
                {
                    MessageBox.Show("串口打开失败!", "提示");
                    SetMessage("串口打开失败!");
                }

            }
            else
            {
                try
                {
                    serialPort1.Close();
                    BOpenPort.Text = "打开串口";
                    cPortName.Enabled = true;
                    cParity.Enabled = true;
                    cBaudRate.Enabled = true;
                    cDataBits.Enabled = true;
                    cStopBits.Enabled = true;
                    BPortSetRead = false;
                    BIpSetRead = false;
                    SetMessage("关闭串口!");
                  
                }
                catch (Exception err)
                {
                    MessageBox.Show("串口无法关闭!", "提示");
                }              
              
            }


        }
        //数据接收使用的代理
        private delegate void myDelegate(byte[] readBuffer);
        //显示接收的数据
        private void SetText(byte[] readBuffer)
        {
            //将byte 转换成string 用于显示
            string readstr = string.Empty;
            if (readBuffer != null)
            {
               ushort crc = CRC16(readBuffer, 0, readBuffer.Length - 3);
                if (readBuffer[readBuffer.Length - 2] == WORD_HI(crc) && readBuffer[readBuffer.Length - 1] == WORD_LO(crc))//crc校验
                {
                    SetMessage("reve:  " ToHexString(readBuffer));
                    // serialPort1.Write(readstr);
                }
                else

                {
                    SetMessage("CRC校验错误:  " readstr);
                    return;
                }

                if (BPortSetMode && readBuffer.Length<30)//设置设备参数
                { }
                else if (BIpSetMode)//设置网络参数
                { }
            }  
        }
        void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            myDelegate md = new myDelegate(SetText);
            try
            {
                if (serialPort1.IsOpen == true)
                {
                    int count = serialPort1.BytesToRead;
                    if (count > 0)
                    {
                        byte[] readBuffer = new byte[count];
                        serialPort1.Read(readBuffer, 0, count);//读取串口数据
                   //     serialPort1.Write(readBuffer, 0, count);
                        Invoke(md, readBuffer);
                    }
                }
            }
            catch (Exception err)
            {
                throw err;
            }

        }
        private void SetMessage(string SMessage)
        {
            this.lMessage.BeginUpdate();   //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度
            this.lMessage.Items.Add(SMessage);
            this.lMessage.EnsureVisible(this.lMessage.Items.Count - 1);
            this.lMessage.EndUpdate();  //结束数据处理,UI界面一次性绘制。
        }
        private bool OpenPort()
        {
            serialPort1.PortName = cPortName.Text;
            //波特率
            serialPort1.BaudRate = Convert.ToInt32(cBaudRate.Text);
            //奇偶
            switch (cParity.SelectedIndex)
            {
                case 0: serialPort1.Parity = Parity.None; break;
                case 1: serialPort1.Parity = Parity.Odd; break;
                case 2: serialPort1.Parity = Parity.Even; break;
                case 3: serialPort1.Parity = Parity.Mark; break;
                case 4: serialPort1.Parity = Parity.Space; break;
                default: serialPort1.Parity = Parity.None; break;
            }
            //数据位
            serialPort1.DataBits = Convert.ToInt32(cDataBits.Text);
            //停止位
            switch (cStopBits.SelectedIndex)
            {
                case 0: serialPort1.StopBits = StopBits.One; break;
                case 1: serialPort1.StopBits = StopBits.Two; break;
                case 2: serialPort1.StopBits = StopBits.OnePointFive; break;
                default: serialPort1.StopBits = StopBits.None; break;
            }
            try
            {
                serialPort1.Open();
                if (serialPort1.IsOpen)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception err)
            {

                //        MessageBox.Show(err.ToString(), "提示");
                return false;
            }
          
           
        }

      

        /*生成读数据命令, 返回命令长度*/
        int gen_read(byte mdaddr, byte R_CMD,
                         ushort min_reg,
                          ushort data_len,
            int R_CMD_LEN)
        {

      //  R_CMD                //读取数据命令字
      //  R_CMD_LEN = 8;              //命令长度

        ushort crc;
        byte[] desc =new byte[8];
        
      //  查询命令格式
      //  站点号(1 byte)命令字(1 byte)开始寄存器地址(2 byte)查询长度(2 byte)CRC(2 byte)
       
        //设置模块号
        desc[0] = mdaddr;
        //设置命令字
        desc[1] = R_CMD;

        //设置开始寄存器
        desc[2] = WORD_HI(min_reg);
        desc[3] = WORD_LO(min_reg);

        //设置数据长度
        desc[4] = WORD_HI(data_len);
        desc[5] = WORD_LO(data_len);

        //设置 CRC
        crc = CRC16(desc, 0, R_CMD_LEN-3);

        desc[6] = WORD_HI(crc);
        desc[7] = WORD_LO(crc);
        serialPort1.Write(desc, 0, 8);
       
        SetMessage("send:  " ToHexString(desc));

        return R_CMD_LEN;
    }
        #region
        private static readonly byte[] _auchCRCHi = new byte[]//crc高位表
        {
            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[] _auchCRCLo = new byte[]//crc低位表
        {
            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
        };
        #endregion

        public static ushort CRC16(Byte[] buffer, int Sset, int Eset)
        {
            byte crcHi = 0xff;  // 高位初始化

            byte crcLo = 0xff;  // 低位初始化

            for (int i = Sset; i <=Eset ; i )
            {
                int crcIndex = crcHi ^ buffer[i]; //查找crc表值

                crcHi = (byte)(crcLo ^ _auchCRCHi[crcIndex]);
                crcLo = _auchCRCLo[crcIndex];
            }
                     return (ushort)(crcHi << 8 | crcLo);
        }


        //取Word变量的高位字节、低位字节
        public static byte WORD_LO(ushort crcCLo)
         {
             crcCLo=(ushort)(crcCLo & 0X00FF);
             return (byte)crcCLo;
         }

         public static byte WORD_HI(ushort crcHI)
         {
             crcHI=(ushort)(crcHI>> 8& 0X00FF);
             return (byte) crcHI;
         }
        //取DWord变量的高位字节、低位字节的宏
         public static ushort DWORD_LO(ushort crcCLo)
         {
             crcCLo=(ushort)(crcCLo & 0X0000FFFF);
             return crcCLo;
         }

         public static ushort DWORD_HI(ushort crcHI)
         {
             crcHI=(ushort)(crcHI>> 16& 0X0000FFFF);
             return crcHI;
         }

        //判断是否是BCD码
         public static bool IS_BCD(byte BCD)
         {
             return ((((( int)(BCD) & 0x000f) < 0x000a) && (((int)(BCD) & 0x00f0) < 0x00a0)) ? true : false);
         }
        //取一个字节的低位BCD码字符
         public static char BCD_LO(int bcd)
         {
             char bcdCLo=(char)((int)(bcd) & 0X000F 0x30);
             return bcdCLo;
         }
        //取一个字节的高位BCD码字符
         public static char BCD_HI(int bcd)
         {
            char bcdHI=(char)((int)(bcd) >> 4& 0X000F 0x30);
             return bcdHI;
         }

         public static string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
         {
             string hexString = string.Empty;

             if (bytes != null)
             {

                 StringBuilder strB = new StringBuilder();

                 for (int i = 0; i < bytes.Length; i )
                 {

                     strB.Append(bytes[i].ToString("X2"));

                 }

                 hexString = strB.ToString();

             } return hexString;

         }
        /// <summary>
     

        private void tabIpSet_Enter(object sender, EventArgs e)
        {

            BPortSet = false;
            BIpSet = true;
            if(serialPort1.IsOpen)
            {
                if (!BIpSetRead)
                {                    
                    BIpSetRead = true;
                    gen_read(0xFE, 0x03, 0x1B, 0xD1, 8);//读取网络设置参数
                }
            }
           
        }

        private void tabPortSet_Enter(object sender, EventArgs e)
        {
            BIpSet = false;
            BPortSet = true;
            if (serialPort1.IsOpen)
            {
                if (!BPortSetRead)
                {
                    BPortSetRead = true;
                    gen_read(0xFE, 0x03, 0x00, 0x1A, 8);//读取串口设置参数
                }
            }
        }

        private void bReadParam_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                if (BPortSet)
                {

                    gen_read(0xFE, 0x03, 0x00, 0x1A, 8);//读取串口设置参数
                }
                else if (BIpSet)
                {
                   
                    gen_read(0xFE, 0x03, 0x1B, 0xD1, 8);//读取网络设置参数
                }
            }
        }

    }
}

实例下载地址

Modbus通讯 串口通讯

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警