2016-07-07 65 views
6

Ho appena riscontrato un problema con la porta seriale ma finora non ho potuto trovare una risposta. Per favore fatemi sapere o darmi qualche indizio se sto sbagliando, grazie. Cercherò di spiegare l'intera situazione nel modo più dettagliato possibile e di porre la mia domanda alla fine. Ecco qui.C#: come determinare la velocità di trasmissione impostabile per un dispositivo con porta seriale?

Ho acquistato un convertitore da USB a TTL utilizzando il chip FTDI FT232RL ed ero curioso di sapere come funzionava la rete seriale e come avrei potuto scrivere il mio programma in C# invece di utilizzare il terminale iper. Ho iniziato a scrivere il programma leggendo alcuni tutorial per darmi un rapido avvio. Dopo aver esaminato le esercitazioni, ho notato che tutte le esercitazioni che ho letto utilizzano metodi simili quando si tratta di impostazioni della velocità di trasmissione. Esse codificano con difficoltà i tipici baud rate nel loro codice invece di chiedere se il dispositivo lo supporta. Cerco sempre di scrivere il programma più generico possibile, per questo motivo ho iniziato a cercare come recuperare informazioni dal dispositivo. Dopo aver cercato, ho trovato molto utile this post answered by HiteshP e ho continuato a utilizzare il metodo di riflessione suggerito nel post. Quindi, ecco quello che il mio codice è simile:

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

Il risultato che ottengo dalla MessageBox è 10066B70 che non ho idea di ciò che rappresenta come è not shown in Microsoft's COMMPROP structure.

Ho fatto più ricerche cercando di capire cosa intendeva dire 10066B70 ma non ho trovato nessuna risposta finché non mi sono imbattuto in Basic serial port listening application di Amund Gjersøe. Forse dovevo eseguire operazioni AND con 10066B70 e tutto il valore dato dalla struttura COMMPROP di Microsoft. Quindi ho buttato il valore nella funzione.

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

Dopo l'esecuzione del programma, ottengo le seguenti velocità di trasmissione:

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

era felice che ha funzionato fino a quando ho confrontato con i valori indicati in Gestione periferiche di Windows per il dispositivo. Le velocità di trasmissione dal Gestore dispositivo è stato:

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

Posso capire che la velocità di trasmissione: 3000000 non risulta, perché ho definito io stesso, ma in cui ha fatto il resto dei valori provengo? Ho iniziato a chiedermi se fosse stato definito nel driver. Ho iniziato a scavare più a fondo e ho trovato il documento FTDI AN232B-05 Configuring FT232R, FT2232 and FT232B Baud Rates. All'interno del documento, si parla del file di configurazione del driver di FTDI (ftdiport.inf). L'ho cercato e l'ho trovato nella cartella di sistema di Windows. La voce è simile al seguente:

[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 

sembra la stessa con quella mostrata nella sezione del documento di FTDI 2.3, Aliasing Utilizzando le addizionali FT232B Sub-Integer divisori. Seguendo le istruzioni nella sezione 2.3 e traducendo il ConfigData da ftdiport.inf, ottengo le seguenti velocità di trasferimento:

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

questo caso, non è la stessa cosa il gestore dispositivo risulti. Mi viene da chiedersi se il baud rate nel device manager è anche hard coded.

Ho anche provato a contare rate come baud: 1800 dal responsabile di dispositivo potrebbe essere simile nel 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% 

errore è ben all'interno del permesso margine di +/- 3% dell'errore come indicato nel documento, quindi la voce di dati in ftdiport.inf dovrebbe avere qualcosa che assomiglia a questo:

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

Invece, [82,46,01,00] è introvabile nel file di ftdiport.inf. Ho anche eseguito dwMaxBaud da COMMPROP e ottenuto il risultato 10000000, che si riferisce a:

BAUD_USER (0x10000000): Programmable baud rate. 

Quindi questo significa che l'utente può utilizzare qualsiasi velocità di trasmissione a loro piace fintanto che soddisfa la velocità di trasmissione del trasmettitore e ricevitore e sono entro il margine di errore, giusto? (Basta fare in modo Non ricevo male come il mio cervello sta iniziando a farsi un po 'sfocata)

Così, ora, sono molto confuso come ho 3 risultati diversi nel mio cervello:

  1. Che cosa significa 10066B70 dal mio programma?
  2. Risultati diversi rispetto ai valori della velocità di trasmissione del gestore dispositivi con 10066B70 che eseguono operazioni AND. È così che doveva essere fatto?
  3. Diversi risultati dai valori della velocità di trasmissione del gestore dispositivi e del documento da FTDI. Non ho idea di quale fidarsi di entrambi sono ufficiali?

Grazie ancora per aver letto tutto quello che ho appena scritto, so che è piuttosto lungo. Spero che qualcuno possa darmi qualche risposta alle mie domande.

* Nota: non ho raggiunto 10 reputazione, quindi non posso pubblicare più di 2 collegamenti, quindi ho inserito i collegamenti nel commento. Grazie ancora per la tua comprensione.

+0

Link 1: [Come trovare programatically tutti disponibili baudrates in C# (classe SerialPort) da HiteshP] (http://stackoverflow.com/questions/1165692/how-to-programatically-find-all -available-baudrates-in-c-sharp-serialport-class) – Bou

+0

Link 2: [struttura COMMPROP] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363189 (v = vs. 85) .aspx) – Bou

+0

@stuartd Grazie. – Bou

risposta

1

Fernhill rende un software in grado di provare automaticamente e rapidamente combinazioni di impostazioni della porta seriale per vedere quali risultano in una sorta di risposta significativa.

Modbus Serial Autodetect Wizard

Problemi correlati