2009-07-22 41 views

答えて

12

私はこれを行う方法がいくつか見つかりました。以下の二つの文書は、手掛かりが最初の文書

から次の段落ではどのようなボーレートを決定する最も簡単な方法である出発点

ました特定のシリアルポートで使用できるかどうかは、GetCommProperties()アプリケーションプログラミングインターフェイス(API)を呼び出して、COMMPROP.dwSettableBau dビットマスクを使用して、そのシリアルポートでサポートされているボーレートを判別します。

1.0を使用する相互運用(P /呼び出し)を以下のように:C#でこれを行うには二つの選択肢が存在する。この段階で

は、次のデータ構造を定義が

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

は今のportNameは、COMのようなもので、次の呼び出し(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); 

を作ります? (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); 

なお、ポートの上記の方法の両方において(S)このデータを取得するには少なくとも1回は開く必要があります。


+0

CloseHandle(hFile) –

+0

@ HiteshPを呼び出すことでハンドルを終了する必要があると思います.Windows CEを使用している人は次の2つの変更を行います:(1) "文字列wcProvChar"を "char wcProvChar" COMMPROP構造体で、(2)両方のP/Invokesに "kernel32.dll"の代わりに "coredll.dll"を使用してください。 Jakubが指摘しているように、後でCOMポートへのファイルハンドルも閉じてください。 – AlainD

0

私はあなたができるとは思わない。

私は最近この問題を抱え、使用したいボーレートをハードコーディングしました。

MSDNは、単に「ボーレートはユーザーのシリアルドライバでサポートされている必要があります」と述べています。

+0

私も同じことを読んでいます。しかし、私はデバイスマネージャがこれらを表示するので、これを行う方法があると思われます。 – HiteshP

+0

これはハードコーディングされている可能性があります。 私はこのコンピュータに2つの異なるシリアルカードを持っていて、異なるチップセットとボーレートのリストは同じです。もちろん、まったく同じボーレートをサポートしている場合もあります。 このWin32構造体を見てください。、ハードコードされた値もあります。 – Bryan

+0

申し訳ありませんが、私はリンクを台無しにしました http://msdn.microsoft.com/en-us/library/aa363214(VS.85).aspx – Bryan

0
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から始まるのは、今世紀に製造されるシリアルポートの安全な下限のようです。