Ich wurde mit der Implementierung des ModBus-Protokolls über ein RS485-2-Draht-System beauftragt. (Eigentlich sind es drei Drähte, A / B und GND). ModBus ist jedoch nicht der Punkt, aber der Schritt davor ... einfache I / O über die Schnittstelle.
Ich verwende den FTDI USB-RS485-Konverter, um einen Linux-Host (nicht austauschbar) mit einem Windows-Host zu verbinden (austauschbar mit einem anderen Linux-Host, obwohl ich das gerne vermeiden möchte)
Die Kodierung soll 19200, 8, n, 1 sein. Aber es scheint einfach nicht zu funktionieren.
Ich habe nicht den genauen Code, aber unter Linux mache ich das:
%Vor%Als nächstes konfiguriere ich den Port.
%Vor%Parität und Flusskontrolle sind derzeit nicht geplant, da das Endergebnis mit einer Low-Level-Karte verbunden wird, wo ich mich selbst um die Signale kümmern muss. Außerdem gibt es keine Kabel, die eine "uneingeschränkte Kommunikation" ermöglichen würden. (Schließlich möchte ich nicht, dass ein XON / XOFF-Zeichen den Bytebereich begrenzt, den ich senden kann)
Alle diese Funktionen werden ordnungsgemäß ausgeführt und die Daten werden festgelegt.
Unter Windows öffne ich den seriellen Port wie folgt:
%Vor%Die Parität ist deaktiviert, ebenso wie die Flusskontrolle. Die Bytegröße ist auf 8 eingestellt.
Bearbeiten: Da es gefragt wurde, hier ist mein Code für die Baudrate unter Windows (aus dem Speicher) SP.DCBlength = Größe von (SP); SP.BaudRate = 19200; SP.Parity = NOPARITÄT; SP.StopBits = ONESTOPBIT; SetCommState (hSerial, & amp; SP);
Auch hier laufen alle diese Funktionen einwandfrei.
Nun, für den Testfall, der mir große Kopfschmerzen bereitet.
Auf dem Linux-Host erstelle ich einen Byte-Puffer von 256 Byte Größe. Dieser Puffer wird mit den Zeichenwerten von 0 bis 255 gefüllt und dann über den Draht mit Schreiben gesendet. Gleichzeitig wartet die andere Seite mit 'ReadFile' darauf, dass Daten ankommen.
Mit dieser Konfiguration, sowohl für den 'anderen Linux-Host', als auch für den Windows-Host, kommen 256 Bytes ... aber es sind NICHT die Zahlen von 0-255, sondern etwas 00 06 usw.
Ich kann den Linuxhost zum Laufen bringen, wenn ich alle Mitglieder der termios-Struktur auf 0 setze, bevor ich die Optionen setze, die ich eigentlich will. Ich vermute, es liegt an den Steuerzeichen ... aber wenn ich das tue, erhält der Windows-Host entweder nur 4 von 256 Bytes.
Wie gesagt, leider habe ich den Code nicht griffbereit. Wenn jemand eine Idee hat, von welchem Punkt ich das angehen könnte, wäre ich sehr dankbar. Ich werde mehr Code posten, sobald ich wieder Zugriff darauf habe.
Wie ich die Leseoperation implementiere:
%Vor%Zu beachten: Ich habe die Timeouts eingestellt, kann mich aber nicht an die genauen Werte erinnern.
Bearbeiten: Da ich nun wieder Zugriff auf meinen Arbeitsplatz habe, hier der aktuelle (aktuelle) Code.
%Vor%}
Was den eigentlichen Sende- / Empfangscode angeht:
%Vor%}
Wie für das Oszilloskop: Ich habe beide Richtungen mit dem Senden getestet. Beide haben ihren Job sehr gut gemacht.
Das Signal von 0x55 ist ein konstantes Up / Down in der Länge von 50 Mikrosekunden (wie es sollte, also ist auch das Einstellen der Baudrate kein Problem).
Also gibt es irgendetwas in meinem 'receive' Code, den ich falsch mache? Ist das 'Auswählen' falsch?
Ihre Lesefunktion könnte leicht explodieren. Wenn Sie sich am Ende des Puffers befinden und mehr als die Menge zum Füllen lesen, werden Sie über das Ende des Puffers hinaus kopieren und den Stapel überschreiben.
Auf der Linux-Sendeseite sollten Sie in den "Rohmodus" schauen, z. B. cfmakeraw (). Auf diese Weise werden Sie nicht von dem System belästigt, das Ihnen "hilft" (wie das Hinzufügen von CR, wenn Sie einen Zeilenumbruch senden - die Binärdaten werden wirklich verschraubt ...). Es gibt eine Möglichkeit, dies in Microsoft zu tun, aber ich vergesse, wie.
auf Windows-Seite, haben Sie das DCBLength-Feld in Ihrer DCB-Struktur festgelegt?
%Vor%Tags und Links c c++ serial-communication baud-rate rs485