Modbus通信、tcp、udp

页面:

image

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Modbus.Device;
namespace WinUpperCourse
{
    public partial class WinNModbus4Test : Form
    {
        public WinNModbus4Test()
        {
            InitializeComponent();
        }
        //声明串口
        SerialPort serialPort = null;
        TcpClient tcpClient = null;
        UdpClient udpClient = null;
        //创建主站对象
        IModbusSerialMaster modbusSerialMaster = null; //串口
        IModbusMaster modbusMaster = null;//网口
        private void WinNModbus4Test_Load(object sender, EventArgs e)
        {
            //初始化控件值
            this.cmInfoType.Items.AddRange(new[] { "串口", "TCP", "UDP" });
            this.cmInfoType.SelectedIndex=0;
            //初始化串口
            string[] portItem = SerialPort.GetPortNames();
            this.cmPort.Items.AddRange(portItem);
            this.cmPort.SelectedIndex = 0;
            this.cmBaudRate.Items.Add("9600");
            this.cmBaudRate.SelectedIndex = 0;

            Parity[] parityItem = new[] { Parity.None, Parity.Odd, Parity.Even };
            cmParity.Items.AddRange(parityItem.Cast<object>().ToArray());
            this.cmParity.SelectedIndex = 0;
            this.cmDataBits.Items.AddRange(new string[] { "8", "9" });
            this.cmDataBits.SelectedIndex = 0;
            StopBits[] stopBitsItem = new[] { StopBits.One, StopBits.None };
            this.cmStopBits.Items.AddRange(stopBitsItem.Cast<object>().ToArray());
            this.cmStopBits.SelectedIndex = 0;

            this.txtIP.Text="127.0.0.1";
            this.txtPort.Text="302";

            this.btnStatue.Text="未连接";

            this.rdRTU.Checked=true;
        }
        /// <summary>
        /// 通信方式选择改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmInfoType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.cmInfoType.Text=="串口")
            {
                this.txtIP.Enabled = false;
                this.txtPort.Enabled = false;

                this.cmPort.Enabled = true;
                this.cmPort.Enabled=true;
                this.cmBaudRate.Enabled = true;
                this.cmParity.Enabled = true;
                this.cmDataBits.Enabled = true;
                this.cmStopBits.Enabled = true;
                this.cmParity.Enabled = true;
            }
            else
            {
                this.cmPort.Enabled = false;
                this.cmPort.Enabled=false;
                this.cmBaudRate.Enabled = false;
                this.cmParity.Enabled = false;
                this.cmDataBits.Enabled = false;
                this.cmStopBits.Enabled = false;
                this.cmParity.Enabled = false;

                this.txtIP.Enabled = true;
                this.txtPort.Enabled = true;
            }
        }
        /// <summary>
        /// 打开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen_Click(object sender, EventArgs e)
        {
            //如果是串口
            if (this.cmInfoType.Text=="串口")
            {
                // 1. 转换波特率、数据位
                int baudRate = int.Parse(cmBaudRate.Text);
                int dataBits = int.Parse(cmDataBits.Text);

                // 2. 校验位文本转 Parity 枚举  校验位
                // Enum.TryParse(cmParity.Text, true, out Parity parity);
                Parity parity = Enum.Parse<Parity>(cmParity.Text);
                // 3. 停止位文本转 StopBits 枚举 停止位
                Enum.TryParse(cmStopBits.Text, true, out StopBits stopBits);

                // 4. 实例化串口
                serialPort = new SerialPort(
                   cmPort.Text,
                   baudRate,
                   parity,
                   dataBits,
                   stopBits
               );
                //打开
                serialPort.Open();
                if (serialPort!=null&&serialPort.IsOpen)
                {
                    this.Invoke(new Action(() => { this.btnStatue.Text = "串口已连接"; }));
                    //判断是 RTU还是ASCII
                    if (rdRTU.Checked==true)
                    {
                        //创建RTU主站
                        modbusSerialMaster=ModbusSerialMaster.CreateRtu(serialPort);
                    }
                    else
                    {
                        modbusSerialMaster=ModbusSerialMaster.CreateAscii(serialPort);
                    }
                }

            }
            else
            {
                //tcp
                if (this.cmInfoType.Text=="TCP")
                {
                    tcpClient=new TcpClient(this.txtIP.Text, int.Parse(this.txtPort.Text));
                    this.Invoke(new Action(() => { this.btnStatue.Text = "tcp已连接"; }));

                    modbusMaster=ModbusIpMaster.CreateIp(tcpClient);
                }
                else //upd
                {
                    udpClient=new UdpClient(this.txtIP.Text, int.Parse(this.txtPort.Text));
                    this.Invoke(new Action(() => { this.btnStatue.Text = "upd已连接"; }));
                    modbusMaster=ModbusIpMaster.CreateIp(udpClient);
                }
            }
        }
        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            if (this.cmInfoType.Text=="串口")
            {
                serialPort.Close();
                this.Invoke(new Action(() => { this.btnStatue.Text = "串口连接断开"; }));

            }
            else if (this.cmInfoType.Text=="TCP")
            {
                tcpClient.Close();
                this.Invoke(new Action(() =>
                {
                    this.btnStatue.Text="TCP连接断开";
                }));

            }
            else
            {
                udpClient.Close();
                this.Invoke(new Action(() =>
                {
                    this.btnStatue.Text="UDP连接断开";
                }));

            }
        }
        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRead_Click(object sender, EventArgs e)
        {
            OperationAction(1);
        }
        /// <summary>
        /// 写入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnWrite_Click(object sender, EventArgs e)
        {
            OperationAction(2);
        }
        /// <summary>
        /// 读写操作
        /// </summary>
        /// <param name="type">1:读,2:写</param>
        public void OperationAction(int type)
        {
            //从站地址
            byte slaveId = byte.Parse(this.txtSlaveId.Text);
            //开始地址
            ushort startAddres = ushort.Parse(this.txtStartAdders.Text);
            //写入开始地址
            ushort writeStartAdder = 0;
            if(type==2)
            {
                writeStartAdder= ushort.Parse(this.txtWriteStartAdder.Text);
            }
            //读取数量
            ushort count = ushort.Parse(this.txtReadQty.Text);
            //功能码
            byte funtionCode = byte.Parse(this.txtFuntionCode.Text);
            bool[] bValue = null;
            ushort[] uValue = null;
            switch (funtionCode)
            {
                //写操作 只能是功能码1和3 读写都可以,     2和4是只读
                case 1://读线一个或多个圈状态
                    if (type==1)
                    {
                        if (this.cmInfoType.Text=="串口")
                        {
                            bValue = modbusSerialMaster.ReadCoils(slaveId, startAddres, count);
                        }
                        else  //tcp  udp
                        {
                            bValue = modbusMaster.ReadCoils(slaveId, startAddres, count);
                        }
                        this.lbData.Items.Add(string.Join(",", bValue));
                    }
                    else
                    {
                        //写入线圈
                        //  bValue=  this.txtValue.Text.Split(',').Select(str => str=="1" ? true : false).ToArray();
                        bValue=   this.txtValue.Text
                        .Split(',', StringSplitOptions.RemoveEmptyEntries)
                        .Select(str => str.Trim() == "1" ? true : false)
                        .ToArray();

                        if (this.cmInfoType.Text=="串口")
                        {
                            //写入多线圈
                            if (bValue.Length>1)
                            {
                                modbusSerialMaster.WriteMultipleCoils(slaveId, writeStartAdder, bValue);
                            }
                            else
                            {
                                modbusSerialMaster.WriteSingleCoil(slaveId, writeStartAdder, bValue[0]);
                            }
                        }
                        else  //tcp  udp
                        {
                            //写入多线圈
                            if (bValue.Length>1)
                            {
                                modbusMaster.WriteMultipleCoils(slaveId, writeStartAdder, bValue);
                            }
                            else
                            {
                                modbusMaster.WriteSingleCoil(slaveId, writeStartAdder, bValue[0]);
                            }

                        }
                    }

                    break;
                case 2: //读一个或多个输入线圈

                    if (this.cmInfoType.Text=="串口")
                    {
                        bValue = modbusSerialMaster.ReadInputs(slaveId, startAddres, count);
                    }
                    else  //tcp  udp
                    {
                        bValue = modbusMaster.ReadInputs(slaveId, startAddres, count);
                    }
                    this.lbData.Items.Add(string.Join(",", bValue));
                    break;
                case 3: //读一个或多个保持寄存器
                    if(type==1)
                    {
                        if (this.cmInfoType.Text=="串口")
                        {
                            uValue = modbusSerialMaster.ReadHoldingRegisters(slaveId, startAddres, count);
                        }
                        else  //tcp  udp
                        {
                            uValue = modbusMaster.ReadHoldingRegisters(slaveId, startAddres, count);
                        }
                        this.lbData.Items.Add(string.Join(",", uValue));
                    }
                    else
                    {
                        ushort[] sValue = this.txtValue.Text
                                                        .Split(',', StringSplitOptions.RemoveEmptyEntries)
                                                        .Select(str => ushort.Parse(str.Trim()))
                                                        .ToArray();
                        if (this.cmInfoType.Text=="串口")
                        {
                            //写入多线圈
                            if (sValue.Length>1)
                            {
                                modbusSerialMaster.WriteMultipleRegisters(slaveId, writeStartAdder, sValue);
                            }
                            else
                            {
                                modbusSerialMaster.WriteSingleRegister(slaveId, writeStartAdder, sValue[0]);
                            }
                        }
                        else  //tcp  udp
                        {
                           
                            //写入多线圈
                            if (sValue.Length>1)
                            {
                                modbusMaster.WriteMultipleRegisters(slaveId, writeStartAdder, sValue);
                            }
                            else
                            {
                                modbusMaster.WriteSingleRegister(slaveId, writeStartAdder, sValue[0]);
                            }

                        }
                    }
                   
                    break;
                case 4: //读一个或多个输入寄存器
                    if (this.cmInfoType.Text=="串口")
                    {
                        uValue = modbusSerialMaster.ReadInputRegisters(slaveId, startAddres, count);
                    }
                    else  //tcp  udp
                    {
                        uValue = modbusMaster.ReadInputRegisters(slaveId, startAddres, count);
                    }
                    this.lbData.Items.Add(string.Join(",", uValue));
                    break;

            }
        }
    }
}

 

posted @ 2026-06-17 21:10  旧夏潜入梦  阅读(2)  评论(0)    收藏  举报