Hallo zusammen. Ich möchte auf einem Raspberry Daten über die serielle Schnittstelle ausgeben. Bedingung dabei: Die write-Funktion sollte genau dann zum normalen programm-Ablauf zurückkehren, wenn alle Daten gesendet wurden. Grund: An der Schnittstelle hängt ein RS485-Konverter, dessen Sendeteil ich nach der Übertragung ausschalten muss. Mit einigen Delay-Anweisungen schaffe ich zwar, dass die Kommunikation mit einem Frequenzumrichter (MODBUS) meistens klappt, nur erscheint mir diese Lösung alles andere als sauber. tcdrain klappt nicht. Hat jemand eine einfache Lösung?
lutz schrieb: > Hat jemand eine einfache Lösung? Nimm eine UART mit entsprechender Hardwareunterstützung, dann musst Du Dich nicht darum kümmern. Am einfachsten geht das mit einer USB-UART wie dem FT232R, der bietet eine für die Software transparente Hardwareunterstützung für RS485-Betrieb. Andernfalls müsstest Du die UART im SOC des Raspberry Pi genauer untersuchen; bietet sie eine Möglichkeit, den Zustand "Sendeschieberegister leer" abzufragen? Kann sie gar bei diesem Zustand einen Interrupt auslösen? Die "bessere" UART im Raspberry Pi ist eine PL011, das ist eine an die 16C650 angelehnte Variante: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0183g/index.html .. und die hat keine Hardwareunterstützung für den RS485-Betrieb. Du müsstest eine Kombination der Flags TXFE (Sendefifo leer) und BUSY (Uart sendet) verwenden, um das Ende des Sendens zu erkennen. Der Sende-Interrupt wird bereits generiert, wenn der Füllstand des Sendefifos einen eingestellten Pegel unterschreitet. Einen "ich bin jetzt wirklich fertig"-Interrupt gibt es nicht. Also müsstest Du im Handler für den Sendeinterrupt, wenn Du erkennst, daß Du nichts mehr zu senden hast, einen Timer aufziehen und bei dessen Ablauf o.g. Flags pollen, um dann Deine RS485-Sende/Empfangs-Umschaltung vorzunehmen ... Das sollte natürlich im Treiber der UART geschehen, nicht in Deiner Anwendung (oder programmierst Du "bare bone", d.h. ohne Betriebssystem?). Ist viel Gefrickel, da bist Du mit der USB-UART-Variante deutlich einfacher am Ziel.
Am Konverter einstellen, dass Du ein Echo der gesendeten Daten bekommst, und nach dem Empfang aller gesendeten Zeichen umschalten.
TCSADRAIN ist nur zum Übernehmen der Einstellung nachdem der Tx-Puffer leer ist. Siehe https://www.cmrr.umn.edu/~strupp/serial.html#3_1 "Setting the Baudrate" Probier mal (void)ioctl(port, TCFLSH); wie hier beschrieben: https://www.cmrr.umn.edu/~strupp/serial.html#5_1 mfg mf
lutz schrieb: > Hat jemand eine einfache Lösung? Man könnte einen für RS485 geeigneten USB2UART Chip nehmen, IIRC kennen bestimmte FTDI Chips sowas. In seltenen Fällen könnnen MCUs die Rx/Tx Umschaltung in Hardware erzeugen und an einem GPIO ausgeben, ich kenne sowas z.B. von NXP LPC17xx oder Silabs EFM32. Beim RPi müsste man mal ins Hardware Handbuch schauen. Eine Hardwarelösung wäre ein retriggerbarer Monoflop, der den Umschalter mit dem Low auf der Tx Leitung verknüpft - und bei high ungefähr nach einer Bitzeit den Tx wieder losslässt. Die Baudrate muss dafür aber konstant sein.
@ lutz (Gast) >Hat jemand eine einfache Lösung? Man nehme ein Monoflop ala 74HC123 und schalte den Eingang an die Sendedaten des UART, den Ausgang an den _RE/DE Pin des MAX485. Die Pulszeit stellt man auf ca. 15 Bitlängen ein. Wenn nun die fallende Flanke des Startbits kommt, schaltet das MONOFLOP auf HIGH und aktiviert damit den Treiber. Jede weitere, fallende Signalflanke macht einen Reset der Monoflopzeit (74HC123 ist ein retriggerbares Monoflop). Erst wenn keine Daten mehr kommen und das UART-TX Signal dauerhaft HIGH bleibt, schaltet das Monoflop wieder auf LOW und damit den Sender ab. Das dauert im Extremfall 1,5 Bytezeiten nach der letzten fallenden Flanke im Datenstrom.
Bei dem voll ausgestattetem UART auf dem RPi könnte man ausprobieren ob man das DTR Signal als Richtungsumschalter benutzen kann. Dessen Logik ist mir leider nicht klar aus der Doku ersichtlich. Der mini UART kennt diese Funktion nicht.
lutz schrieb: > Hat jemand eine einfache Lösung? Kann man Hardware-Flow-Control aktivieren, RTS mit CTS verbinden und das als Steuersignal für -RE/DE benutzen? mfg mf
lutz schrieb: > Ich möchte auf einem Raspberry Daten über die serielle Schnittstelle > ausgeben. Bedingung dabei: Die write-Funktion sollte genau dann zum > normalen programm-Ablauf zurückkehren, wenn alle Daten gesendet wurden. Bedenke mal, daß du zwischen deinem Programm und der HW noch das Betriebssystem dazwischen hast, was selbstverständlich die Daten zwischenpuffert und für dich unvorhersagbare Zeitabläufe mit sich bringt. Wann also dein Programm überhaupt Rechenzeit kriegt und ob das genau dann der Fall ist, wenn tatsächlich alle Daten gesendet wurden, ist sehr fraglich. Also sehe ich als einfache Lösung nur, daß dein Programm anhand der Baudrate und der Anzahl gesendeter Zeichen sich ausrechnet, wann die Übertragung fertig sein sollte. Dann noch etwas Zeit draufschlagen und dann den Sender ausschalten. Aber (s.o.) das kann eben auch mal ne ganze Weile später der Fall sein, eben wegen der Zuteilung der Rechenzeit. W.S.
Vielen Dank. An das Betriebssystem hab ich gar nicht gedacht. Bleibt wohl nur ein Hardwarelösung über Monoflops oder DTR (gibt ja auch die fertigen RS485-Converter wo bereits alles eingebaut ist, die ich aber vermeiden wollte).
lutz schrieb: > Bleibt wohl nur ein > Hardwarelösung über Monoflops oder DTR Was spricht gegen den von mir genannten Ansatz? Kann der Konverter das nicht?
Hmmm schrieb: > Was spricht gegen den von mir genannten Ansatz? Kann der Konverter das > nicht? Jetzt kapiere ich erst, was du meinst. Probiere ich gleich mal aus. Dagegen könnte aber sprechen, dass meinem Programm nicht die gesamte Rechenzeit zur Verfügung steht. Ich weiß nicht genau, nach welcher Zeit mein MODBUS-Gegenpart zu reden anfängt. Hab mal was von 50ms gelesen, das sollte also leicht reichen. Vielen Dank, obs erfolgreich war melde ich, sobald ich es weiß.
lutz schrieb: > Geht offenbar. Super Idee. Das mit dem Monoflop funktioniert perfekt, wenn man immer die gleiche Baudrate hat, dann kann man die Zeit darauf einstellen. In der Praxis ist das fast immer der Fall, nur muss man sich anpassen wenn ein anderes System eine andere Geschwindigkeit fährt. Es ist aber typisch für dieses Forum, dass eine gute Lösung erst einmal ignoriert oder abgelehnt wird. Hätte hmmm nicht nachgefasst hätte lutz das nie probiert. Georg
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.