我剛剛遇到串口問題,但到目前爲止找不到答案。請讓我知道或給我一些線索,如果我做錯了,謝謝。我會盡量詳細解釋整個情況,並最終提出我的問題。開始。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分不同的結果:
- 我的程序中的10066B70是什麼意思?
- 與10066B70執行AND操作時設備管理器的波特率值相比,有不同的結果。這是如何完成的?
- 設備管理器波特率值和FTDI文檔的不同結果。我不知道哪一個可以信任,因爲兩者都是正式的?
再次感謝您閱讀我剛剛寫的所有內容,我知道這段時間很長。希望有人能夠爲我提出一些問題的答案。
*注意:我沒有達到10個聲望,所以我不能發佈超過2個鏈接,因此我已將鏈接放入評論中。再次感謝您的理解。
鏈接1:如何以編程方式找到在C#中的HiteshP所有可用的波特率(SerialPort類)](http://stackoverflow.com/questions/1165692/how-to-programatically-find-all -available-in-c-sharp-serialport-class) – Bou
鏈接2:[COMMPROP結構](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363189(v = vs。 85).aspx) – Bou
@stuartd謝謝。 – Bou