C# desarrolla un asistente de depuración de puerto serie para realizar la comunicación modbusRTU

Hagamos un proyecto para todos hoy, ven conmigo, no te lo pierdas cuando pases, y mira cómo la gran V juega el desarrollo de software industrial C #. El propósito de hacer las cosas es: dominar el protocolo de comunicación MODBUS RTU, dominar el desarrollo de asistentes de depuración de puertos serie simples y dominar el proceso de comunicación del puerto serie

Productos de hardware: sensor de temperatura y humedad del puerto serie RS232, utilizado para probar la temperatura y la humedad del mundo exterior, como almacenes, invernaderos, talleres, etc., directamente en Tbao

 Un cable USB a 232, utilizado para conectar el dispositivo y la computadora

 La conexión del hardware es como se muestra en la figura: el host tiene muchos puertos USB, por lo que no necesita el extensor USB, simplemente conéctelo a la computadora directamente

 Después de que la conexión del hardware sea exitosa, verifique el puerto serie en el "Administrador de dispositivos"

Entorno de software: VS2019, C#, WINFORM, software de herramientas del fabricante

1. Obtenga el manual, el software de la herramienta del fabricante y pruebe el equipo. Este pdf es el manual. Léalo detenidamente. Si no lo entiende, pregúntele al fabricante.

Instale el software de la herramienta proporcionado por el fabricante,

 Método de prueba 1: encienda la plataforma de recolección y monitoreo DL-MDM, puede ver dos datos de temperatura y humedad, lo que indica que el equipo está funcionando normalmente

 Método de prueba 2: use el asistente de depuración del puerto serie, 

Nota: Para cerrar y salir del software de la herramienta anterior

Prueba de acuerdo con las instrucciones del fabricante y las instrucciones enviadas

 

 

 

Prueba 3: escriba el programa winform C# usted mismo para realizar la comunicación modbusrtu. Este es el enfoque, el núcleo, la clave. La prueba anterior es solo para comprobar si el equipo es normal.

1. Crear un proyecto en vs2019, mi proyecto se llama DaLingFormApp

 2. Diseño de la interfaz de usuario

 Se utiliza la clase AlgorithmHelper

 Se utiliza la clase SerialPortHelper

 3. Código de evento del botón

 

 El código completo es:

using DaLingFormApp.Helper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DaLingFormApp
{
    public partial class Form1 : Form
    {
        //创建串口操作助手对象
        private SerialPortHelper serialPortHelper = new SerialPortHelper();
        //创建进制转换助手对象
        private AlgorithmHelper algorithmHelper = new AlgorithmHelper();
        public Form1()
        {
            InitializeComponent();
            //串口基本参数初始化
            this.cboBaudRrate.SelectedIndex = 5;   //波特率默认9600
            this.cboCheckBit.SelectedIndex = 0;      //校验位默认NONE
            this.cboDataBit.SelectedIndex = 2;         //数据位默认8
            this.cboStopBit.SelectedIndex = 0;         //停止位默认1

            //获取当前计算机的端口
            if (this.serialPortHelper.PortNames.Length == 0)
            {
                MessageBox.Show("当前计算机上没有找到可用的端口!", "警告信息");
                this.btnOperatePort.Enabled = false;//禁用打开端口按钮
            }
            else
            {
                //将端口添加到下拉框
                this.cboCOMList.Items.AddRange(this.serialPortHelper.PortNames);
                this.cboCOMList.SelectedIndex = 0;
            }

            //串口对象委托和串口接收数据事件关联
            this.serialPortHelper.SerialPortObject.DataReceived += new SerialDataReceivedEventHandler(this.SerialPort_DataReceived);
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                ReceiveData(this.serialPortHelper.ReceiveData());
            }
            catch (Exception ex)
            {
                MessageBox.Show("接收数据出现错误:" + ex.Message);
            }
        }

        /// <summary>
        /// 接收数据的具体实现过程
        /// </summary>
        /// <param name="byteData"></param>
        private void ReceiveData(byte[] byteData)
        {
            string data = string.Empty;
            if (this.ckb16Receive.Checked)//十六机制接收
            {
                data = algorithmHelper.BytesTo16(byteData, Enum16Hex.Blank);
                //在这里编写具体的数据处理过程。。。可以保存到数据库,或其他文件...
            }
            else
            {
                data = algorithmHelper.BytesToString(byteData, Enum16Hex.None);
            }

            //显示到当前文本框中
            //因为接收数据的事件是一个独立显存,所有必须通过跨线程访问可视化控件的方法来完成展示
            //Invoke()方法的第一个参数必须是返回值为void的委托,第二个参数是给委托对应方法传递的参数
            this.txtReceiver.Invoke(new Action<string>(
                s =>
                {
                    this.txtReceiver.Text += s + Environment.NewLine;
                }), data);
        }



        #region 串口参数设置

        //波特率的设置
        private void cboBaudRrate_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.serialPortHelper.SerialPortObject.BaudRate = Convert.ToInt32(this.cboBaudRrate.Text);
        }
        //设置奇偶校验
        private void cboCheckBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboCheckBit.Text == "EVEN")
            {
                serialPortHelper.SerialPortObject.Parity = System.IO.Ports.Parity.Even;
            }
            else if (cboCheckBit.Text == "NONE")
            {
                serialPortHelper.SerialPortObject.Parity = System.IO.Ports.Parity.None;
            }
            else if (cboCheckBit.Text == "0DD")
            {
                serialPortHelper.SerialPortObject.Parity = System.IO.Ports.Parity.Odd;
            }
        }
        //设置数据位
        private void cboDataBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.serialPortHelper.SerialPortObject.DataBits = Convert.ToInt32(cboDataBit.Text);
        }
        //设置停止位
        private void cboStopBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboStopBit.Text == "1")
            {
                serialPortHelper.SerialPortObject.StopBits = System.IO.Ports.StopBits.One;
            }
            else if (cboStopBit.Text == "2")
            {
                serialPortHelper.SerialPortObject.StopBits = System.IO.Ports.StopBits.Two;
            }
        }

        #endregion

        /// <summary>
        /// 打开端口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOperatePort_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.btnOperatePort.Text.Trim() == "打开端口")
                {
                    this.serialPortHelper.OpenSerialPort(this.cboCOMList.Text.Trim(), 1);
                    this.lblSerialPortStatus.Text = "端口已打开";
                    this.lblStatusShow.BackColor = Color.Green;
                    this.btnOperatePort.Text = "关闭端口";
                    this.btnOperatePort.Image = this.imageList.Images[0];
                }
                else
                {
                    this.serialPortHelper.OpenSerialPort(this.cboCOMList.Text.Trim(), 0);
                    this.lblSerialPortStatus.Text = "端口未打开";
                    this.lblStatusShow.BackColor = Color.Red;
                    this.btnOperatePort.Text = "打开端口";
                    this.btnOperatePort.Image = this.imageList.Images[1];
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("端口操作异常:" + ex.Message);
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {
            if (this.txtSender.Text.Trim().Length == 0)
            {
                MessageBox.Show("发送内容不能为空!", "提示信息");
            }
            else
            {
                string txt = this.txtSender.Text.Trim();
                if (txt.Length != 17)
                {
                    txt = txt.Replace(" ", "");
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < txt.Length; i = i + 2)
                    {
                        sb.Append(txt.Substring(i, 2));
                        sb.Append(" ");
                    }
                    txt = sb.ToString();//去掉尾部的空格 
                }
                string crctxt = algorithmHelper.Crc16(txt);
                string sendMsg = txt = txt + crctxt;
                SendData(sendMsg);  //开始发送
            }
        }

        /// <summary>
        /// 发送命令
        /// </summary>
        /// <param name="data"></param>
        private void SendData(string data)
        {
            try
            {
                if (this.ckb16Send.Checked)//发送十六进制数据
                {
                    this.serialPortHelper.SendData(data, SendFormat.Hex);
                }
                else  //发送字符串
                {
                    this.serialPortHelper.SendData(data, SendFormat.String);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("发送数据出现错误:" + ex.Message, "错误提示!");
            }
        }

        /// <summary>
        /// 清空数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            this.txtReceiver.Clear();
            this.txtSender.Clear();
        }
    }
}

Aquí, se utilizan el evento de recepción de datos del puerto serie DataReceived, delegación, conversión base, Invoke y otras tecnologías.

4. Ejecuta el programa

 

 

 

 El propósito de nuestro combate actual es dominar C# para desarrollar software industrial para la computadora superior. Aunque esta herramienta es simple, el núcleo es dominar la comunicación MODBUS RTU en la interfaz RS232, el grupo de combate de élite de la nación china.

Supongo que te gusta

Origin blog.csdn.net/hqwest/article/details/131002997
Recomendado
Clasificación