自动端口读取 [英] Automatic Port Reading

查看:67
本文介绍了自动端口读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,我有一个问题.我正在做一个非常普通的应用程序,其中我需要从硬件设备串行接收数据.该设备由我使用非常基本的AT89C51制成.我正在用C#设计软件.我想要的是,每当我通过串行端口将数据发送到PC时,数据都直接显示在屏幕上.到目前为止,我的策略是使用Application.Idle事件.我做了这样的事情.

Hello, I have a question. I am making a very general application wherein I need to receive data from a hardware device serially. The device is made by me using very basic AT89C51. I am designing the software in C#. What I want is that whenever I send data to my PC through serial port, it is displayed directly on the screen. My strategy up till now is to use Application.Idle event. I have made something like this.

private void btnStart_Click(object sender, EventArgs e)
{
    int Number;
    bool isValid;
    isValid = Int32.TryParse(txtBaudRate.Text, out Number);
    if(!isValid)
    {
        MessageBox.Show("Use only Integer for Baud Rate", "Error", MessageBoxButtons.Ok, MessageBoxIcon.Error);
    }
    else
    {
        try
        {
            sp = new SerialPort(txtPort.Text,Number);
            sp.Open();
            buffer_write = new byte[1];
            buffer_read = new byte[1];
            Application.Idle += Application_Idle;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.Ok, MessageBoxIcon.Error);
        }
    }
}



现在,我无法弄清楚如何编写Application_Idle方法,因此当我在应用程序中按键盘上的某个键时,该按键字符会串行发送到端口,并且每当我通过设备串行发送一些数据时,它就会被回显屏幕上的标签.

请对此提供帮助.



Now I am unable to figure out how to write the Application_Idle method, so that When I hit a key on keyboard while in application, That keypress character is sent serially to port and whenever I send some data serially through my device, it gets echoed on the screen on a label.

Please Help me regarding this.

推荐答案

我不认为Application.Idle应该像这样使用.如果我没弄错,则需要在串行端口上使用侦听器.
这可以帮助您:基本串行端口侦听应用程序 [ ^ ]
I don''t think that Application.Idle is meant to be used like this. If I got it correctly, you want a listener on the serial port.
This could help you out: Basic serial port listening application[^]


我自己解决了.
我添加了背景工作者.
当您单击开始"按钮初始化串行端口时,后台工作程序将启动另一个线程,在该线程中它将检查存储在读取缓冲区中的值,如果此处存储的值发生更改,它将在TextBox上显示该值.的我的程序",我正在将其发布给他人...以便对他们有帮助.

I have solved it myself.
I added a Background Worker.
When you will initialize the Serial Port on Clicking the Start Button, the background worker will start another thread where it will check the value stored in read buffer, if value stored here changes, it will display that value on the TextBox ... Here''s My Program, I am posting it for others... so that it may help them.

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 Serial_Communication
{
    public partial class frmMain : Form
    {
        SerialPort sp;
        byte[] buffer_write,buffer_read;
        bool set = false;
        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            txtPort.MaxLength = 5;
            txtBaudRate.MaxLength = 5;
            txtPort.Text = "COM1";
            txtBaudRate.Text = "9600";
            this.FormClosing += new FormClosingEventHandler(frmMain_FormClosing);
        }

        void consoleBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            buffer_write = BitConverter.GetBytes(e.KeyChar);
            sp.Write(buffer_write, 0, 1);
        }

        void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            MessageBox.Show("Exiting Application");
            try
            {
                backgroundWorker.CancelAsync();
                sp.Close();
            }
            catch (Exception)
            {
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                backgroundWorker.CancelAsync();
                sp.Close();
            }
            catch (Exception)
            {
            }
            Application.Exit();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            int Number;
            bool isValid;
            isValid = Int32.TryParse(txtBaudRate.Text, out Number);
            if (!isValid)
            {
                MessageBox.Show("Use only Integer for Baud Rate", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (!set)
            {
                try
                {
                    sp = new SerialPort(txtPort.Text, Number);
                    sp.Open();
                    buffer_write = new byte[2];
                    buffer_read = new byte[2];
                    set = true;
                    backgroundWorker.RunWorkerAsync(sp);
                    btnStart.Text = "Stop";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                backgroundWorker.CancelAsync();
                sp.Close();
                btnStart.Text = "Start";
            }
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            SerialPort sm = e.Argument as SerialPort;

            while (set)
            {
                if (backgroundWorker.CancellationPending == true)
                {
                    sm.Close();
                    e.Cancel = true;
                    break;
                }
                else
                {
                    try
                    {
                        sm.Read(buffer_read, 0, 1);
                        if (buffer_read[0].ToString() != "")
                        {
                            e.Result = sm;
                            backgroundWorker.ReportProgress(1);
                        }
                    }
                    catch (Exception) { }
                }
            }
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.consoleBox.Text += BitConverter.ToChar(buffer_read,0).ToString();
            buffer_read[0] = 0x00;
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                backgroundWorker.Dispose();
                backgroundWorker = null;
                GC.Collect();
            }
        }
    }
}



这是我创建的完整程序.现在我也想在这里问一个问题,我已经设置了许多异常处理程序.现在我在安全地部署后台工作程序时遇到了一个问题,因此,我在这里添加了异常处理程序.但我对此表示严重怀疑,为什么在解雇后台工作人员时会发生这些未处理的异常.请对此提供帮助.



This is complete Program created by me. Now I also want to ask a question here, I have setup many exception handlers. Now I am facing a problem while disposing the background worker safely, So, I have added exception handler here. But I doubt it seriously, why these unhandled exceptions are occurring while disposing off the background worker. Please help me regarding this.


这篇关于自动端口读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆