Ich habe gerade ein Problem mit der seriellen Schnittstelle gefunden, konnte aber bisher keine Antwort darauf finden. Bitte lassen Sie mich wissen oder geben Sie mir ein paar Hinweise, wenn ich es falsch mache, Danke. Ich werde versuchen, die ganze Situation so detailliert wie möglich zu erklären und meine Frage am Ende zu stellen. Hier geht.C#: Wie kann die einstellbare Baudrate für ein Gerät mit seriellem Port bestimmt werden?
Ich kaufte einen USB-TTL-Konverter mit FTDI FT232RL-Chip und war neugierig, wie serielle Netzwerk funktionieren würde und wie ich mein eigenes Programm in C# schreiben könnte statt Hyper-Terminal verwenden. Ich fing an, das Programm zu schreiben, indem ich einige Tutorials las, um mir einen schnellen Start zu geben. Nachdem ich Tutorials gelesen habe, habe ich bemerkt, dass alle Tutorials, die ich gelesen habe, ähnliche Methoden verwenden, wenn es um Baudrateneinstellungen geht. Sie codieren die typischen Baudraten fest in ihren Code, anstatt zu fragen, ob das Gerät dies unterstützen würde. Ich versuche immer, das Programm so generisch wie möglich zu schreiben, deshalb habe ich angefangen zu untersuchen, wie ich Informationen vom Gerät abrufen kann. Nach der Suche habe ich this post answered by HiteshP sehr nützlich gefunden und habe die in der Post vorgeschlagene Methode weiter verwendet. Also hier ist, was mein Code wie folgt aussieht:
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"));
}
Das Ergebnis, das ich von der MessageBox bekommen ist 10066B70 die ich keine Ahnung, was es darstellt, wie es not shown in Microsoft's COMMPROP structure ist.
Ich habe mehr Suche versucht herauszufinden, was 10066B70 bedeutete, aber konnte keine Antwort finden, bis ich auf Basic serial port listening application von Amund Gjersøe stieß. Vielleicht musste ich AND-Operationen mit 10066B70 und dem gesamten Wert, der von COMPROP-Struktur von Microsoft angegeben wird, ausführen. Also habe ich den Wert in die Funktion geworfen.
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);
}
Nach dem Ausführen des Programms, erhalte ich die Baudraten:
300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 3000000
zufrieden war, dass es funktioniert, bis ich es mit den Werten verglichen, die für das Gerät in Windows Geräte-Manager angezeigt. Die Baudraten von dem Geräte-Manager waren:
300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600
ich die Baudrate verstehen kann: 3000000 ist nicht gezeigt, weil ich es selbst definiert, aber wo hat der Rest des Wertes kommt aus? Ich begann mich zu fragen, ob es vielleicht im Fahrer definiert war. Ich begann tiefer zu graben und fand das Dokument von FTDI AN232B-05 Configuring FT232R, FT2232 and FT232B Baud Rates. Im Dokument wird über die FTDI-Treiberkonfigurationsdatei (ftdiport.inf) gesprochen. Ich suchte danach und fand es unter Windows Systemordner. Der Eintrag sieht wie folgt aus:
[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
Es ist das gleiche in FTDIs Dokument Abschnitt 2.3, Aliasing Mit den Zusatz FT232B Sub-Integer Divisoren gezeigt mit dem man schaut. Im Anschluss an die Anweisung in Abschnitt 2.3 und die ConfigData von ftdiport.inf übersetzen, erhalte ich die Baudraten:
300, 600, 1200, 2400, 4800, 9600, 19230, 38461, 57692, 115384, 230769, 461538, 923076, 14406
Wieder ist es nicht das gleiche wie das, was der Gerätemanager angezeigt wird. Wundert mich, ob die Baudrate im Gerätemanager auch fest codiert ist.
Ich habe auch versucht, wie Baudrate zählen: 1800 aus dem Gerätemanager wie in der ftdiport.inf Datei aussehen könnte:
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%
Fehler liegt innerhalb der zulässigen +/- 3% Fehlerquote wie angegeben im Dokument, also die Dateneingabe in ftdiport.inf sollte etwas, das wie folgt aussieht: in ftdiport.inf Datei, nirgends zu finden ist [82,46,01,00] Statt
1666.625 Dec = 00014682 Hex
Data entry after re-order: 00014682 Hex => 82,46,01,00
. Ich führte auch dwMaxBaud von COMMPROP und erhielt das Ergebnis 10000000, die sich bezieht:
BAUD_USER (0x10000000): Programmable baud rate.
So bedeutet dies, dass der Benutzer eine beliebige Baudrate verwenden können sie so lange wie, wie es die Baudrate von Sender und Empfänger erfüllt und sind innerhalb der Fehlermarge, oder? (Nur dafür, dass ich es nicht vertun, wie mein Gehirn ein bisschen unscharf zu bekommen beginnt)
So jetzt bin ich sehr verwirrt, ich habe 3 verschiedene Ergebnisse in meinem Gehirn:
- Was bedeutet 10066B70 aus meinem Programm?
- Unterschiedliche Ergebnisse im Vergleich zu den Baudratenwerten des Gerätemanagers, wenn 10066B70 UND-Operationen ausgeführt werden. Soll das so gemacht werden?
- Unterschiedliche Ergebnisse aus den Baudratenwerten des Gerätemanagers und dem Dokument aus FTDI. Ich habe keine Ahnung, welchem man vertrauen kann, da beide offiziell sind?
Nochmals vielen Dank für das Lesen alles, was ich gerade geschrieben habe, ich weiß, es ist ziemlich lang. Hoffentlich könnte mir jemand eine Antwort auf meine Fragen geben.
* Hinweis: Ich habe 10 Reputation nicht erreicht, also kann ich nicht mehr als 2 Links posten, deshalb habe ich die Links in den Kommentar eingefügt. Nochmals vielen Dank für Ihr Verständnis.
Verbindung 1: [Wie programmatisch alle verfügbaren Baudraten in C# (Serieller_Anschluss Klasse) von HiteshP finden] (http://stackoverflow.com/questions/1165692/how-to-programatically-find-all -available-Baudrate-in-c-sharp-serialport-Klasse) – Bou
Link 2: [COMMPROP-Struktur] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363189 (v = vs. 85) .aspx) – Bou
@stuartd Danke. – Bou