我刚刚遇到串口问题,但到目前为止找不到答案。请让我知道或给我一些线索,如果我做错了,谢谢。我会尽量详细解释整个情况,并最终提出我的问题。开始。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