簡體   English   中英

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

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

有沒有辦法找出特定系統通過C#支持的所有可用波特率? 這可以通過設備管理器 - >端口獲得,但我想以編程方式列出這些。

我找到了幾種方法來做到這一點。 以下兩個文件是一個起點

線索在第一份文件的以下段落中

確定特定串行端口上可用波特率的最簡單方法是調用GetCommProperties()應用程序編程接口(API)並檢查COMMPROP.dwSettableBaud位掩碼以確定該串行端口支持的波特率。

在這個階段,在C#中有兩種選擇:

1.0使用interop(P / Invoke)如下:

定義以下數據結構

[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;
}

然后定義以下簽名

[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);

現在進行以下調用(參考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);

哪里的portName就像COM? (COM1,COM2等)。 commProp.dwSettableBaud現在應該包含所需的信息。

2.0使用C#反射

反射可用於訪問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);

請注意,在上述兩種方法中,必須至少打開一次端口才能​​獲取此數據。


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

顯然,這對我沒有幫助。 所以這就是我目前所依賴的:

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;
    }

波特率是字符串,因為它們的目的地是組合框。

    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());
        }
    }

如果您知道計划打開的所有串行端口支持的最小波特率,則可以提高性能。 例如,從115,200開始,似乎是本世紀制造的串行端口的安全下限。

我認為你不能。

我最近遇到了這個問題,最終硬編碼了我想要使用的波特率。

MSDN簡單地說,“波特率必須由用戶的串行驅動程序支持”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM