MODBUS RTU/TCP通讯工具源码(不使用库文件)
MODBUS RTU/TCP协议及常用功能码详解
链接: https://blog.csdn.net/qq_43254236/article/details/118152650.
使用库文件的通讯工具看这里
链接: https://www.cnblogs.com/pandefu/p/10824331.html.
MODBUS RTU/TCP通讯工具源码
先看看软件界面
软件界面代码
namespace ModbusRtu
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.label1 = new System.Windows.Forms.Label();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.gbRTU = new System.Windows.Forms.GroupBox();
this.cmb_stopBits = new System.Windows.Forms.ComboBox();
this.label6 = new System.Windows.Forms.Label();
this.cmb_databBits = new System.Windows.Forms.ComboBox();
this.label5 = new System.Windows.Forms.Label();
this.cmb_parity = new System.Windows.Forms.ComboBox();
this.button3 = new System.Windows.Forms.Button();
this.label4 = new System.Windows.Forms.Label();
this.cmb_baud = new System.Windows.Forms.ComboBox();
this.label3 = new System.Windows.Forms.Label();
this.cmb_portname = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.checkBox2 = new System.Windows.Forms.CheckBox();
this.button4 = new System.Windows.Forms.Button();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.txt_length = new System.Windows.Forms.TextBox();
this.label8 = new System.Windows.Forms.Label();
this.txt_startAddr1 = new System.Windows.Forms.TextBox();
this.label7 = new System.Windows.Forms.Label();
this.txt_slave1 = new System.Windows.Forms.TextBox();
this.label11 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.label13 = new System.Windows.Forms.Label();
this.txt_data = new System.Windows.Forms.TextBox();
this.label9 = new System.Windows.Forms.Label();
this.txt_startAddr2 = new System.Windows.Forms.TextBox();
this.label10 = new System.Windows.Forms.Label();
this.txt_slave2 = new System.Windows.Forms.TextBox();
this.label12 = new System.Windows.Forms.Label();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.cmb_DataFormat = new System.Windows.Forms.ComboBox();
this.label15 = new System.Windows.Forms.Label();
this.cmb_VarType = new System.Windows.Forms.ComboBox();
this.label14 = new System.Windows.Forms.Label();
this.port = new System.IO.Ports.SerialPort(this.components);
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.gbTCP = new System.Windows.Forms.GroupBox();
this.label16 = new System.Windows.Forms.Label();
this.tbTCPIP = new System.Windows.Forms.TextBox();
this.tbTCPPort = new System.Windows.Forms.TextBox();
this.tbLocalPort = new System.Windows.Forms.TextBox();
this.label17 = new System.Windows.Forms.Label();
this.label18 = new System.Windows.Forms.Label();
this.rbRTU = new System.Windows.Forms.RadioButton();
this.rbTCP = new System.Windows.Forms.RadioButton();
this.btnOpen = new System.Windows.Forms.Button();
this.gbRTU.SuspendLayout();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox4.SuspendLayout();
this.gbTCP.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 29);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(41, 12);
this.label1.TabIndex = 2;
this.label1.Text = "功能码";
//
// comboBox1
//
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Items.AddRange(new object[] {
"01 Read Coils",
"02 Read DisCrete Inputs",
"03 Read Holding Registers",
"04 Read Input Registers",
"05 Write Single Coil",
"06 Write Single Registers",
"0F Write Multiple Coils",
"10 Write Multiple Registers"});
this.comboBox1.Location = new System.Drawing.Point(55, 26);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(177, 20);
this.comboBox1.TabIndex = 1;
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// button1
//
this.button1.Image = global::ModbusRtu.Properties.Resources.finger;
this.button1.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.button1.Location = new System.Drawing.Point(561, 20);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(119, 28);
this.button1.TabIndex = 4;
this.button1.Text = "Read/Write ";
this.button1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(697, 20);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 28);
this.button2.TabIndex = 9;
this.button2.Text = "Clear";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// gbRTU
//
this.gbRTU.Controls.Add(this.cmb_stopBits);
this.gbRTU.Controls.Add(this.label6);
this.gbRTU.Controls.Add(this.cmb_databBits);
this.gbRTU.Controls.Add(this.label5);
this.gbRTU.Controls.Add(this.cmb_parity);
this.gbRTU.Controls.Add(this.button3);
this.gbRTU.Controls.Add(this.label4);
this.gbRTU.Controls.Add(this.cmb_baud);
this.gbRTU.Controls.Add(this.label3);
this.gbRTU.Controls.Add(this.cmb_portname);
this.gbRTU.Controls.Add(this.label2);
this.gbRTU.Location = new System.Drawing.Point(12, 100);
this.gbRTU.Name = "gbRTU";
this.gbRTU.Size = new System.Drawing.Size(777, 65);
this.gbRTU.TabIndex = 10;
this.gbRTU.TabStop = false;
this.gbRTU.Text = "串口参数";
//
// cmb_stopBits
//
this.cmb_stopBits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmb_stopBits.FormattingEnabled = true;
this.cmb_stopBits.Items.AddRange(new object[] {
"1",
"2",
"1.5"});
this.cmb_stopBits.Location = new System.Drawing.Point(575, 22);
this.cmb_stopBits.Name = "cmb_stopBits";
this.cmb_stopBits.Size = new System.Drawing.Size(76, 20);
this.cmb_stopBits.TabIndex = 32;
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(528, 25);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(41, 12);
this.label6.TabIndex = 31;
this.label6.Text = "停止位";
//
// cmb_databBits
//
this.cmb_databBits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmb_databBits.FormattingEnabled = true;
this.cmb_databBits.Items.AddRange(new object[] {
"7",
"8"});
this.cmb_databBits.Location = new System.Drawing.Point(446, 22);
this.cmb_databBits.Name = "cmb_databBits";
this.cmb_databBits.Size = new System.Drawing.Size(76, 20);
this.cmb_databBits.TabIndex = 30;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(399, 25);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(41, 12);
this.label5.TabIndex = 32;
this.label5.Text = "数据位";
//
// cmb_parity
//
this.cmb_parity.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmb_parity.FormattingEnabled = true;
this.cmb_parity.Items.AddRange(new object[] {
"奇",
"偶",
"无"});
this.cmb_parity.Location = new System.Drawing.Point(317, 22);
this.cmb_parity.Name = "cmb_parity";
this.cmb_parity.Size = new System.Drawing.Size(76, 20);
this.cmb_parity.TabIndex = 28;
//
// button3
//
this.button3.Location = new System.Drawing.Point(665, 20);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(106, 23);
this.button3.TabIndex = 40;
this.button3.Text = "打开串口";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(282, 25);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(29, 12);
this.label4.TabIndex = 27;
this.label4.Text = "校验";
//
// cmb_baud
//
this.cmb_baud.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmb_baud.FormattingEnabled = true;
this.cmb_baud.Items.AddRange(new object[] {
"300",
"600",
"1200",
"2400",
"4800",
"9600",
"14400",
"19200",
"38400",
"43000",
"56000",
"76800",
"115200",
"128000",
"230400",
"256000",
"460800",
"921600",
"1382400"});
this.cmb_baud.Location = new System.Drawing.Point(199, 22);
this.cmb_baud.Name = "cmb_baud";
this.cmb_baud.Size = new System.Drawing.Size(77, 20);
this.cmb_baud.TabIndex = 25;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(152, 25);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(41, 12);
this.label3.TabIndex = 25;
this.label3.Text = "波特率";
//
// cmb_portname
//
this.cmb_portname.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmb_portname.FormattingEnabled = true;
this.cmb_portname.Items.AddRange(new object[] {
"COM1",
"COM2",
"COM3",
"COM4",
"COM5",
"COM6",
"COM7",
"COM8",
"COM9",
"COM10"});
this.cmb_portname.Location = new System.Drawing.Point(52, 22);
this.cmb_portname.Name = "cmb_portname";
this.cmb_portname.Size = new System.Drawing.Size(85, 20);
this.cmb_portname.TabIndex = 23;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(17, 25);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(29, 12);
this.label2.TabIndex = 0;
this.label2.Text = "串口";
//
// groupBox1
//
this.groupBox1.Controls.Add(this.checkBox2);
this.groupBox1.Controls.Add(this.button2);
this.groupBox1.Controls.Add(this.button4);
this.groupBox1.Controls.Add(this.checkBox1);
this.groupBox1.Controls.Add(this.txt_length);
this.groupBox1.Controls.Add(this.label8);
this.groupBox1.Controls.Add(this.txt_startAddr1);
this.groupBox1.Controls.Add(this.label7);
this.groupBox1.Controls.Add(this.txt_slave1);
this.groupBox1.Controls.Add(this.label11);
this.groupBox1.Location = new System.Drawing.Point(11, 237);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(780, 65);
this.groupBox1.TabIndex = 33;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "读操作";
//
// checkBox2
//
this.checkBox2.AutoSize = true;
this.checkBox2.Location = new System.Drawing.Point(556, 26);
this.checkBox2.Name = "checkBox2";
this.checkBox2.Size = new System.Drawing.Size(66, 16);
this.checkBox2.TabIndex = 43;
this.checkBox2.Text = "HEX发送";
this.checkBox2.UseVisualStyleBackColor = true;
//
// button4
//
this.button4.Location = new System.Drawing.Point(500, 18);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(50, 30);
this.button4.TabIndex = 42;
this.button4.Text = "发送";
this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.button4_Click);
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Location = new System.Drawing.Point(628, 26);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(66, 16);
this.checkBox1.TabIndex = 41;
this.checkBox1.Text = "HEX接收";
this.checkBox1.UseVisualStyleBackColor = true;
//
// txt_length
//
this.txt_length.Location = new System.Drawing.Point(389, 20);
this.txt_length.Name = "txt_length";
this.txt_length.Size = new System.Drawing.Size(100, 21);
this.txt_length.TabIndex = 5;
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(354, 26);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(41, 12);
this.label8.TabIndex = 4;
this.label8.Text = "长度:";
//
// txt_startAddr1
//
this.txt_startAddr1.Location = new System.Drawing.Point(226, 20);
this.txt_startAddr1.Name = "txt_startAddr1";
this.txt_startAddr1.Size = new System.Drawing.Size(100, 21);
this.txt_startAddr1.TabIndex = 3;
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(167, 26);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(65, 12);
this.label7.TabIndex = 2;
this.label7.Text = "起始地址:";
//
// txt_slave1
//
this.txt_slave1.Location = new System.Drawing.Point(49, 20);
this.txt_slave1.Name = "txt_slave1";
this.txt_slave1.Size = new System.Drawing.Size(100, 21);
this.txt_slave1.TabIndex = 1;
//
// label11
//
this.label11.AutoSize = true;
this.label11.Location = new System.Drawing.Point(14, 26);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(41, 12);
this.label11.TabIndex = 0;
this.label11.Text = "站号:";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.label13);
this.groupBox2.Controls.Add(this.txt_data);
this.groupBox2.Controls.Add(this.label9);
this.groupBox2.Controls.Add(this.txt_startAddr2);
this.groupBox2.Controls.Add(this.label10);
this.groupBox2.Controls.Add(this.txt_slave2);
this.groupBox2.Controls.Add(this.label12);
this.groupBox2.Location = new System.Drawing.Point(11, 310);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(780, 65);
this.groupBox2.TabIndex = 34;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "写操作";
//
// label13
//
this.label13.AutoSize = true;
this.label13.BackColor = System.Drawing.Color.Transparent;
this.label13.ForeColor = System.Drawing.Color.Chocolate;
this.label13.Location = new System.Drawing.Point(400, 44);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(377, 12);
this.label13.TabIndex = 13;
this.label13.Text = "(数据之间用\'空格\'隔开,线圈数据用0或1表示,寄存器数据ushort类型)";
//
// txt_data
//
this.txt_data.Location = new System.Drawing.Point(417, 20);
this.txt_data.Name = "txt_data";
this.txt_data.Size = new System.Drawing.Size(346, 21);
this.txt_data.TabIndex = 5;
//
// label9
//
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(354, 26);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(65, 12);
this.label9.TabIndex = 4;
this.label9.Text = "数据数组:";
//
// txt_startAddr2
//
this.txt_startAddr2.Location = new System.Drawing.Point(226, 20);
this.txt_startAddr2.Name = "txt_startAddr2";
this.txt_startAddr2.Size = new System.Drawing.Size(100, 21);
this.txt_startAddr2.TabIndex = 10;
//
// label10
//
this.label10.AutoSize = true;
this.label10.Location = new System.Drawing.Point(167, 26);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(65, 12);
this.label10.TabIndex = 2;
this.label10.Text = "起始地址:";
//
// txt_slave2
//
this.txt_slave2.Location = new System.Drawing.Point(49, 20);
this.txt_slave2.Name = "txt_slave2";
this.txt_slave2.Size = new System.Drawing.Size(100, 21);
this.txt_slave2.TabIndex = 8;
//
// label12
//
this.label12.AutoSize = true;
this.label12.Location = new System.Drawing.Point(14, 26);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(41, 12);
this.label12.TabIndex = 0;
this.label12.Text = "站号:";
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(11, 382);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(780, 203);
this.richTextBox1.TabIndex = 35;
this.richTextBox1.Text = "";
this.richTextBox1.TextChanged += new System.EventHandler(this.richTextBox1_TextChanged);
//
// cmb_DataFormat
//
this.cmb_DataFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmb_DataFormat.FormattingEnabled = true;
this.cmb_DataFormat.Location = new System.Drawing.Point(463, 26);
this.cmb_DataFormat.Name = "cmb_DataFormat";
this.cmb_DataFormat.Size = new System.Drawing.Size(81, 20);
this.cmb_DataFormat.TabIndex = 42;
this.cmb_DataFormat.SelectedIndexChanged += new System.EventHandler(this.cmb_DataFormat_SelectedIndexChanged);
//
// label15
//
this.label15.AutoSize = true;
this.label15.Location = new System.Drawing.Point(394, 30);
this.label15.Name = "label15";
this.label15.Size = new System.Drawing.Size(65, 12);
this.label15.TabIndex = 41;
this.label15.Text = "数据格式:";
//
// cmb_VarType
//
this.cmb_VarType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmb_VarType.FormattingEnabled = true;
this.cmb_VarType.Location = new System.Drawing.Point(302, 26);
this.cmb_VarType.Name = "cmb_VarType";
this.cmb_VarType.Size = new System.Drawing.Size(74, 20);
this.cmb_VarType.TabIndex = 39;
this.cmb_VarType.SelectedIndexChanged += new System.EventHandler(this.cmb_VarType_SelectedIndexChanged);
//
// label14
//
this.label14.AutoSize = true;
this.label14.Location = new System.Drawing.Point(243, 29);
this.label14.Name = "label14";
this.label14.Size = new System.Drawing.Size(53, 12);
this.label14.TabIndex = 38;
this.label14.Text = "变量类型";
//
// port
//
this.port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.port_DataReceived);
//
// groupBox4
//
this.groupBox4.Controls.Add(this.cmb_DataFormat);
this.groupBox4.Controls.Add(this.button1);
this.groupBox4.Controls.Add(this.label1);
this.groupBox4.Controls.Add(this.label15);
this.groupBox4.Controls.Add(this.comboBox1);
this.groupBox4.Controls.Add(this.cmb_VarType);
this.groupBox4.Controls.Add(this.label14);
this.groupBox4.Location = new System.Drawing.Point(11, 170);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(778, 61);
this.groupBox4.TabIndex = 43;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "数据参数";
//
// gbTCP
//
this.gbTCP.Controls.Add(this.btnOpen);
this.gbTCP.Controls.Add(this.label16);
this.gbTCP.Controls.Add(this.tbTCPIP);
this.gbTCP.Controls.Add(this.tbTCPPort);
this.gbTCP.Controls.Add(this.tbLocalPort);
this.gbTCP.Controls.Add(this.label17);
this.gbTCP.Controls.Add(this.label18);
this.gbTCP.Location = new System.Drawing.Point(12, 31);
this.gbTCP.Name = "gbTCP";
this.gbTCP.Size = new System.Drawing.Size(778, 58);
this.gbTCP.TabIndex = 44;
this.gbTCP.TabStop = false;
this.gbTCP.Text = "TCP参数";
//
// label16
//
this.label16.AutoSize = true;
this.label16.Location = new System.Drawing.Point(7, 29);
this.label16.Name = "label16";
this.label16.Size = new System.Drawing.Size(71, 12);
this.label16.TabIndex = 39;
this.label16.Text = "PLC的IP地址";
//
// tbTCPIP
//
this.tbTCPIP.Location = new System.Drawing.Point(84, 25);
this.tbTCPIP.Name = "tbTCPIP";
this.tbTCPIP.Size = new System.Drawing.Size(100, 21);
this.tbTCPIP.TabIndex = 38;
this.tbTCPIP.Text = "127.0.0.1";
this.tbTCPIP.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// tbTCPPort
//
this.tbTCPPort.Location = new System.Drawing.Point(270, 25);
this.tbTCPPort.Name = "tbTCPPort";
this.tbTCPPort.Size = new System.Drawing.Size(44, 21);
this.tbTCPPort.TabIndex = 40;
this.tbTCPPort.Text = "502";
this.tbTCPPort.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// tbLocalPort
//
this.tbLocalPort.Location = new System.Drawing.Point(405, 25);
this.tbLocalPort.Name = "tbLocalPort";
this.tbLocalPort.Size = new System.Drawing.Size(44, 21);
this.tbLocalPort.TabIndex = 36;
this.tbLocalPort.Text = "0";
this.tbLocalPort.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.tbLocalPort.Visible = false;
//
// label17
//
this.label17.AutoSize = true;
this.label17.Location = new System.Drawing.Point(219, 28);
this.label17.Name = "label17";
this.label17.Size = new System.Drawing.Size(47, 12);
this.label17.TabIndex = 41;
this.label17.Text = "PLC端口";
//
// label18
//
this.label18.AutoSize = true;
this.label18.Location = new System.Drawing.Point(348, 28);
this.label18.Name = "label18";
this.label18.Size = new System.Drawing.Size(53, 12);
this.label18.TabIndex = 37;
this.label18.Text = "本机端口";
this.label18.Visible = false;
//
// rbRTU
//
this.rbRTU.AutoSize = true;
this.rbRTU.Checked = true;
this.rbRTU.Location = new System.Drawing.Point(158, 10);
this.rbRTU.Name = "rbRTU";
this.rbRTU.Size = new System.Drawing.Size(41, 16);
this.rbRTU.TabIndex = 45;
this.rbRTU.TabStop = true;
this.rbRTU.Text = "RTU";
this.rbRTU.UseVisualStyleBackColor = true;
this.rbRTU.CheckedChanged += new System.EventHandler(this.rb_CheckedChanged);
//
// rbTCP
//
this.rbTCP.AutoSize = true;
this.rbTCP.Location = new System.Drawing.Point(211, 9);
this.rbTCP.Name = "rbTCP";
this.rbTCP.Size = new System.Drawing.Size(41, 16);
this.rbTCP.TabIndex = 46;
this.rbTCP.TabStop = true;
this.rbTCP.Text = "TCP";
this.rbTCP.UseVisualStyleBackColor = true;
this.rbTCP.CheckedChanged += new System.EventHandler(this.rb_CheckedChanged);
//
// btnOpen
//
this.btnOpen.Location = new System.Drawing.Point(663, 23);
this.btnOpen.Name = "btnOpen";
this.btnOpen.Size = new System.Drawing.Size(98, 22);
this.btnOpen.TabIndex = 42;
this.btnOpen.Text = "打开连接";
this.btnOpen.UseVisualStyleBackColor = true;
this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 597);
this.Controls.Add(this.rbTCP);
this.Controls.Add(this.rbRTU);
this.Controls.Add(this.gbTCP);
this.Controls.Add(this.groupBox4);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.richTextBox1);
this.Controls.Add(this.gbRTU);
this.Controls.Add(this.groupBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Name = "Form1";
this.Text = "Modbus Rtu";
this.Load += new System.EventHandler(this.Form1_Load);
this.gbRTU.ResumeLayout(false);
this.gbRTU.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.groupBox4.ResumeLayout(false);
this.groupBox4.PerformLayout();
this.gbTCP.ResumeLayout(false);
this.gbTCP.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.GroupBox gbRTU;
private System.Windows.Forms.ComboBox cmb_stopBits;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.ComboBox cmb_databBits;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.ComboBox cmb_parity;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.ComboBox cmb_baud;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox cmb_portname;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox txt_length;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.TextBox txt_startAddr1;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.TextBox txt_slave1;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.TextBox txt_data;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.TextBox txt_startAddr2;
private System.Windows.Forms.Label label10;
private System.Windows.Forms.TextBox txt_slave2;
private System.Windows.Forms.Label label12;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.Label label13;
private System.Windows.Forms.ComboBox cmb_VarType;
private System.Windows.Forms.Label label14;
private System.IO.Ports.SerialPort port;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.CheckBox checkBox2;
private System.Windows.Forms.ComboBox cmb_DataFormat;
private System.Windows.Forms.Label label15;
private System.Windows.Forms.GroupBox groupBox4;
private System.Windows.Forms.GroupBox gbTCP;
internal System.Windows.Forms.Label label16;
internal System.Windows.Forms.TextBox tbTCPIP;
internal System.Windows.Forms.TextBox tbTCPPort;
internal System.Windows.Forms.TextBox tbLocalPort;
internal System.Windows.Forms.Label label17;
internal System.Windows.Forms.Label label18;
private System.Windows.Forms.RadioButton rbRTU;
private System.Windows.Forms.RadioButton rbTCP;
private System.Windows.Forms.Button btnOpen;
}
}
主程序代码
using System;
using System.Collections;
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.Net.Sockets;
using System.Threading;
using System.IO.Ports;
using System.Drawing.Text;
using System.Windows.Forms.VisualStyles;
using System.Timers;
using System.CodeDom.Compiler;
using System.Net;
namespace ModbusRtu
{
public partial class Form1 : Form
{
#region 参数配置
//private static SerialPort port;
//串口发送数据数组
private byte[] SendBuff;
//写线圈或写寄存器数组
private bool[] coilsBuffer /*= new bool[16]*/;
private ushort[] UshortBuffer;
private short[] ShortBuffer;
private uint[] UintBuffer;
private int[] IntBuffer;
private float[] FloatBuffer;
//功能码
private string functionCode;
//功能码序号
private int functionOder;
//参数(分别为从站地址,起始地址,长度)
private byte slaveAddress;
private ushort startAddress;
private ushort numberOfPoints;
//串口参数
private string portName;
private int baudRate;
private Parity parity;
private int dataBits;
private StopBits stopBits;
//自动测试标志位
private bool AutoFlag = false;
//获取当前时间
private System.DateTime Current_time;
//定时器初始化
private System.Timers.Timer t = new System.Timers.Timer(1000);
private const int WM_DEVICE_CHANGE = 0x219; //设备改变
private const int DBT_DEVICEARRIVAL = 0x8000; //设备插入
private const int DBT_DEVICE_REMOVE_COMPLETE = 0x8004; //设备移除
private VarType vartype;
//数据格式
private DataFormat dataFormat;
private string InPutstr;
Socket socketSend;
private bool IsOpen = false;
private int Port;
private string IP;
#endregion
public enum VarType
{
Bit = 0,
Byte = 1,
Word = 2,
DWord = 3,
Int = 4,
DInt = 5,
Real = 6,
String = 7,
Timer = 8,
Counter = 9
}
public enum DataFormat
{
ABCD = 0,
BADC = 1,
CDAB = 2,
DCBA = 3
}
public Form1()
{
InitializeComponent();
GetSerialLstTb1();
}
private void Form1_Load(object sender, EventArgs e)
{
//界面初始化
gbRTU.Enabled = rbRTU.Checked;
gbTCP.Enabled = rbTCP.Checked;
cmb_portname.SelectedIndex = 0;
cmb_baud.SelectedIndex = 5;
cmb_parity.SelectedIndex = 2;
cmb_databBits.SelectedIndex = 1;
cmb_stopBits.SelectedIndex = 0;
cmb_VarType.DataSource = Enum.GetNames(typeof(VarType));
cmb_VarType.SelectedIndex = 2;
vartype = (VarType)Enum.Parse(typeof(VarType), cmb_VarType.SelectedItem.ToString(), false);
cmb_DataFormat.DataSource = Enum.GetNames(typeof(DataFormat));
cmb_DataFormat.SelectedIndex = 0;
dataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), cmb_DataFormat.SelectedItem.ToString(), false);
button1.Enabled = false;
}
/// <summary>
/// 设置读参数
/// </summary>
private bool SetReadParameters()
{
if (txt_slave1.Text == ""|| txt_startAddr1.Text == "" || txt_length.Text == "")
{
MessageBox.Show("请填写读参数!");
return false;
}
else
{
slaveAddress = byte.Parse(txt_slave1.Text);
startAddress = ushort.Parse(txt_startAddr1.Text);
numberOfPoints = ushort.Parse(txt_length.Text);
return true;
}
}
/// <summary>
/// 设置写参数
/// </summary>
private bool SetWriteParametes()
{
if (txt_startAddr2.Text == "" || txt_slave2.Text == "" || txt_data.Text == "")
{
MessageBox.Show("请填写写参数!");
return false;
}
else
{
InPutstr = txt_data.Text;
slaveAddress = byte.Parse(txt_slave2.Text);
startAddress = ushort.Parse(txt_startAddr2.Text);
//判断是否写线圈
if (functionOder == 4 || functionOder == 6)
{
string[] strarr = txt_data.Text.Split(' ');
numberOfPoints = (ushort)strarr.Length;
if (strarr.Length % 8 == 0)
{
coilsBuffer = new bool[strarr.Length];
}
else
{
coilsBuffer = new bool[strarr.Length + 8 - strarr.Length % 8];
}
//转化为bool数组
for (int i = 0; i < coilsBuffer.Length; i++)
{
// strarr[i] == "0" ? coilsBuffer[i] = false : coilsBuffer[i] = true;
if (i < strarr.Length)
{
if (strarr[i] == "0")
{
coilsBuffer[i] = false;
}
else
{
coilsBuffer[i] = true;
}
}
else
{
coilsBuffer[i] = false;
}
}
}
else
{
string[] strarr = txt_data.Text.Split(' ');
numberOfPoints = (ushort)strarr.Length;
switch (vartype)
{
case VarType.Word:
UshortBuffer = new ushort[strarr.Length];
for (int i = 0; i < strarr.Length; i++)
{
UshortBuffer[i] = ushort.Parse(strarr[i]);
}
break;
case VarType.DWord:
UintBuffer = new uint[strarr.Length];
for (int i = 0; i < strarr.Length; i++)
{
UintBuffer[i] = uint.Parse(strarr[i]);
}
break;
case VarType.Int:
ShortBuffer = new short[strarr.Length];
for (int i = 0; i < strarr.Length; i++)
{
ShortBuffer[i] = short.Parse(strarr[i]);
}
break;
case VarType.DInt:
IntBuffer = new int[strarr.Length];
for (int i = 0; i < strarr.Length; i++)
{
IntBuffer[i] = int.Parse(strarr[i]);
}
break;
case VarType.Real:
FloatBuffer = new float[strarr.Length];
for (int i = 0; i < strarr.Length; i++)
{
FloatBuffer[i] = float.Parse(strarr[i]);
}
break;
case VarType.String:
case VarType.Bit:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
break;
}
}
return true;
}
}
/// <summary>
/// 创建委托,打印日志
/// </summary>
/// <param name="msg"></param>
public void SetMsg(string msg)
{
richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(msg); }));
}
/// <summary>
/// 清空日志
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
richTextBox1.Clear();
}
/// <summary>
/// 单击button1事件,串口完成一次读/写操作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
try
{
//if (rbRTU.Checked)
//{
ExecuteFunction2();
//}
//else if (rbTCP.Checked)
//{
// ExecuteFunction();
//}
}
catch (Exception)
{
MessageBox.Show("初始化异常");
}
}
/// <summary>
/// 读取数据时,失能写数据;写数据时,失能读数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex >= 4)
{
groupBox2.Enabled = true;
groupBox1.Enabled = false;
}
else
{
groupBox1.Enabled = true;
groupBox2.Enabled = false;
}
//委托事件,在主线程中创建的控件,在子线程中读取设置控件的属性会出现异常,使用Invoke方法可以解决
comboBox1.Invoke(new Action(() => { functionCode = comboBox1.SelectedItem.ToString(); functionOder = comboBox1.SelectedIndex; }));
}
/// <summary>
/// 将打印日志显示到最新接收到的符号位置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
this.richTextBox1.SelectionStart = int.MaxValue;
this.richTextBox1.ScrollToCaret();
}
#region 串口下拉列表刷新
/// <summary>
/// 刷新下拉列表显示
/// </summary>
private void GetSerialLstTb1()
{
//清除cmb_portname显示
cmb_portname.SelectedIndex = -1;
cmb_portname.Items.Clear();
//获取串口列表
string[] serialLst = SerialPort.GetPortNames();
if (serialLst.Length > 0)
{
//取串口进行排序
Array.Sort(serialLst);
//将串口列表输出到cmb_portname
cmb_portname.Items.AddRange(serialLst);
cmb_portname.SelectedIndex = 0;
}
}
#endregion
private void button3_Click(object sender, EventArgs e)
{
if (button3.Text == "打开串口")
{//如果按钮显示的是打开串口
try
{
//防止意外错误
if (!InitPortParameter())
{
return;
}
port.Open();//打开串口
button1.Enabled = true;
button3.Text = "关闭串口";//按钮显示关闭串口
}
catch (Exception err)
{
MessageBox.Show("打开失败" + err.ToString(), "提示!");//对话框显示打开失败
}
}
else
{//要关闭串口
try
{//防止意外错误
port.Close();//关闭串口
button1.Enabled = false;
}
catch (Exception) { }
button3.Text = "打开串口";//按钮显示打开
}
}
/// <summary>
/// 串口参数获取
/// </summary>
/// <returns></返回串口配置参数>
private bool InitPortParameter()
{
if (rbRTU.Checked)
{
if (cmb_portname.SelectedIndex < 0 || cmb_baud.SelectedIndex < 0 || cmb_parity.SelectedIndex < 0 || cmb_databBits.SelectedIndex < 0 || cmb_stopBits.SelectedIndex < 0)
{
MessageBox.Show("请选择串口参数");
return false;
}
else
{
port.PortName = cmb_portname.SelectedItem.ToString();
port.BaudRate = int.Parse(cmb_baud.SelectedItem.ToString());
port.DataBits = int.Parse(cmb_databBits.SelectedItem.ToString());
switch (cmb_parity.SelectedItem.ToString())
{
case "奇":
port.Parity = Parity.Odd;
break;
case "偶":
port.Parity = Parity.Even;
break;
case "无":
port.Parity = Parity.None;
break;
default:
break;
}
switch (cmb_stopBits.SelectedItem.ToString())
{
case "1":
port.StopBits = StopBits.One;
break;
case "2":
port.StopBits = StopBits.Two;
break;
case "1.5":
port.StopBits = StopBits.OnePointFive;
break;
default:
break;
}
//port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
return true;
}
}
if (rbTCP.Checked)
{
if (tbTCPIP.Text.Split('.').Length != 4 || !int.TryParse(tbTCPPort.Text, out Port))
{
MessageBox.Show("请选择端口参数");
return false;
}
else
{
IP = tbTCPIP.Text;
Port = Convert.ToInt32(tbTCPPort.Text);
return true;
}
}
return true;
}
#region TCP收/发
private void ExecuteFunction()
{
}
#endregion
#region 串口收/发
private void ExecuteFunction2()
{
Current_time = System.DateTime.Now;
try
{
dataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), cmb_DataFormat.SelectedItem.ToString(), false);
vartype = (VarType)Enum.Parse(typeof(VarType), cmb_VarType.SelectedItem.ToString(), false);
if (rbRTU.Checked)
{
if (port.IsOpen == false)
{
MessageBox.Show("串口未打开");
return;
}
}
else if (rbTCP.Checked)
{
if (IsOpen==false)
{
MessageBox.Show("未连接");
return;
}
}
if (functionCode != null)
{
switch (functionCode)
{
case "01 Read Coils"://读取输出线圈
if (!SetReadParameters())
{
return;
}
try
{
switch (vartype)
{
case VarType.Bit:
MyRead(01);
break;
case VarType.Word:
case VarType.DWord:
case VarType.Int:
case VarType.DInt:
case VarType.Real:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("读取失败,变量类型不支持");
break;
}
}
catch (Exception)
{
MessageBox.Show("参数配置错误");
AutoFlag = false;
break;
}
break;
case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
if (!SetReadParameters())
{
return;
}
try
{
switch (vartype)
{
case VarType.Bit:
MyRead(02);
break;
case VarType.Word:
case VarType.DWord:
case VarType.Int:
case VarType.DInt:
case VarType.Real:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("读取失败,变量类型不支持");
break;
}
}
catch (Exception)
{
MessageBox.Show("参数配置错误");
AutoFlag = false;
break;
}
break;
case "03 Read Holding Registers"://读取保持寄存器
if (!SetReadParameters())
{
return;
}
try
{
switch (vartype)
{
case VarType.Word:
case VarType.Int:
MyRead(03);
break;
case VarType.DWord:
case VarType.DInt:
case VarType.Real:
MyRead(03, 2);
break;
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("读取失败,变量类型不支持");
break;
}
}
catch (Exception)
{
MessageBox.Show("参数配置错误");
AutoFlag = false;
break;
}
break;
case "04 Read Input Registers"://读取输入寄存器
if (!SetReadParameters())
{
return;
}
try
{
switch (vartype)
{
case VarType.Word:
case VarType.Int:
MyRead(04);
break;
case VarType.DWord:
case VarType.DInt:
case VarType.Real:
MyRead(04, 2);
break;
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("读取失败,变量类型不支持");
break;
}
}
catch (Exception)
{
MessageBox.Show("参数配置错误");
AutoFlag = false;
break;
}
break;
case "05 Write Single Coil"://写单个线圈
if (!SetWriteParametes())
{
return;
}
try
{
switch (vartype)
{
case VarType.Bit:
MyWrite(05);
break;
case VarType.Word:
case VarType.Int:
case VarType.DWord:
case VarType.DInt:
case VarType.Real:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("写入失败,变量类型不支持");
break;
}
}
catch (Exception)
{
MessageBox.Show("参数配置错误");
AutoFlag = false;
break;
}
break;
case "06 Write Single Registers"://写单个保持寄存器
if (!SetWriteParametes())
{
return;
}
try
{
switch (vartype)
{
case VarType.Word:
case VarType.Int:
MyWrite(06);
break;
case VarType.DWord:
case VarType.DInt:
case VarType.Real:
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("写入失败,变量类型不支持");
break;
}
}
catch (Exception)
{
MessageBox.Show("参数配置错误");
AutoFlag = false;
break;
}
break;
case "0F Write Multiple Coils"://写一组线圈
if (!SetWriteParametes())
{
return;
}
try
{
switch (vartype)
{
case VarType.Bit:
MyWrite(0x0F);
break;
case VarType.Word:
case VarType.Int:
case VarType.DWord:
case VarType.DInt:
case VarType.Real:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("写入失败,变量类型不支持");
break;
}
}
catch (Exception)
{
MessageBox.Show("参数配置错误");
AutoFlag = false;
break;
}
break;
case "10 Write Multiple Registers"://写一组保持寄存器
if (!SetWriteParametes())
{
return;
}
switch (vartype)
{
case VarType.Word:
case VarType.Int:
case VarType.DWord:
case VarType.DInt:
case VarType.Real:
MyWrite(0x10);
break;
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("写入失败,变量类型不支持");
break;
}
break;
default:
break;
}
}
else
{
MessageBox.Show("请选择功能码!");
}
//port.Close();
}
catch (Exception ex)
{
//port.Close();
//button1.Enabled = false;
//button3.Text = "打开串口";//按钮显示打开
MessageBox.Show(ex.Message);
}
}
#endregion
byte addH;
byte addL;
byte lenH;
byte lenL;
ushort num = 0;
//01 01 00 00 00 0A BC 0D
//01 01 02 05 00 BA AC
//01 02 00 00 00 0A F8 0D
//01 02 02 25 01 62 E8
//01 03 00 00 00 0D 84 0F
//01 03 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D3 C2
//01 04 00 00 00 0D 31 CF
//01 04 1A 00 00 00 6F 00 00 00 00 01 4D 00 00 00 00 01 BC 00 00 02 2B 00 00 00 DE 00 00 6A 13
/// <summary>
/// 读命令
/// </summary>
/// <param name="f">功能码</param>
/// <param name="length">16位数据长度为去1,32位数据长度位2</param>
private void MyRead(byte f, int length = 1)
{
UshortToHex(ref addL, ref addH, startAddress);
UshortToHex(ref lenL, ref lenH, (ushort)(numberOfPoints * length));
byte[] byteArray1 = { slaveAddress, f, addH, addL, lenH, lenL };
UintToHex(ref L, ref H, GetCRC16(byteArray1));
byte[] byteArray2 = { slaveAddress, f, addH, addL, lenH, lenL, L, H };
if (rbRTU.Checked)
{
port.Write(byteArray2, 0, byteArray2.Length);
}
else if (rbTCP.Checked)
{
num++;
byte[] bytenum = BitConverter.GetBytes((int)num);
byte[] byteArray3 = { bytenum[1], bytenum[0], 0, 0, 0, 6, slaveAddress, f, addH, addL, lenH, lenL };
socketSend.Send(byteArray3);
}
}
//01 05 00 00 FF 00 8C 3A
//01 05 00 00 FF 00 8C 3A
//01 06 00 00 00 02 08 0B
//01 06 00 00 00 02 08 0B
//01 0F 00 00 00 0A 02 09 00 E3 68
//01 0F 00 00 00 0A D5 CC
//01 0F 00 00 00 19 04 09 00 00 00 C2 7D
//01 0F 00 00 00 19 94 01
//01 0F 00 00 00 19 04 09 50 40 00 F3 AC
//01 0F 00 00 00 19 94 01
/// <summary>
/// 写命令 通断标志为FF00H表示写ON,0000H表示写OFF
/// </summary>
/// <param name="f">功能码</param>
private void MyWrite(byte f)
{
byte[] dataBuff0 = { 0, 0 };
byte[] intBuff = { 0, 0, 0, 0 };
byte[] lenghtBuff = { 0, 0, 0, 0 };
byte[] dataBuff;
int[] int1;
List<byte> frameBytes = new List<byte>();
UshortToHex(ref addL, ref addH, startAddress);
if (f == 0x05)
{
if (coilsBuffer[0])
{
dataBuff0[0] = 0xFF;
dataBuff0[1] = 0x00;
}
else
{
dataBuff0[0] = 0x00;
dataBuff0[1] = 0x00;
}
}
else if (f == 0x06)
{
switch (vartype)
{
case VarType.Word:
dataBuff0[0] = (byte)((0xff00 & UshortBuffer[0]) >> 8);
dataBuff0[1] = (byte)(0xff & UshortBuffer[0]);
//dataBuff0 = GetIntByteArray(dataBuff0, 0, dataFormat);
break;
case VarType.Int:
dataBuff0[0] = (byte)((0xff00 & ShortBuffer[0]) >> 8);
dataBuff0[1] = (byte)(0xff & ShortBuffer[0]);
//dataBuff0 = GetIntByteArray(dataBuff0, 0, dataFormat);
break;
case VarType.DWord:
case VarType.DInt:
case VarType.Real:
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
break;
}
}
else if (f == 0x0F)
{
int1 = new int[(coilsBuffer.Length / 4)];
intBuff = BitConverter.GetBytes(numberOfPoints);
for (int i = 0; i < coilsBuffer.Length; i += 4)
{
int1[i / 4] = Convert.ToInt32(coilsBuffer[i]) + Convert.ToInt32(coilsBuffer[i + 1]) * 2 + Convert.ToInt32(coilsBuffer[i + 2]) * 4 + Convert.ToInt32(coilsBuffer[i + 3]) * 8;
}
dataBuff = new byte[coilsBuffer.Length / 8];
for (int i = 0; i < int1.Length; i += 2)
{
dataBuff[i / 2] = (byte)(int1[i] + int1[i + 1] * 16);
}
if (rbRTU.Checked)
{
frameBytes.Clear();
frameBytes.Add(slaveAddress);
frameBytes.Add(f);
frameBytes.Add(addH);
frameBytes.Add(addL);
frameBytes.Add(intBuff[1]);
frameBytes.Add(intBuff[0]);
frameBytes.Add((byte)dataBuff.Length);
for (int i = 0; i < dataBuff.Length; i++)
{
frameBytes.Add(dataBuff[i]);
}
byte[] byteArray1 = frameBytes.ToArray();//list转byte[]
UintToHex(ref L, ref H, GetCRC16(byteArray1));
frameBytes.Add(L);
frameBytes.Add(H);
byte[] byteArray2 = frameBytes.ToArray();
port.Write(byteArray2, 0, byteArray2.Length);
}
else if (rbTCP.Checked)
{
num++;
lenghtBuff = BitConverter.GetBytes(dataBuff.Length + 7);
frameBytes.Clear();
byte[] bytenum = BitConverter.GetBytes((int)num);
frameBytes.Add(bytenum[1]);
frameBytes.Add(bytenum[0]);
frameBytes.Add(0);
frameBytes.Add(0);
frameBytes.Add(lenghtBuff[1]);
frameBytes.Add(lenghtBuff[0]);
frameBytes.Add(slaveAddress);
frameBytes.Add(f);
frameBytes.Add(addH);
frameBytes.Add(addL);
frameBytes.Add(intBuff[1]);
frameBytes.Add(intBuff[0]);
frameBytes.Add((byte)dataBuff.Length);
for (int i = 0; i < dataBuff.Length; i++)
{
frameBytes.Add(dataBuff[i]);
}
byte[] byteArray3 = frameBytes.ToArray();//list转byte[]
socketSend.Send(byteArray3);
}
}
else if (f == 0x10)
{
byte[] temp = { 0, 0, 0, 0 };
if (rbRTU.Checked)
{
frameBytes.Clear();
frameBytes.Add(slaveAddress);
frameBytes.Add(f);
frameBytes.Add(addH);
frameBytes.Add(addL);
}
else if (rbTCP.Checked)
{
num++;
frameBytes.Clear();
byte[] bytenum = BitConverter.GetBytes((int)num);
frameBytes.Add(bytenum[1]);
frameBytes.Add(bytenum[0]);
frameBytes.Add(0);
frameBytes.Add(0);
}
switch (vartype)
{
case VarType.Word:
byte[] UshortBuff = new byte[UshortBuffer.Length * 2];
for (int i = 0; i < UshortBuff.Length; i += 2)
{
UshortBuff[i] = (byte)((0xff00 & UshortBuffer[i / 2]) >> 8);
UshortBuff[i + 1] = (byte)(0xff & UshortBuffer[i / 2]);
}
intBuff = BitConverter.GetBytes(numberOfPoints);
if (rbTCP.Checked)
{
lenghtBuff = BitConverter.GetBytes(UshortBuff.Length + 7);
frameBytes.Add(lenghtBuff[1]);
frameBytes.Add(lenghtBuff[0]);
frameBytes.Add(slaveAddress);
frameBytes.Add(f);
frameBytes.Add(addH);
frameBytes.Add(addL);
}
frameBytes.Add(intBuff[1]);
frameBytes.Add(intBuff[0]);
frameBytes.Add((byte)UshortBuff.Length);
for (int i = 0; i < UshortBuff.Length; i++)
{
frameBytes.Add(UshortBuff[i]);
}
byte[] byteArray10 = frameBytes.ToArray();//list转byte[]
if (rbTCP.Checked)
{
socketSend.Send(byteArray10);
}
if (rbRTU.Checked)
{
UintToHex(ref L, ref H, GetCRC16(byteArray10));
frameBytes.Add(L);
frameBytes.Add(H);
byte[] byteArray20 = frameBytes.ToArray();
port.Write(byteArray20, 0, byteArray20.Length);
}
break;
case VarType.Int:
byte[] ShortBuff = new byte[ShortBuffer.Length * 2];
for (int i = 0; i < ShortBuff.Length; i += 2)
{
ShortBuff[i] = (byte)((0xff00 & ShortBuffer[i / 2]) >> 8);
ShortBuff[i + 1] = (byte)(0xff & ShortBuffer[i / 2]);
}
intBuff = BitConverter.GetBytes(numberOfPoints);
if (rbTCP.Checked)
{
lenghtBuff = BitConverter.GetBytes(ShortBuff.Length + 7);
frameBytes.Add(lenghtBuff[1]);
frameBytes.Add(lenghtBuff[0]);
frameBytes.Add(slaveAddress);
frameBytes.Add(f);
frameBytes.Add(addH);
frameBytes.Add(addL);
}
frameBytes.Add(intBuff[1]);
frameBytes.Add(intBuff[0]);
frameBytes.Add((byte)ShortBuff.Length);
for (int i = 0; i < ShortBuff.Length; i++)
{
frameBytes.Add(ShortBuff[i]);
}
byte[] byteArray11 = frameBytes.ToArray();//list转byte[]
if (rbTCP.Checked)
{
socketSend.Send(byteArray11);
}
if (rbRTU.Checked)
{
UintToHex(ref L, ref H, GetCRC16(byteArray11));
frameBytes.Add(L);
frameBytes.Add(H);
byte[] byteArray21 = frameBytes.ToArray();
port.Write(byteArray21, 0, byteArray21.Length);
}
break;
case VarType.DWord:
byte[] UintBuff = new byte[UintBuffer.Length * 4];
for (int i = 0; i < UintBuff.Length; i += 4)
{
UintBuff[i] = (byte)((0xff000000 & UintBuffer[i / 4]) >> 24);
UintBuff[i + 1] = (byte)((0xff0000 & UintBuffer[i / 4]) >> 16);
UintBuff[i + 2] = (byte)((0xff00 & UintBuffer[i / 4]) >> 8);
UintBuff[i + 3] = (byte)(0xff & UintBuffer[i / 4]);
}
intBuff = BitConverter.GetBytes(numberOfPoints * 2);
if (rbTCP.Checked)
{
lenghtBuff = BitConverter.GetBytes(UintBuff.Length + 7);
frameBytes.Add(lenghtBuff[1]);
frameBytes.Add(lenghtBuff[0]);
frameBytes.Add(slaveAddress);
frameBytes.Add(f);
frameBytes.Add(addH);
frameBytes.Add(addL);
}
frameBytes.Add(intBuff[1]);
frameBytes.Add(intBuff[0]);
frameBytes.Add((byte)UintBuff.Length);
for (int i = 0; i < UintBuff.Length; i += 4)
{
temp = GetSingleByteArray(UintBuff, i, dataFormat);
frameBytes.Add(temp[0]);
frameBytes.Add(temp[1]);
frameBytes.Add(temp[2]);
frameBytes.Add(temp[3]);
}
byte[] byteArray12 = frameBytes.ToArray();//list转byte[]if (rbTCP.Checked)
if (rbTCP.Checked)
{
socketSend.Send(byteArray12);
}
if (rbRTU.Checked)
{
UintToHex(ref L, ref H, GetCRC16(byteArray12));
frameBytes.Add(L);
frameBytes.Add(H);
byte[] byteArray22 = frameBytes.ToArray();
port.Write(byteArray22, 0, byteArray22.Length);
}
break;
case VarType.DInt:
byte[] IntBuff = new byte[IntBuffer.Length * 4];
for (int i = 0; i < IntBuff.Length; i += 4)
{
IntBuff[i] = (byte)((0xff000000 & IntBuffer[i / 4]) >> 24);
IntBuff[i + 1] = (byte)((0xff0000 & IntBuffer[i / 4]) >> 16);
IntBuff[i + 2] = (byte)((0xff00 & IntBuffer[i / 4]) >> 8);
IntBuff[i + 3] = (byte)(0xff & IntBuffer[i / 4]);
}
intBuff = BitConverter.GetBytes(numberOfPoints * 2);
if (rbTCP.Checked)
{
lenghtBuff = BitConverter.GetBytes(IntBuff.Length + 7);
frameBytes.Add(lenghtBuff[1]);
frameBytes.Add(lenghtBuff[0]);
frameBytes.Add(slaveAddress);
frameBytes.Add(f);
frameBytes.Add(addH);
frameBytes.Add(addL);
}
frameBytes.Add(intBuff[1]);
frameBytes.Add(intBuff[0]);
frameBytes.Add((byte)IntBuff.Length);
for (int i = 0; i < IntBuff.Length; i += 4)
{
temp = GetSingleByteArray(IntBuff, i, dataFormat);
frameBytes.Add(temp[0]);
frameBytes.Add(temp[1]);
frameBytes.Add(temp[2]);
frameBytes.Add(temp[3]);
}
byte[] byteArray13 = frameBytes.ToArray();//list转byte[]
if (rbTCP.Checked)
{
socketSend.Send(byteArray13);
}
if (rbRTU.Checked)
{
UintToHex(ref L, ref H, GetCRC16(byteArray13));
frameBytes.Add(L);
frameBytes.Add(H);
byte[] byteArray23 = frameBytes.ToArray();
port.Write(byteArray23, 0, byteArray23.Length);
}
break;
case VarType.Real:
byte[] FloatBuff = new byte[FloatBuffer.Length * 4];
for (int i = 0; i < FloatBuff.Length; i += 4)
{
temp = BitConverter.GetBytes(FloatBuffer[i / 4]);
temp = GetSingleByteArray(temp, 0, dataFormat);
FloatBuff[i] = temp[3];
FloatBuff[i + 1] = temp[2];
FloatBuff[i + 2] = temp[1];
FloatBuff[i + 3] = temp[0];
}
intBuff = BitConverter.GetBytes(numberOfPoints * 2);
if (rbTCP.Checked)
{
lenghtBuff = BitConverter.GetBytes(FloatBuff.Length + 7);
frameBytes.Add(lenghtBuff[1]);
frameBytes.Add(lenghtBuff[0]);
frameBytes.Add(slaveAddress);
frameBytes.Add(f);
frameBytes.Add(addH);
frameBytes.Add(addL);
}
frameBytes.Add(intBuff[1]);
frameBytes.Add(intBuff[0]);
frameBytes.Add((byte)FloatBuff.Length);
for (int i = 0; i < FloatBuff.Length; i++)
{
frameBytes.Add(FloatBuff[i]);
}
byte[] byteArray14 = frameBytes.ToArray();//list转byte[]
if (rbTCP.Checked)
{
socketSend.Send(byteArray14);
}
if (rbRTU.Checked)
{
UintToHex(ref L, ref H, GetCRC16(byteArray14));
frameBytes.Add(L);
frameBytes.Add(H);
byte[] byteArray24 = frameBytes.ToArray();
port.Write(byteArray24, 0, byteArray24.Length);
}
break;
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
break;
}
}
if (f != 0x0f && f != 0x10)
{
byte[] byteArray1 = { slaveAddress, f, addH, addL, dataBuff0[0], dataBuff0[1] };
UintToHex(ref L, ref H, GetCRC16(byteArray1));
byte[] byteArray2 = { slaveAddress, f, addH, addL, dataBuff0[0], dataBuff0[1], L, H };
if (rbRTU.Checked)
{
port.Write(byteArray2, 0, byteArray2.Length);
}
else if (rbTCP.Checked)
{
num++;
byte[] bytenum = BitConverter.GetBytes((int)num);
byte[] byteArray3 = { bytenum[1], bytenum[0], 0, 0, 0, 6, slaveAddress, f, addH, addL, dataBuff0[0], dataBuff0[1] };
socketSend.Send(byteArray3);
}
}
//port.Write(byteArray2, 0, byteArray2.Length);
}
private void ResolutionCoils(byte[] buff1)//解析线圈
{
switch (vartype)
{
case VarType.Bit:
//byte[] buff1 = buff.Skip(3).Take(2).ToArray();
BitArray bitSet1 = new BitArray(buff1);//a为byte数组,bitSet是bool类型的数组
//for (int i = 0; i < bitSet1.Count; i++)
//{
// coilsBuffer[i] = bitSet1[i];
//}
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
for (int i = 0; i < numberOfPoints; i++)
{
//SetMsg(coilsBuffer[i] + " ");
SetMsg(bitSet1[i] + " ");
}
SetMsg("\r\n");
break;
case VarType.Word:
case VarType.DWord:
case VarType.Int:
case VarType.DInt:
case VarType.Real:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("读取失败,变量类型不支持");
break;
}
}
private void ResolutionRegisters(byte[] buff3)//解析寄存器
{
switch (vartype)
{
case VarType.Word:
string wordvalue = string.Empty;
buff3 = SwapAB(buff3);
if (buff3 != null && buff3.Length == numberOfPoints * 2)
{
for (int i = 0; i < buff3.Length; i += 2)
{
//wordvalue += BitConverter.ToUInt16(GetIntByteArray(buff3, i, dataFormat), 0).ToString() + " ";
wordvalue += BitConverter.ToUInt16(buff3.Skip(i).Take(2).ToArray(), 0).ToString() + " ";
}
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
SetMsg(wordvalue + " ");
SetMsg("\r\n");
}
else
{
SetMsg("读取失败,请检查地址、类型及连接状态");
SetMsg("\r\n");
}
break;
case VarType.DWord:
buff3 = SwapABCD(buff3);
string dwordvalue = string.Empty;
if (buff3 != null && buff3.Length == numberOfPoints * 4)
{
for (int i = 0; i < buff3.Length; i += 4)
{
dwordvalue += BitConverter.ToUInt32(GetSingleByteArray(buff3, i, dataFormat), 0).ToString() + " ";
}
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
SetMsg(dwordvalue + " ");
SetMsg("\r\n");
}
else
{
SetMsg("读取失败,请检查地址、类型及连接状态");
SetMsg("\r\n");
}
break;
case VarType.Int:
buff3 = SwapAB(buff3);
string intvalue = string.Empty;
if (buff3 != null && buff3.Length == numberOfPoints * 2)
{
for (int i = 0; i < buff3.Length; i += 2)
{
//intvalue += BitConverter.ToInt16(GetIntByteArray(buff3, i, dataFormat), 0).ToString() + " ";
intvalue += BitConverter.ToInt16(buff3.Skip(i).Take(2).ToArray(), 0).ToString() + " ";
}
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
SetMsg(intvalue + " ");
SetMsg("\r\n");
}
else
{
SetMsg("读取失败,请检查地址、类型及连接状态");
SetMsg("\r\n");
}
break;
case VarType.DInt:
buff3 = SwapABCD(buff3);
string dintvalue = string.Empty;
if (buff3 != null && buff3.Length == numberOfPoints * 4)
{
for (int i = 0; i < buff3.Length; i += 4)
{
dintvalue += BitConverter.ToInt32(GetSingleByteArray(buff3, i, dataFormat), 0).ToString() + " ";
}
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
SetMsg(dintvalue + " ");
SetMsg("\r\n");
}
else
{
SetMsg("读取失败,请检查地址、类型及连接状态");
SetMsg("\r\n");
}
break;
case VarType.Real:
buff3 = SwapABCD(buff3);
string floatvalue = string.Empty;
if (buff3 != null && buff3.Length == numberOfPoints * 4)
{
for (int i = 0; i < buff3.Length; i += 4)
{
floatvalue += BitConverter.ToSingle(GetSingleByteArray(buff3, i, dataFormat), 0).ToString() + " ";
}
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
SetMsg(floatvalue + " ");
SetMsg("\r\n");
}
else
{
SetMsg("读取失败,请检查地址、类型及连接状态");
SetMsg("\r\n");
}
break;
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
MessageBox.Show("读取失败,变量类型不支持");
break;
}
}
private void ResolutionReply(byte[] buff, byte f)//解析写数据回复
{
byte f1 = buff[1];
string res = "false";
if (f == 0x05)
{
if (buff[4] == 0xff)
{
res = "true";
}
else
{
res = "false";
}
}
else if (f == 0x06)
{
//byte[] buff3 = { buff[5], buff[4], 0, 0 };
//res = (BitConverter.ToInt32(buff3, 0)).ToString();
switch (vartype)
{
case VarType.Word:
byte[] UshortBuff = { buff[5], buff[4] };
res = (BitConverter.ToUInt16(UshortBuff, 0)).ToString();
break;
case VarType.Int:
byte[] ShortBuff = { buff[5], buff[4] };
res = (BitConverter.ToInt16(ShortBuff, 0)).ToString();
break;
case VarType.DWord:
case VarType.DInt:
case VarType.Real:
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
break;
}
}
else if (f == 0x0f)
{
res = "";
byte[] intBuff = { 0, 0, 0, 0 };
intBuff = BitConverter.GetBytes(numberOfPoints);
if (buff[4] == intBuff[1] && buff[5] == intBuff[0] && f1 == f)
{
string[] strarr = InPutstr.Split(' ');
for (int i = 0; i < strarr.Length; i++)
{
if (i < strarr.Length)
{
if (strarr[i] == "0")
{
strarr[i] = "fasle";
}
else
{
strarr[i] = "true";
}
res += strarr[i] + " ";
}
}
}
else
{
f1 = (byte)(f + 1);
}
}
else if (f == 0x10)
{
res = "";
byte[] intBuff = { 0, 0, 0, 0 };
switch (vartype)
{
case VarType.Word:
intBuff = BitConverter.GetBytes(numberOfPoints);
break;
case VarType.Int:
intBuff = BitConverter.GetBytes(numberOfPoints);
break;
case VarType.DWord:
intBuff = BitConverter.GetBytes(numberOfPoints * 2);
break;
case VarType.DInt:
intBuff = BitConverter.GetBytes(numberOfPoints * 2);
break;
case VarType.Real:
intBuff = BitConverter.GetBytes(numberOfPoints * 2);
break;
case VarType.Bit:
case VarType.String:
case VarType.Byte:
case VarType.Timer:
case VarType.Counter:
break;
}
if (buff[4] == intBuff[1] && buff[5] == intBuff[0] && f1 == f)
{
res = InPutstr;
}
else
{
f1 = (byte)(f + 1);
}
}
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " "));
SetMsg(f1 == f ? "写入成功,写入值:" + res : "写入失败");
SetMsg("\r\n");
}
/// <summary>
/// 串口发送
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button4_Click(object sender, EventArgs e)
{
String Str = txt_data.Text.ToString();//获取发送文本框里面的数据
try
{
if (Str.Length > 0)
{
if (checkBox2.Checked)//16进制发送
{
byte[] byt = strToToHexByte(Str);
port.Write(byt, 0, byt.Length);
}
else
{
port.Write(Str);//串口发送数据
}
}
}
catch (Exception) { }
}
/// <summary>
/// 串口接收事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int len = port.BytesToRead;//获取可以读取的字节数
byte[] buff = new byte[len];//创建缓存数据数组
port.Read(buff, 0, len);//把数据读取到buff数组
if (buff.Length > 1 && buff[1] != 0x81 && buff[1] != 0x83)
{
if (functionCode != null)
{
switch (functionCode)
{
case "01 Read Coils"://读取输出线圈
byte[] buff0 = buff.Skip(3).Take(buff[2]).ToArray();
ResolutionCoils(buff0);
break;
case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
byte[] buff1 = buff.Skip(3).Take(buff[2]).ToArray();
ResolutionCoils(buff1);
break;
case "03 Read Holding Registers"://读取保持寄存器
byte[] buff2 = buff.Skip(3).Take(buff[2]).ToArray();
ResolutionRegisters(buff2);
break;
case "04 Read Input Registers"://读取输入寄存器
byte[] buff3 = buff.Skip(3).Take(buff[2]).ToArray();
ResolutionRegisters(buff3);
break;
case "05 Write Single Coil"://写单个线圈
ResolutionReply(buff, 05);
break;
case "06 Write Single Registers"://写单个保持寄存器
ResolutionReply(buff, 06);
break;
case "0F Write Multiple Coils"://写一组线圈
ResolutionReply(buff, 0x0F);
break;
case "10 Write Multiple Registers"://写一组保持寄存器
ResolutionReply(buff, 0x10);
break;
}
}
}
else
{
if (buff.Length > 2)
{
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " "));
SetMsg("异常应答,异常代码:" + buff[2].ToString() + " ");
SetMsg("\r\n");
}
}
//Buff = buff;
//SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " "));
//Invoke((new Action(() =>
//{//C# 3.0以后代替委托的新方法
// if (checkBox1.Checked)//16进制显示
// {
// SetMsg(byteToHexStr(buff) + " ");//对话框追加显示数据
// }
// else
// {
// SetMsg(Encoding.Default.GetString(buff) + " ");//对话框追加显示数据
// }
//})));
//SetMsg("\r\n");
//Buff = buff.Take(len - 2).ToArray();
//UintToHex(ref L, ref H, GetCRC16(Buff));
//List<byte> frameBytes = new List<byte>();
//for (int i = 0; i < Buff.Length; i++)
//{
// frameBytes.Add(Buff[i]);
//}
//frameBytes.Add(L);
//frameBytes.Add(H);
//Buff = frameBytes.ToArray();//list转byte[]
// List<byte> b=transByte.ToList();//byte[]转list
//SetMsg(byteToHexStr(Buff) + " ");//对话框追加显示数据
//SetMsg("\r\n");
}
byte L;
byte H;
public static void UintToHex(ref byte L, ref byte H, uint Val)
{
L = (byte)(Val & (uint)byte.MaxValue);
H = (byte)(Val >> 8);
}
public static void UshortToHex(ref byte L, ref byte H, ushort Val)
{
L = (byte)((uint)Val & (uint)byte.MaxValue);
H = (byte)((uint)Val >> 8);
}
/// <字节数组转16进制字符串>
/// <param name="bytes"></param>
/// <returns> String 16进制显示形式</returns>
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
try
{
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2");
returnStr += " ";//两个16进制用空格隔开,方便看数据
}
}
return returnStr;
}
catch (Exception)
{
return returnStr;
}
}
/// <字符串转16进制格式,不够自动前面补零>
///
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
private static byte[] strToToHexByte(String hexString)
{
int i;
hexString = hexString.Replace(" ", "");//清除空格
if ((hexString.Length % 2) != 0)//奇数个
{
byte[] returnBytes = new byte[(hexString.Length + 1) / 2];
try
{
for (i = 0; i < (hexString.Length - 1) / 2; i++)
{
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
returnBytes[returnBytes.Length - 1] = Convert.ToByte(hexString.Substring(hexString.Length - 1, 1).PadLeft(2, '0'), 16);
}
catch
{
MessageBox.Show("含有非16进制字符", "提示");
return null;
}
return returnBytes;
}
else
{
byte[] returnBytes = new byte[(hexString.Length) / 2];
try
{
for (i = 0; i < returnBytes.Length; i++)
{
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
}
catch
{
MessageBox.Show("含有非16进制字符", "提示");
return null;
}
return returnBytes;
}
}
/// <summary>
/// ABABABABAB……转换为BABABABABA
/// </summary>
/// <param name="byteArr"></param>
/// <returns></returns>
private byte[] SwapAB(byte[] byteArr)
{
if (byteArr.Length % 2 == 0)
{
byte tmpe;
for (int i = 0; i < byteArr.Length; i += 2)
{
tmpe = byteArr[i];
byteArr[i] = byteArr[i + 1];
byteArr[i + 1] = tmpe;
}
return byteArr;
}
else
{
MessageBox.Show("数据长度错误");
return null;
}
}
/// <summary>
/// ABCDABCDABCDABCDABCD……转换为DCBADCBADCBADCBADCBA
/// </summary>
/// <param name="byteArr"></param>
/// <returns></returns>
private byte[] SwapABCD(byte[] byteArr)
{
byte tmpe1;
byte tmpe2;
if (byteArr.Length % 4 == 0)
{
for (int i = 0; i < byteArr.Length; i += 4)
{
tmpe1 = byteArr[i];
tmpe2 = byteArr[i + 1];
byteArr[i] = byteArr[i + 3];
byteArr[i + 1] = byteArr[i + 2];
byteArr[i + 2] = tmpe2;
byteArr[i + 3] = tmpe1;
}
return byteArr;
}
else
{
MessageBox.Show("数据长度错误");
return null;
}
}
#region 双字节顺序转换
/// <summary>
/// 双字节顺序转换:1为AB,2为BA
/// </summary>
/// <param name="byteArr"></param>
/// <param name="start"></param>
/// <param name="type"></param>
/// <returns></returns>
private byte[] GetIntByteArray(byte[] byteArr, int start, DataFormat type)
{
byte[] Res = new byte[2];
if (byteArr != null && byteArr.Length >= start + 2)
{
for (int i = 0; i < 2; i++)
{
Res[i] = byteArr[i + start];
}
byte[] Res1 = new byte[2];
switch (type)
{
case DataFormat.ABCD:
case DataFormat.CDAB:
Res1 = Res;
break;
case DataFormat.BADC:
case DataFormat.DCBA:
Res1[1] = Res[0];
Res1[0] = Res[1];
break;
default:
break;
}
return Res1;
}
return Res;
}
#endregion
#region 四字节顺序转换
/// <summary>
/// 四字节顺序转换:1为ABCD,2为BADC,3为CDAB,4为 DCBA
/// </summary>
/// <param name="byteArr"></param>
/// <param name="start"></param>
/// <param name="type"></param>
/// <returns></returns>
private byte[] GetSingleByteArray(byte[] byteArr, int start, DataFormat type)
{
byte[] Res = new byte[4];
if (byteArr != null && byteArr.Length >= start + 4)
{
for (int i = 0; i < 4; i++)
{
Res[i] = byteArr[i + start];
}
byte[] Res1 = new byte[4];
switch (type)
{
case DataFormat.ABCD:
Res1 = Res;
break;
case DataFormat.BADC:
Res1[0] = Res[1];
Res1[1] = Res[0];
Res1[2] = Res[3];
Res1[3] = Res[2];
break;
case DataFormat.CDAB:
Res1[0] = Res[2];
Res1[1] = Res[3];
Res1[2] = Res[0];
Res1[3] = Res[1];
break;
case DataFormat.DCBA:
Res1[0] = Res[3];
Res1[1] = Res[2];
Res1[2] = Res[1];
Res1[3] = Res[0];
break;
default:
break;
}
return Res1;
}
return Res;
}
#endregion
#region CRC校验
public uint GetCRC16(byte[] buffer)
{
int length = buffer.Length;
byte data;
uint crc = 0xFFFF; //初始值(16位举个例子0xFFFF,8位0xFF)
int i;
for (int j = 0; j < length; j++)
{
data = buffer[j];
data = (byte)Reverse8(data); //输入是否反转,如果不需要则这句注释掉;
crc = (uint)(crc ^ (data << 8)); //32位左移24位,16位左移8位,8位左移0位;
for (i = 0; i < 8; i++)
{
if ((crc & 0x8000) == 0x8000)//16位 0x8000 8位 0x80
{
crc = (crc << 1) ^ 0x8005;//多项式,没什么好说的;
}
else
{
crc <<= 1;
}
}
}
crc = Reverse16(crc);//输出是否需要反转,如果不需要则注释掉这句话,注意如果是16位则调用Reverse16(crc),8位调用Reverse8(crc)
crc = crc ^ 0x0000;// xor 异或值(与上面初始值类似,16位 0x0000 8位 0x00;
return crc;
}
public uint GetCRC32(byte[] buffer)
{
int length = buffer.Length;
byte data;
uint crc = 0xFFFFFFFF; //初始值(16位举个例子0xFFFF,8位0xFF)
int i;
for (int j = 0; j < length; j++)
{
data = buffer[j];
data = (byte)Reverse8(data); //输入是否反转,如果不需要则这句注释掉;
crc = (uint)(crc ^ (data << 24)); //32位左移24位,16位左移8位,8位左移0位;
for (i = 0; i < 8; i++)
{
if ((crc & 0x80000000) == 0x80000000)//16位 0x8000 8位 0x80
{
crc = (crc << 1) ^ 0x04C11DB7;//多项式,没什么好说的;
}
else
{
crc <<= 1;
}
}
}
crc = Reverse32(crc);//输出是否需要反转,如果不需要则注释掉这句话,注意如果是16位则调用Reverse16(crc),8位调用Reverse8(crc)
crc = crc ^ 0x00000000;// xor 异或值(与上面初始值类似,16位 0x0000 8位 0x00;
return crc;
}
private uint Reverse32(uint data)
{
byte i;
uint temp = 0;
for (i = 0; i < 32; i++)
{
temp |= ((data >> i) & 0x01) << (31 - i);
}
return temp;
}
private uint Reverse16(uint data)
{
byte i;
uint temp = 0;
for (i = 0; i < 16; i++)
{
temp |= ((data >> i) & 0x01) << (15 - i);
}
return temp;
}
private byte Reverse8(byte data)
{
byte i;
byte temp = 0;
for (i = 0; i < 8; i++)
{
temp = (byte)(temp | (((data >> i) & 0x01) << (7 - i)));
}
return temp;
}
#endregion
private void cmb_DataFormat_SelectedIndexChanged(object sender, EventArgs e)
{
dataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), cmb_DataFormat.SelectedItem.ToString(), false);
}
private void cmb_VarType_SelectedIndexChanged(object sender, EventArgs e)
{
vartype = (VarType)Enum.Parse(typeof(VarType), cmb_VarType.SelectedItem.ToString(), false);
}
private void rb_CheckedChanged(object sender, EventArgs e)
{
gbRTU.Enabled = rbRTU.Checked;
gbTCP.Enabled = rbTCP.Checked;
}
private void btnOpen_Click(object sender, EventArgs e)
{
if (btnOpen.Text == "打开连接")
{//如果按钮显示的是打开串口
try
{
//防止意外错误
if (!InitPortParameter())
{
return;
}
//创建客户端Socket,获得远程ip和端口号
socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(IP);
IPEndPoint point = new IPEndPoint(ip, Port);
socketSend.Connect(point);
SetMsg("连接成功!");
SetMsg("\r\n");
IsOpen = true;
btnOpen.Text = "断开连接";
button1.Enabled = true;
//开启新的线程,不停的接收服务器发来的消息
Thread c_thread = new Thread(Received);
c_thread.IsBackground = true;
c_thread.Start();
}
catch (Exception)
{
IsOpen = false;
SetMsg("IP或者端口号错误...");
SetMsg("\r\n");
}
}
else
{
try
{//防止意外错误
socketSend.Close();//关闭
button1.Enabled = false;
btnOpen.Text = "打开连接";//按钮显示打开
SetMsg("断开连接成功!");
SetMsg("\r\n");
}
catch (Exception) { }
}
}
void send(string msg)
{
try
{
byte[] buffer = new byte[1024 * 1024 * 3];
buffer = Encoding.UTF8.GetBytes(msg);
socketSend.Send(buffer);
}
catch { }
}
/// <summary>
/// 接收服务端返回的消息
/// </summary>
void Received()
{
while (true)
{
try
{
byte[] buff = new byte[1024 * 1024 * 3];
//实际接收到的有效字节数
int len = socketSend.Receive(buff);
if (len == 0)
{
break;
}
//string str = Encoding.UTF8.GetString(buff, 0, len);
//SetMsg(socketSend.RemoteEndPoint + ":" + str);
//SetMsg("\r\n");
if (buff.Length > 7 && buff[7] != 0x81 && buff[7] != 0x83)
{
if (functionCode != null)
{
switch (functionCode)
{
case "01 Read Coils"://读取输出线圈
byte[] buff0 = buff.Skip(9).Take(buff[8]).ToArray();
ResolutionCoils(buff0);
break;
case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
byte[] buff1 = buff.Skip(9).Take(buff[8]).ToArray();
ResolutionCoils(buff1);
break;
case "03 Read Holding Registers"://读取保持寄存器
byte[] buff2 = buff.Skip(9).Take(buff[8]).ToArray();
ResolutionRegisters(buff2);
break;
case "04 Read Input Registers"://读取输入寄存器
byte[] buff3 = buff.Skip(9).Take(buff[8]).ToArray();
ResolutionRegisters(buff3);
break;
case "05 Write Single Coil"://写单个线圈
byte[] buff4 = buff.Skip(6).ToArray();
ResolutionReply(buff4, 05);
break;
case "06 Write Single Registers"://写单个保持寄存器
byte[] buff5 = buff.Skip(6).ToArray();
ResolutionReply(buff5, 06);
break;
case "0F Write Multiple Coils"://写一组线圈
byte[] buff6 = buff.Skip(6).ToArray();
ResolutionReply(buff6, 0x0F);
break;
case "10 Write Multiple Registers"://写一组保持寄存器
byte[] buff7 = buff.Skip(6).ToArray();
ResolutionReply(buff7, 0x10);
break;
}
}
}
else
{
if (buff.Length > 8)
{
Current_time = System.DateTime.Now;
SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " "));
SetMsg("异常应答,异常代码:" + buff[8].ToString() + " ");
SetMsg("\r\n");
}
}
}
catch { }
}
}
}
}