2016-07-07 385 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

回答