简体   繁体   English

C#中最快的串口通信?

[英]the fastest serial port communication possible in C#?

I am new at this forum and I do not have many experiences with programming in C#.我是这个论坛的新手,我在 C# 编程方面没有很多经验。 I have build simple Windows application in C# to communicate with some electronic board that my friend gave it to me.我用 C# 构建了简单的 Windows 应用程序,以与我朋友给我的一些电子板进行通信。 He has defined serial port baud rate in microcontroller at 38400. I want to send and receive bytes via serial port as fast as possible.他在微控制器中定义了串口波特率为38400。我想通过串口尽可能快地发送和接收字节。 With existing serialport tool in C# I was able only to read bytes but still not fast enough even with eventhandler in its own thread.使用 C# 中现有的串行端口工具,我只能读取字节,但即使在其自己的线程中使用 eventhandler 仍然不够快。 My buffer[4096] was full in few seconds.我的缓冲区 [4096] 在几秒钟内就满了。

My question is if there exist some other functions or tools for serial port communication that does not use so much processor time.我的问题是是否存在其他一些不占用太多处理器时间的串行端口通信功能或工具。 I need to read one byte in less than 200 us.我需要在不到 200 us 的时间内读取一个字节。 I have more experiences with embedded systems where this was not a problem.我在嵌入式系统方面有更多经验,这不是问题。

Thanks everyone for some advice or idea.谢谢大家的一些建议或想法。

Tomaž托马日

thanks for all replies.感谢所有回复。 I can read all bytes coming from board, but I can not reply fast enough.我可以读取来自电路板的所有字节,但我的回复速度不够快。 Here is my code.这是我的代码。 I have used an event for reading buffer.我使用了一个事件来读取缓冲区。 If I try to reply in event the next bytes contains wrong values.如果我尝试在下一个字节包含错误值时回复。

#region namespace usings
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;

using Microsoft.Win32;
using Zaber.Serial.Core;
using Diagnostics = System.Diagnostics;
#endregion

namespace Lucifire_aplication {命名空间 Lucifire_aplication {

public partial class Form1 : Form
{


    int k = 1;
    string number_of_bytes;
    byte checksum;
    byte[] buffer = new byte[11];
    byte[] buffer_old = new byte[11];


    public Form1()
    {
        InitializeComponent();
        configure_button.Enabled = false;
        start_button.Enabled = false;
        foreach (string s in SerialPort.GetPortNames())
        {
            serial_port_name.Items.Add(s);
        }
        serial_port_name.Text = "Select port";
        for (int i = 4800; i <= 38400; i = i * 2)
        {
            baud_rate.Items.Add(i);
        }
        for (int i = 57600; i <= 921600; i = i * 2)
        {
            baud_rate.Items.Add(i);
        }

        serial_port_name.DropDownStyle = ComboBoxStyle.DropDownList;
        baud_rate.SelectedIndex = 3;
        baud_rate.DropDownStyle = ComboBoxStyle.DropDownList;


    }

    private void serial_port_name_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (serial_port_name.Text != "Select port")
        {
            configure_button.Enabled = true;
        }
    }

    private void configure_button_Click(object sender, EventArgs e)
    {
        serialPort1.PortName = serial_port_name.Text;
        serialPort1.BaudRate = Int32.Parse(baud_rate.Text);
        serialPort1.DataBits = 8;
        serialPort1.StopBits = StopBits.One;
        //serialPort1.Handshake = Handshake.None;
        serialPort1.ReceivedBytesThreshold = 44;
        serialPort1.ReadBufferSize = 8192;
        MessageBox.Show("Communication is set on " + serialPort1.PortName + " with baud rate: " + serialPort1.BaudRate);
        start_button.Enabled = true;
    }

    private void start_button_Click(object sender, EventArgs e)
    {
        if (serialPort1.IsOpen)
        {

            serialPort1.Close();
            start_button.Text = "START";
            read_button.Enabled = false;
            //read_write.Enabled = false;
            comport_status.Text = "DISCONNECTED";
        }
        else
        {
            serialPort1.Open();
            start_button.Text = "STOP";
            read_button.Enabled = true;
            //read_write.Enabled = true;
            comport_status.Text = "CONNECTED";
        }
    }

    private void quitToolStripMenuItem_Click(object sender, EventArgs e)
    {
        System.Windows.Forms.Application.Exit();
    }

    private void read_button_Click(object sender, EventArgs e)
    {
        bytes_to_read.Text = serialPort1.BytesToRead.ToString();
        read_data.Text = serialPort1.ReadExisting().ToString();
        read_data.Text += k.ToString() + "   ";
        if (buffer_old[0] == 4)
        {
            serialPort1.ReadByte();
        }
        serialPort1.Read(buffer, 0, 11);
        for (int j = 0; j < 11; j++)
        {
            read_data.Text += buffer[j].ToString() + "  ";
        }
        read_data.Text += "\n";
        k++;
        buffer_old = buffer;
    }

    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {

        serialPort1 = (SerialPort)sender;
        number_of_bytes = serialPort1.BytesToRead.ToString();
        if (buffer_old[0] == 4)
        {
            serialPort1.ReadByte();
        }
        serialPort1.Read(buffer, 0, 11);
        buffer_old = buffer;
        this.Invoke(new EventHandler(displaytext));
        Thread.Sleep(20);
    }

    private void displaytext(object sender, EventArgs e)
    {
        checksum = 0;
        bytes_to_read.Text = number_of_bytes;
        read_data.Text += k.ToString() + "\t";
        for (int j = 0; j < 11; j++)
        {
            read_data.Text += buffer[j].ToString() + "  ";
            checksum += buffer[j]; 
        }
        checksum -= buffer[10];
        read_data.Text += "  \t" + checksum.ToString();
        read_data.Text += "\n";
        k++;
    }

}

} }

Please take a look at : If you must use .NET System.IO.Ports.SerialPort请看一看: 如果你必须使用.NET System.IO.Ports.SerialPort

Ben Voigt (the author) gives an excellent example on how to use the inherent BaseStream member of SerialPort which is more efficient for using the underlying Win32 API. Ben Voigt(作者)给出了一个很好的例子,说明如何使用SerialPort的固有BaseStream成员,它可以更有效地使用底层 Win32 API。

Port = new SerialPort("COM" + PORT_NUMBER.ToString()); 
...
private void ReadEvent()  
{      
    byte[] buffer = new byte[2000];  
    Action kickoffRead = null;  
    kickoffRead = (Action)(() => Port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate(IAsyncResult ar)  
    {  
        try  
        {  
            int count = Port.BaseStream.EndRead(ar);  
            byte[] dst = new byte[count];  
            Buffer.BlockCopy(buffer, 0, dst, 0, count);  
            RaiseAppSerialDataEvent(dst);  
        }  
        catch (Exception exception)  
        {  
            MessageBox.Show(ERROR == > " + exception.ToString());    
        }  
        kickoffRead();  
    }, null)); kickoffRead();  
}

Regards.问候。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM