- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我刚刚遇到了串行端口的问题,但到目前为止还没有找到答案。如果我做错了,请让我知道或给我一些线索,谢谢。我会尽量详细地解释整个情况,并在最后提出我的问题。开始。
我购买了一个使用 FTDI FT232RL 芯片的 USB 转 TTL 转换器,并对串行网络如何工作以及如何用 C# 编写自己的程序而不是使用 super 终端感到好奇。我通过阅读一些教程开始编写程序,让自己快速入门。通过教程后,我注意到我读过的所有教程在波特率设置方面都使用了类似的方法。他们将典型的波特率硬编码到他们的代码中,而不是询问设备是否支持。我总是尝试编写尽可能通用的程序,因此,我开始研究如何从设备中检索信息。经过搜索,我找到了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 .
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 的文档
[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
同样,它与设备管理器显示的不同。让我想知道设备管理器中的波特率是否也是硬编码的。
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
相反,在 ftdiport.inf 文件中找不到 [82,46,01,00]。我还从 COMMPROP 执行了 dwMaxBaud 并得到了结果 10000000,它指的是:
BAUD_USER (0x10000000): Programmable baud rate.
所以这意味着用户可以使用他们喜欢的任何波特率,只要它满足发送器和接收器的波特率并且在误差范围内,对吗? (只是确保我没有弄错,因为我的大脑开始变得有点模糊)
最佳答案
Fernhill 开发的软件可以自动快速地尝试大量串行端口设置组合,以查看哪些会产生某种有意义的响应。
Modbus Serial Autodetect Wizard
关于C#:如何确定串口设备的可设置波特率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38243197/
在 setup() 中,我有 Serial.begin(9600),但是当我让串行监视器打印任何内容时,没有显示任何文本。我曾尝试移动 print() 函数的位置(包括直接在 Serial.begin
我正在使用以下代码片段每秒通过 com 端口发送一次 gps 数据: serialPort = new SerialPort("COM4", 4800, Parity.None, 8, StopBit
我们有一个电机 Controller ,它实现了USB->虚拟COM端口,其波特率固定为921600(手册甚至指出波特率无法更改)。我发现如果我使用像 Terminal 这样的终端程序,我可以通过自定
我一直在寻找 Beaglebone Black (BB) 支持的 UART 波特率。我在 BB 系统引用手册或 sitara 处理器本身的数据表中找不到它。我正在使用 pyserial 和 Adafr
我正在尝试编写一个使用 IrDA 与 Uwatec 潜水电脑通信的工具……在 Mac 上。我正在使用的 USB IrDA 设备提供了一个串行设备(/dev/cu.IrDA-IrCOMM0 和 /dev
我是一名优秀的程序员,十分优秀!