如何以编程方式查找 C# 中所有可用的波特率(serialPort 类)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1165692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:47:37  来源:igfitidea点击:

How to programmatically find all available Baudrates in C# (serialPort class)

c#serial-portbaud-rate

提问by HiteshP

Is there a way to find out all the available baud rates that a particular system supports via C#? This is available through Device Manager-->Ports but I want to list these programmatically.

有没有办法通过 C# 找出特定系统支持的所有可用波特率?这可通过设备管理器--> 端口获得,但我想以编程方式列出这些。

采纳答案by HiteshP

I have found a couple of ways to do this. The following two documents were a starting point

我找到了几种方法来做到这一点。以下两个文件是一个起点

The clue is in the following paragraph from the first document

线索在第一个文档的以下段落中

The simplest way to determine what baud rates are available on a particular serial port is to call the GetCommProperties() application programming interface (API) and examine the COMMPROP.dwSettableBaud bitmask to determine what baud rates are supported on that serial port.

确定特定串行端口上可用的波特率的最简单方法是调用 GetCommProperties() 应用程序编程接口 (API) 并检查 COMMPROP.dwSettableBaud 位掩码以确定该串行端口支持的波特率。

At this stage there are two choices to do this in C#:

在这个阶段,在 C# 中有两种选择:

1.0 Use interop (P/Invoke) as follows:

1.0 使用互操作(P/Invoke)如下:

Define the following data structure

定义如下数据结构

[StructLayout(LayoutKind.Sequential)]
struct COMMPROP
{
    short wPacketLength;
    short wPacketVersion;
    int dwServiceMask;
    int dwReserved1;
    int dwMaxTxQueue;
    int dwMaxRxQueue;
    int dwMaxBaud;
    int dwProvSubType;
    int dwProvCapabilities;
    int dwSettableParams;
    int dwSettableBaud;
    short wSettableData;
    short wSettableStopParity;
    int dwCurrentTxQueue;
    int dwCurrentRxQueue;
    int dwProvSpec1;
    int dwProvSpec2;
    string wcProvChar;
}

Then define the following signatures

然后定义如下签名

[DllImport("kernel32.dll")]
static extern bool GetCommProperties(IntPtr hFile, ref COMMPROP lpCommProp);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess,
           int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, 
           int dwFlagsAndAttributes, IntPtr hTemplateFile);

Now make the following calls (refer to http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx)

现在进行以下调用(请参阅http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

   COMMPROP _commProp = new COMMPROP();
   IntPtr hFile = CreateFile(@"\.\" + portName, 0, 0, IntPtr.Zero, 3, 0x80, IntPtr.Zero);
   GetCommProperties(hFile, ref commProp);

Where portNameis something like COM?? (COM1, COM2, etc). commProp.dwSettableBaudshould now contain the desired information.

其中portName类似于 COM?(COM1、COM2 等)。commProp.dwSettableBaud现在应该包含所需的信息。

2.0 Use C# reflection

2.0 使用 C# 反射

Reflection can be used to access the SerialPort BaseStream and thence the required data as follows:

反射可用于访问 SerialPort BaseStream,然后访问所需的数据,如下所示:

   _port = new SerialPort(portName);
   _port.Open();
   object p = _port.BaseStream.GetType().GetField("commProp", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_port.BaseStream);
   Int32 bv = (Int32)p.GetType().GetField("dwSettableBaud", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(p);

Note that in both the methods above the port(s) has to be opened at least once to get this data.

请注意,在上述两种方法中,必须至少打开一次端口才能​​获取此数据。



回答by Bryan

I don't think you can.

我不认为你可以。

I recently had this problem, and ended up hard coding the baud rates I wanted to use.

我最近遇到了这个问题,最终对我想要使用的波特率进行了硬编码。

MSDN simply states, "The baud rate must be supported by the user's serial driver".

MSDN 只是声明,“用户的串行驱动程序必须支持波特率”。

回答by Max Euwe

dwSettableBaud  gives 268894207 int (0x1006ffff)
while dwMaxBaud gives 268435456 int (0x10000000)

Obviously, this doesn't help me. So this is what I am currently relying upon:

显然,这对我没有帮助。所以这就是我目前所依赖的:

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;


  public static readonly List<string> SupportedBaudRates = new List<string>
{
    "300",
    "600",
    "1200",
    "2400",
    "4800",
    "9600",
    "19200",
    "38400",
    "57600",
    "115200",
    "230400",
    "460800",
    "921600"
};

    public static int MaxBaudRate(string portName)
    {
        var maxBaudRate = 0;
        try
        {
            //SupportedBaudRates has the commonly used baudRate rates in it
            //flavor to taste
            foreach (var baudRate in ConstantsType.SupportedBaudRates)
            {
                var intBaud = Convert.ToInt32(baudRate);
                using (var port = new SerialPort(portName))
                {
                    port.BaudRate = intBaud;
                    port.Open();
                }
                maxBaudRate = intBaud;
            }
        }
        catch
        {
            //ignored - traps exception generated by
            //baudRate rate not supported
        }

        return maxBaudRate;
    }

The baud rates are in strings because they are destined for a combo box.

波特率在字符串中,因为它们用于组合框。

    private void CommPorts_SelectedIndexChanged(object sender, EventArgs e)
    {
        var combo = sender as ComboBox;
        if (combo != null)
        {
            var port = combo.Items[combo.SelectedIndex].ToString();
            var maxBaud = AsyncSerialPortType.MaxBaudRate(port);
            var baudRates = ConstantsType.SupportedBaudRates;
            var f = (SerialPortOpenFormType)(combo.Parent);
            f.Baud.Items.Clear();
            f.Baud.Items.AddRange(baudRates.Where(baud => Convert.ToInt32(baud) <= maxBaud).ToArray());
        }
    }

You can improve on performance if you know the minimum baud rate supported by all of the serial ports you plan to open. For instance, starting with 115,200 seems like a safe lower limit for serial ports manufactured in this century.

如果您知道计划打开的所有串行端口支持的最低波特率,则可以提高性能。例如,从 115,200 开始似乎是本世纪制造的串行端口的安全下限。