2016-07-07 13 views
6

Tôi vừa gặp sự cố với cổng nối tiếp nhưng cho đến nay vẫn không thể tìm thấy câu trả lời cho nó. Xin vui lòng cho tôi biết hoặc cho tôi một số manh mối nếu tôi làm sai, Cảm ơn. Tôi sẽ cố gắng giải thích toàn bộ tình huống càng chi tiết càng tốt và đặt câu hỏi của tôi cuối cùng. Đây rồi.C#: Làm cách nào để xác định tốc độ truyền có thể cài đặt cho thiết bị cổng nối tiếp?

Tôi mua bộ chuyển đổi USB sang TTL sử dụng chip FTDI FT232RL và tò mò về cách mạng nối tiếp hoạt động và cách tôi có thể viết chương trình của riêng mình trong C# thay vì sử dụng siêu thiết bị đầu cuối. Tôi bắt đầu viết chương trình bằng cách đọc một số hướng dẫn để bắt đầu một cách nhanh chóng. Sau khi đi qua hướng dẫn, tôi đã nhận thấy rằng tất cả các hướng dẫn tôi đã đọc về sử dụng các phương pháp tương tự khi nói đến cài đặt tốc độ truyền. Họ cứng mã tỷ lệ baud điển hình vào mã của họ thay vì hỏi nếu thiết bị sẽ hỗ trợ đó. Tôi luôn cố gắng viết chương trình càng chung càng tốt, vì điều này, tôi bắt đầu tìm hiểu cách tôi có thể lấy thông tin từ thiết bị. Sau khi tìm kiếm, tôi đã tìm thấy this post answered by HiteshP rất hữu ích và đã tiếp tục sử dụng phương pháp phản chiếu được đề xuất trong bài đăng. Vì vậy, đây là những gì mã của tôi trông giống như:

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")); 
} 

Kết quả mà tôi nhận được từ các MessageBox là 10066B70 mà tôi không có ý tưởng những gì nó đại diện vì nó là not shown in Microsoft's COMMPROP structure.

Tôi đã tìm kiếm nhiều hơn để tìm ra ý nghĩa của 10066B70 nhưng không thể tìm thấy câu trả lời cho đến khi tôi xem qua số Basic serial port listening application bởi Amund Gjersøe. Có lẽ tôi đã phải thực hiện và hoạt động với 10066B70 và tất cả các giá trị được đưa ra bởi cấu trúc COMMPROP của Microsoft. Vì vậy, tôi đã ném giá trị vào hàm.

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); 
} 

Sau khi chạy chương trình, tôi nhận được mức độ truyền sau đây:

300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 3000000 

Là hạnh phúc mà nó đã làm việc cho đến khi tôi so sánh nó với các giá trị thể hiện trong Device Manager của Windows cho các thiết bị. Tốc độ truyền từ Trình quản lý thiết bị là:

300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600 

Tôi có thể hiểu rằng tốc độ truyền: 3000000 không được hiển thị vì tôi tự xác định nhưng phần còn lại của giá trị đến từ đâu? Tôi bắt đầu tự hỏi có lẽ nó đã được định nghĩa trong tài xế. Tôi bắt đầu đào sâu hơn và tìm thấy tài liệu của FTDI AN232B-05 Configuring FT232R, FT2232 and FT232B Baud Rates. Bên trong tài liệu, nó nói về tập tin cấu hình trình điều khiển của FTDI (ftdiport.inf). Tôi tìm kiếm nó và tìm thấy nó dưới thư mục hệ thống cửa sổ. Mục trông như thế này:

[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 

Nó trông giống với một hiển thị trong phần tài liệu FTDI của 2.3, Aliasing Sử dụng FT232B bổ sung Sub-Integer ước. Thực hiện chỉ đạo tại mục 2.3 và dịch ConfigData từ ftdiport.inf, tôi nhận được mức độ truyền sau đây:

300, 600, 1200, 2400, 4800, 9600, 19230, 38461, 57692, 115384, 230769, 461538, 923076, 14406 

Một lần nữa, nó không phải là giống như những gì người quản lý thiết bị được hiển thị. Làm tôi băn khoăn liệu tốc độ truyền trong trình quản lý thiết bị cũng được mã hóa cứng hay không.

Tôi cũng đã cố gắng đếm tốc độ như thế nào baud: 1800 từ người quản lý thiết bị có thể trông giống như trong file 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% 

Lỗi cũng là trong phép +/- 3% lợi nhuận của lỗi như đã nêu trong tài liệu, vì vậy nhập dữ liệu trong ftdiport.inf nên có một cái gì đó trông như thế này:

1666.625 Dec = 00014682 Hex 
Data entry after re-order: 00014682 Hex => 82,46,01,00 

Thay vào đó, [82,46,01,00] không có trong tệp ftdiport.inf. Tôi cũng thực hiện dwMaxBaud từ COMMPROP và nhận được kết quả 10000000 trong đó đề cập đến:

BAUD_USER (0x10000000): Programmable baud rate. 

Vì vậy, điều này có nghĩa rằng người dùng có thể sử dụng bất kỳ tốc độ truyền họ thích miễn là nó đáp ứng tốc độ truyền của cả hai bộ truyền và bộ tiếp nhận và là trong phạm vi sai sót, phải không? (Chỉ cần đảm bảo tôi không nhận được nó sai như bộ não của tôi đang bắt đầu để có được một chút mờ)

Vì vậy, bây giờ, tôi rất bối rối như tôi có 3 kết quả khác nhau trong não của tôi:

  1. 10066B70 từ chương trình của tôi có nghĩa là gì?
  2. Kết quả khác so với giá trị tốc độ truyền của trình quản lý thiết bị với 10066B70 hoạt động VÀ hoạt động. Đây có phải là cách nó được thực hiện?
  3. Kết quả khác nhau từ giá trị tốc độ truyền của trình quản lý thiết bị và tài liệu từ FTDI. Tôi không biết ai tin tưởng cả hai đều chính thức?

Cảm ơn bạn đã đọc mọi thứ mà tôi vừa viết, tôi biết nó khá dài. Hy vọng rằng ai đó sẽ có thể cung cấp cho tôi một số câu trả lời cho câu hỏi của tôi.

* Lưu ý: Tôi chưa đạt đến 10 danh tiếng nên tôi không thể đăng hơn 2 liên kết, do đó tôi đã đặt liên kết trong nhận xét. Cảm ơn một lần nữa cho sự hiểu biết của bạn.

+0

Link 1: [Làm thế nào để programatically tìm thấy tất cả Baudrates sẵn trong C# (lớp SerialPort) bởi HiteshP] (http://stackoverflow.com/questions/1165692/how-to-programatically-find-all có sẵn-baudrates-in-c-sharp-serialport-class) – Bou

+0

Liên kết 2: [cấu trúc COMMPROP] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363189 (v = vs. 85) .aspx) – Bou

+0

@stuartd Cảm ơn. – Bou

Trả lời

1

Fernhill làm cho phần mềm có thể tự động và nhanh chóng thử kết hợp lớn các cài đặt cổng nối tiếp để xem kết quả nào đáp ứng một số loại phản hồi có ý nghĩa.

Modbus Serial Autodetect Wizard

Các vấn đề liên quan