2016-07-07 204 views
6

我剛剛遇到串口問題,但到目前爲止找不到答案。請讓我知道或給我一些線索,如果我做錯了,謝謝。我會盡量詳細解釋整個情況,並最終提出我的問題。開始。C#:如何確定串口設備可設置的波特率?

我用FTDI FT232RL芯片買了一個USB轉TTL轉換器,並且很好奇串行網絡如何工作,以及如何用C#編寫我自己的程序,而不是使用超級終端。我開始通過閱讀一些教程來開始編寫程序,以便讓自己快速入門。閱讀完教程後,我發現所有關於波特率設置的教程都使用了類似的方法。他們將典型的波特率硬編碼到他們的代碼中,而不是詢問設備是否支持該功能。我總是儘量編寫程序儘可能通用,因此,我開始研究如何從設備中獲取信息。搜索後,我發現this post answered by HiteshP非常有用,並且繼續使用該帖子中建議的反射方法。因此,這裏是我的代碼看起來像:

private void UpdateBaudRateCollection() 
{ 
    mySerialPort.PortName = cboAllPortNames.SelectedItem.ToString(); 
    mySerialPort.Open(); 
    object p = mySerialPort.BaseStream.GetType().GetField("commProp", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(mySerialPort.BaseStream); 
    int dwSettableBaud = (int)p.GetType().GetField("dwSettableBaud", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(p); 
    mySerialPort.Close(); 
    MessageBox.Show(dwSettableBaud.ToString("X")); 
} 

結果,我從MessageBox中得到的是10066B70,我不知道它代表什麼,因爲它是not shown in Microsoft's COMMPROP structure

我做了更多的搜索,試圖找出10066B70的含義,但找不到任何答案,直到我遇到了AmundGjersøe的Basic serial port listening application。也許我必須用10066B70和微軟的COMMPROP結構給出的所有值執行AND操作。所以我把價值投入了這個函數。

private void SettableBaudRateOfDevice(int settableBaudRate) 
{ 
    const int BAUD_075 = 0x00000001; 
    const int BAUD_110 = 0x00000002; 
    const int BAUD_150 = 0x00000008; 
    const int BAUD_300 = 0x00000010; 
    const int BAUD_600 = 0x00000020; 
    const int BAUD_1200 = 0x00000040; 
    const int BAUD_1800 = 0x00000080; 
    const int BAUD_2400 = 0x00000100; 
    const int BAUD_4800 = 0x00000200; 
    const int BAUD_7200 = 0x00000400; 
    const int BAUD_9600 = 0x00000800; 
    const int BAUD_14400 = 0x00001000; 
    const int BAUD_19200 = 0x00002000; 
    const int BAUD_38400 = 0x00004000; 
    const int BAUD_56K = 0x00008000; 
    const int BAUD_57600 = 0x00040000; 
    const int BAUD_115200 = 0x00020000; 
    const int BAUD_128K = 0x00010000; 
    const int BAUD_USER = 0x10000000; 

    cboBaudRate.Items.Clear(); 

    if ((settableBaudRate & BAUD_075) > 0) 
     cboBaudRate.Items.Add(75); 
    if ((settableBaudRate & BAUD_110) > 0) 
     cboBaudRate.Items.Add(110); 
    if ((settableBaudRate & BAUD_150) > 0) 
     cboBaudRate.Items.Add(150); 
    if ((settableBaudRate & BAUD_300) > 0) 
     cboBaudRate.Items.Add(300); 
    if ((settableBaudRate & BAUD_600) > 0) 
     cboBaudRate.Items.Add(600); 
    if ((settableBaudRate & BAUD_1200) > 0) 
     cboBaudRate.Items.Add(1200); 
    if ((settableBaudRate & BAUD_1800) > 0) 
     cboBaudRate.Items.Add(1800); 
    if ((settableBaudRate & BAUD_2400) > 0) 
     cboBaudRate.Items.Add(2400); 
    if ((settableBaudRate & BAUD_4800) > 0) 
     cboBaudRate.Items.Add(4800); 
    if ((settableBaudRate & BAUD_7200) > 0) 
     cboBaudRate.Items.Add(7200); 
    if ((settableBaudRate & BAUD_9600) > 0) 
     cboBaudRate.Items.Add(9600); 
    if ((settableBaudRate & BAUD_14400) > 0) 
     cboBaudRate.Items.Add(14400); 
    if ((settableBaudRate & BAUD_19200) > 0) 
     cboBaudRate.Items.Add(19200); 
    if ((settableBaudRate & BAUD_38400) > 0) 
     cboBaudRate.Items.Add(38400); 
    if ((settableBaudRate & BAUD_56K) > 0) 
     cboBaudRate.Items.Add(56000); 
    if ((settableBaudRate & BAUD_57600) > 0) 
     cboBaudRate.Items.Add(57600); 
    if ((settableBaudRate & BAUD_115200) > 0) 
     cboBaudRate.Items.Add(115200); 
    if ((settableBaudRate & BAUD_128K) > 0) 
     cboBaudRate.Items.Add(128000); 
    if ((settableBaudRate & BAUD_USER) > 0) 
     cboBaudRate.Items.Add(3000000); 
} 

運行程序後,我得到以下波特率:

300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 3000000 

很高興,它的工作,直到我在該設備的Windows的設備管理器中顯示的值進行了比較。從設備管理器的波特率爲:

300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600 

我可以理解,波特率:3000000沒有顯示,因爲我定義自己,但哪兒來的其餘值從何而來?我開始想知道它可能是在驅動程序中定義的。我開始深入挖掘並發現FTDI的文檔 AN232B-05 Configuring FT232R, FT2232 and FT232B Baud Rates。在文檔中,它提到了FTDI的驅動程序配置文件(ftdiport.inf)。我搜索了它,並在Windows系統文件夾下找到它。入口看起來是這樣的:

[FtdiPort.NT.HW.AddReg] 
HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00 

它看起來與FTDI的文檔部分2.3所示的一樣,混疊使用附加FT232B子整數除數。繼2.3節的指令,並從ftdiport.inf翻譯ConfigData,我得到以下波特率:

300, 600, 1200, 2400, 4800, 9600, 19230, 38461, 57692, 115384, 230769, 461538, 923076, 14406 

再次,這是不一樣的是什麼設備管理器中顯示。讓我懷疑設備管理器中的波特率是否也是硬編碼的。

我也試過怎麼計算波特率:從設備管理器1800可能看起來像在ftdiport.inf文件:

Required divisor = 3000000/1800 = 1666.666 
Divisor = 1666 
Sub-integer divisors = 0.6666 
Closest Sub-integer divisors = 0.625 
Closest achievable baud rate = 3000000/1666.625 = 1800.045 
Error = (1800.045-1800)/1800*100 = 0.0025% 

錯誤是非常錯誤的允許+/- 3%的保證金之內聲明在文檔中,所以在ftdiport中輸入數據。INF應該有一些看起來像這樣:

1666.625 Dec = 00014682 Hex 
Data entry after re-order: 00014682 Hex => 82,46,01,00 

相反,[82,46,01,00]是無處ftdiport.inf文件被發現。我也是從COMMPROP進行dwMaxBaud並得到它指的是結果10000000:

BAUD_USER (0x10000000): Programmable baud rate. 

因此,這意味着用戶可以使用,只要他們喜歡的任何波特率,因爲它滿足了發射器和接收器的波特率,並在誤差範圍內,對嗎? (只是確保我沒有得到它錯了,因爲我的大腦開始變得有點模糊)

所以現在,我很困惑,我在我的腦中3分不同的結果:

  1. 我的程序中的10066B70是什麼意思?
  2. 與10066B70執行AND操作時設備管理器的波特率值相比,有不同的結果。這是如何完成的?
  3. 設備管理器波特率值和FTDI文檔的不同結果。我不知道哪一個可以信任,因爲兩者都是正式的?

再次感謝您閱讀我剛剛寫的所有內容,我知道這段時間很長。希望有人能夠爲我提出一些問題的答案。

*注意:我沒有達到10個聲望,所以我不能發佈超過2個鏈接,因此我已將鏈接放入評論中。再次感謝您的理解。

+0

鏈接1:如何以編程方式找到在C#中的HiteshP所有可用的波特率(SerialPort類)](http://stackoverflow.com/questions/1165692/how-to-programatically-find-all -available-in-c-sharp-serialport-class) – Bou

+0

鏈接2:[COMMPROP結構](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363189(v = vs。 85).aspx) – Bou

+0

@stuartd謝謝。 – Bou

回答