【问题标题】:Using serial port connection in multiple functions?在多种功能中使用串口连接?
【发布时间】:2016-02-04 16:00:33
【问题描述】:

我正在编写一个应用程序,该应用程序旨在从串行端口读取数据,然后将数据绘制在图表上并将其保存到日志文件中。到目前为止,我正在处理初始串行端口设置和打开/关闭。

有一个组合框可以选择要使用的串行端口,还有一个用于连接/断开连接的按钮。与串行端口断开连接是否重要,或者当应用程序关闭时 Windows 会自动执行此操作?

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace FieldProbe
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            var ports = SerialPort.GetPortNames();
            cmbSerialPorts.DataSource = ports;
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (btnConnect.Text == "Connect")
            {
                btnConnect.Text = "Disconnect";

                if (cmbSerialPorts.SelectedIndex > -1)
                {
                    MessageBox.Show(String.Format("You selected port '{0}'", cmbSerialPorts.SelectedItem));
                    Connect(cmbSerialPorts.SelectedItem.ToString());
                }
                else
                {
                    MessageBox.Show("Please select a port first");
                }
            }
            else
            {
                btnConnect.Text = "Connect";
                port.Close();
            }


        }

        private void Connect(string portName)
        {
            var port = new SerialPort(portName);
            if (!port.IsOpen)
            {
                port.BaudRate = 921600;
                port.DataBits = 8;
                port.StopBits = StopBits.One;
                port.Parity = Parity.None;
                port.Handshake = Handshake.None;
                port.Open();
            }
        }

    }
}

这是无耻地从几个例子中提取的,我不是专业的编码器。 “port.close”行不起作用,似乎我无法从“连接”以外的任何功能访问“端口”。从其他功能访问此端口的最佳解决方案是什么?

【问题讨论】:

  • 你需要了解变量作用域
  • 在您的按钮处理程序中,您将“活动端口”称为cmbSerialPorts.SelectedItem.ToString()(至少是端口名称)。那么为什么不做一个var port = new SerialPort(cmbSerialPorts.SelectedItem.ToString()); port.Close();呢?也可以考虑将Connect()中创建的port保存到数组中,或者在这个类中将port变成private SerialPort(即改变port的作用域)。
  • 关闭你的应用程序会自动关闭你的端口

标签: c# serial-port port


【解决方案1】:

我建议您阅读范围 - 但基本上您是在 Connect 方法中创建一个端口。此变量是此方法的本地变量,其他方法(例如 btnConnect_Click!)无法看到或访问它。我建议您将端口变量设为 MainForm 的类成员(将其声明在与您的方法 MainForm_Load 相同的级别) - 这样所有类方法都可以访问该变量:

public partial class MainForm : Form
{
    SerialPort _port;

    public MainForm()
    {
        InitializeComponent();
    }

    private void MainForm_Load(object sender, EventArgs e)
    {
        var ports = SerialPort.GetPortNames();
        cmbSerialPorts.DataSource = ports;
    }

    private void btnConnect_Click(object sender, EventArgs e)
    {
        if (btnConnect.Text == "Connect")
        {
            btnConnect.Text = "Disconnect";

            if (cmbSerialPorts.SelectedIndex > -1)
            {
                MessageBox.Show(String.Format("You selected port '{0}'", cmbSerialPorts.SelectedItem));
                Connect(cmbSerialPorts.SelectedItem.ToString());
            }
            else
            {
                MessageBox.Show("Please select a port first");
            }
        }
        else
        {
            btnConnect.Text = "Connect";
            _port.Close();
        }

    }

    private void Connect(string portName)
    {
        _port = new SerialPort(portName);
        if (!_port.IsOpen)
        {
            _port.BaudRate = 921600;
            _port.DataBits = 8;
            _port.StopBits = StopBits.One;
            _port.Parity = Parity.None;
            _port.Handshake = Handshake.None;
            _port.Open();
        }
    }
}

【讨论】:

    【解决方案2】:

    如果您的代码正确且有效,那么唯一要做的就是将变量端口从本地转换为函数到类的字段。这里有一个可能的解决方案:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO.Ports;
    
    namespace FieldProbe
    {
        public partial class MainForm : Form
        {
            private SerialPort port;
            public MainForm()
            {
                InitializeComponent();
            }
    
            private void MainForm_Load(object sender, EventArgs e)
            {
                var ports = SerialPort.GetPortNames();
                cmbSerialPorts.DataSource = ports;
            }
    
            private void btnConnect_Click(object sender, EventArgs e)
            {
                if (btnConnect.Text == "Connect")
                {
                    btnConnect.Text = "Disconnect";
    
                    if (cmbSerialPorts.SelectedIndex > -1)
                    {
                        MessageBox.Show(String.Format("You selected port '{0}'", cmbSerialPorts.SelectedItem));
                        Connect(cmbSerialPorts.SelectedItem.ToString());
                    }
                    else
                    {
                        MessageBox.Show("Please select a port first");
                    }
                }
                else
                {
                    btnConnect.Text = "Connect";
                    port.Close();
                }
    
    
            }
    
            private void Connect(string portName)
            {
                port = new SerialPort(portName);
                if (!port.IsOpen)
                {
                    port.BaudRate = 921600;
                    port.DataBits = 8;
                    port.StopBits = StopBits.One;
                    port.Parity = Parity.None;
                    port.Handshake = Handshake.None;
                    port.Open();
                }
            }
            private void OtherFunction()
            {
                if (port == null || !port.IsOpen)
                    return;
    
                // HERE DO WHATEVER YOU WANT WITH port
            }
        }
    }
    

    注意在类的开头,有字段声明,在末尾有一个使用该字段的虚拟函数。

    【讨论】:

    • private var port = new SerialPort(portName); 不会编译,因为 portName 是一个未声明的变量。同样var 在该范围内是不允许的,现在它不能推断类型! (var 只允许在函数本地范围内)
    • 是的,当我的手机响起然后我按下按钮时,我还在移动代码......我从不使用var......我只是展示了原理。
    • 我建议,作为我之前的答案,使用一些东西来区分字段和变量。作为其他用户,我总是在字段中使用前导取消标记。
    猜你喜欢
    • 2015-01-31
    • 2016-10-26
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 2021-06-19
    • 2015-05-03
    • 1970-01-01
    • 2021-01-29
    相关资源
    最近更新 更多