0

每次我从串行端口获取两个字节并找到它们之间的差异时,我都在其中创建了一个 wpf,然后在 while 循环中我通过文本框显示差异:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

    }
    SerialPort port;
    private void StartButton_Click(object sender, RoutedEventArgs e)
    {
        port = new SerialPort("COM3");
        port.BaudRate = 9600;
        port.DtrEnable = true;
        port.RtsEnable = true;
        port.Handshake = Handshake.None;
        port.Open();
        try
        {
            if (!port.IsOpen)
                throw new Exception();
        }
        catch (Exception)
        {
            Console.Out.WriteLine("port is not open!!");
        }
        while (port.IsOpen)
        {
            var b1 = port.ReadByte();
            var b2 = port.ReadByte();
            double t1 = b1 * 1e-9;
            double t2 = b2 * 1e-9; ;
            var dift = t2 - t1;
            if (dift == 0)
            {
                this.SpeedTextBox.Text = "0";
                continue;
            }
            this.SpeedTextBox.Text = dift;
        }
    }

    private void StopButton_Click(object sender, RoutedEventArgs e)
    {
        if (port != null)
        {
            if (port.IsOpen) port.Close();
            port.Dispose();
        }
    }
}

但是当我执行它并单击 StartButton 时,表单将停止工作。我知道该程序接收数据(我用另一个简单的程序对其进行了测试)。但我不知道这里出了什么问题!!

谁能帮我?

提前致谢。

4

2 回答 2

2

ReadByte() 是一个阻塞方法,在接收到一个字节之前它不会返回。这就是 SerialPort 有 DataReceived 事件的原因。

首先使用另一个程序,如 Hyperterminal 或 Putty 来测试连接并消除简单的错误,如接线错误、选择错误的端口号或波特率以及奇偶校验、DataBits 和 StopBits 设置错误。你没有设置,所以你会得到框架错误的非零几率。您必须实现 ErrorReceived 事件,以确保不会发现此类错误并让您对它为什么不起作用感到困惑。

如果您不使用 DataReceived,那么使用 ReadTimeout 属性也很重要,以确保您的程序不会永远挂起,如果连接出现问题,没有任何方法可以诊断原因。准备好捕捉 TimeoutException。

SysInternals 的 PortMon 是一个非常有用的实用程序,可以用来比较好坏,它可以准确地显示串行端口驱动程序内部发生的情况。但请注意,它不适用于 64 位操作系统。

于 2013-07-28T13:16:46.337 回答
0

Hans 已经介绍了串行端口的情况,但您的程序会锁定的另一个原因是您的点击处理程序使用了无限等待循环。Windows 应用程序的工作方式是它们有一个从队列中获取消息(如点击事件)的主循环。对于每条消息,都会调用您的事件处理程序,并且只有当您的事件处理程序将控制权返回到主循环时,它才能处理下一条消息(例如,重绘窗口并显示您在控件上设置的新文本)。因此,如果您希望程序保持对用户输入的响应,则不能在事件处理程序中使用长循环或阻塞调用。

于 2013-07-28T13:58:58.847 回答