C#:如何确定串口设备的可设置波特率?

Bou*_*Bou 6 c# serial-port winforms

我刚刚遇到串口问题,但到目前为止找不到答案.如果我做错了,请告诉我或给我一些线索,谢谢.我将尽可能详细地解释整个情况并最终提出我的问题.开始.

我使用FTDI FT232RL芯片购买了一个USB转TTL转换器,并对串行网络如何工作以及如何用C#编写自己的程序而不是使用超级终端感到好奇.我开始编写程序,阅读一些教程,让自己快速入门.在完成教程之后,我注意到我所阅读的所有教程在波特率设置方面都使用了类似的方法.他们将典型的波特率硬编码到代码中,而不是询问设备是否支持它.我总是尽量把程序写成通用的,因此,我开始研究如何从设备中获取检索信息.搜索之后,我发现这篇由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"));
}
Run Code Online (Sandbox Code Playgroud)

我从MessageBox得到的结果是10066B70,我不知道它代表什么,因为它没有在Microsoft的COMMPROP结构中显示.

在我遇到AmundGjersøe的Basic串口监听应用程序之前,我做了更多的搜索,试图找出10066B70的含义,但找不到任何答案.也许我必须使用10066B70执行AND操作以及Microsoft的COMMPROP结构给出的所有值.所以我将值扔进了函数中.

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);
}
Run Code Online (Sandbox Code Playgroud)

运行程序后,我得到以下波特率:

300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 3000000
Run Code Online (Sandbox Code Playgroud)

很高兴它有效,直到我将它与Windows的设备管理器中显示的值进行比较.设备管理器的波特率为:

300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600
Run Code Online (Sandbox Code Playgroud)

我可以理解波特率:3000000没有显示,因为我自己定义了它,但其余值是从哪里来的?我开始想知道它可能是在驱动程序中定义的.我开始深入挖掘并找到了FTDI的文档 AN232B-05配置FT232R,FT2232和FT232B波特率.在文档中,它说明了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
Run Code Online (Sandbox Code Playgroud)

它看起来与FTDI文档第2.3节"使用附加FT232B子整数除数进行别名"中显示的相同.按照2.3节中的说明并从ftdiport.inf转换ConfigData,我得到以下波特率:

300, 600, 1200, 2400, 4800, 9600, 19230, 38461, 57692, 115384, 230769, 461538, 923076, 14406
Run Code Online (Sandbox Code Playgroud)

同样,它与设备管理器显示的内容不同.让我想知道设备管理器中的波特率是否也是硬编码的.

我还试过计算一​​下ftdiport.inf文件中设备管理器的波特率:1800的样子:

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%
Run Code Online (Sandbox Code Playgroud)

如文档中所述,错误在允许的+/- 3%误差范围内,因此ftdiport.inf中的数据条目应该具有如下所示的内容:

1666.625 Dec = 00014682 Hex
Data entry after re-order: 00014682 Hex => 82,46,01,00
Run Code Online (Sandbox Code Playgroud)

相反,[82,46,01,00]无法在ftdiport.inf文件中找到.我还从COMMPROP执行了dwMaxBaud并得到了结果10000000,它指的是:

BAUD_USER (0x10000000): Programmable baud rate.
Run Code Online (Sandbox Code Playgroud)

所以这意味着用户可以使用他们喜欢的任何波特率,只要它满足发送器和接收器的波特率并且在误差范围内,对吧?(只是确保我没有弄错,因为我的大脑开始变得有点模糊)

所以到现在为止,我很困惑,因为我脑中有三种不同的结果:

  1. 我的程序中的10066B70是什么意思?
  2. 与10066B70执行AND运算的设备管理器的波特率值相比,结果不同.这是怎么做的?
  3. 设备管理器的波特率值和FTDI文档的结果不同.我不知道哪一个值得信任,因为两者都是正式的?

再次感谢您阅读我刚写的所有内容,我知道它很长.希望有人能够为我提供一些问题的答案.

*注意:我没有达到10个声誉,因此我不能发布超过2个链接,因此我将链接放在评论中.再次感谢您的理解.

ski*_*les 1

Fernhill 开发的软件可以自动快速地尝试大量串行端口设置组合,以查看哪些组合会产生某种有意义的响应。

Modbus 串行自动检测向导