在startbutton_Click()函数中的while循环中接收串行端口数据

时间:2013-07-28 12:52:12

标签: c# serial-port

我每次从串口获取两个字节时都会从中创建一个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时,表单将停止工作。我知道程序接收数据(我用另一个简单程序测试它)。但我不知道这里出了什么问题!

任何人都可以帮助我吗?

提前感谢。

2 个答案:

答案 0 :(得分:2)

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

首先使用Hyperterminal或Putty等其他程序来测试连接并消除简单的错误,如接线错误,选择错误的端口号或波特率,以及错误地设置Parity,DataBits和StopBits。你没有设置,所以有非零赔率你会得到框架错误。您必须实现ErrorReceived事件以确保不会忽略这些类型的错误并让您神秘化为什么它不起作用。

如果您不使用DataReceived,那么使用ReadTimeout属性来确保您的程序不会永远挂起也是很重要的,如果连接出现问题,则无法诊断原因。准备好赶上TimeoutException。

SysInternals的PortMon是一个非常有用的实用工具,用于比较好与坏,它会准确显示串口驱动程序内部的内容。但要注意它在64位操作系统上不起作用。

答案 1 :(得分:0)

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