Hallo, ich habe mir mit Fleurys UART Lib ein RS485 Protokoll aufgebaut. Controller ist ein "ATmega128" und RS485-Chip ist ein "sn75als176". Das Ganze im Halbduplex-Betrieb. Wenn ich Daten empfangen habe frage ich das TXC-Register ab bevor ich wieder den Richtungs-PIN auf Empfang setze. Das funktioniert prima. Was ich mir nicht erklären kann ist, dass ich mindestens ein _ms_delay(4) nach dem setzen in Senderichtung einfügen muss bevor ich via uart_putc Bytes verschicke. Mache ich das nicht, kommt nichts mehr am Master an. Woran könnte das liegen?
:
Verschoben durch Moderator
Schau mal ins Datenblatt des sn75als176... vermutlich wird dort eine maximale Zeit stehen, welche der Chip zum Umschalten zwischen Senden und Empfangen benötigt. ... Mit etwas Reserve ist das deine Wartezeit. Ich nutze den MAX485, da muss ich mind. 2ms warten...
Da habe ich auch schon nachgesehen, aber leider keine Angaben gefunden. Aber wenn Du sagst beim MAX ist es auch so... Ich muss mind. 4ms warten bevor ich mit dem senden beginne.
Beim RS485 Umschalten kann es zu einen Spike kommen, der als Startbit erkannt werden kann und dann sind alle Daten hinterher Müll. Abhilfe ist, die Terminierung entsprechend vorspannen. Peter
Peter Dannegger schrieb: > Beim RS485 Umschalten kann es zu einen Spike kommen, der als Startbit > erkannt werden kann und dann sind alle Daten hinterher Müll. > > Abhilfe ist, die Terminierung entsprechend vorspannen. > > > Peter Hi Peter, kannst Du mir das bitte näher erläutern?
Wenn der vorherige Transmitter abschaltet und die Terminierung nicht vorgespannt ist, dann stellt sich kommend aus einem eindeutigen Idle-Zustand ein Zustand A=B ein. In der Theorie mit perfekt abgeschlossenem Bus passiert dabei nichts - aber wenn die Praxis nicht ganz so genau der Theorie folgt...
Wieso liegt der Thread eigentlich in "GCC"?
A. K. schrieb: > Wieso liegt der Thread eigentlich in "GCC"? Weil ihn niemand vor dir gemeldet hat. ;-)
Hi >Wenn ich Daten empfangen habe frage ich das >TXC-Register ab bevor ich wieder den Richtungs-PIN auf Empfang setze. Sicher, das das beim Empfangen passiert? Da macht TXC eigentlich keinen Sinn. TXC wird gesetzt, wenn ein Datenbyte vollständig übertragen wurde und kein weiteres mehr im Puffer ist. Ist also nur für Senden relevant. MfG Spess
Sind Master und Slave identische Hardware? Ansonsten nimmt der Master nicht schnell genug die Umschaltung vor.
spess53 schrieb: > Hi > >>Wenn ich Daten empfangen habe frage ich das >>TXC-Register ab bevor ich wieder den Richtungs-PIN auf Empfang setze. > > Sicher, das das beim Empfangen passiert? Da macht TXC eigentlich keinen > Sinn. TXC wird gesetzt, wenn ein Datenbyte vollständig übertragen wurde > und kein weiteres mehr im Puffer ist. Ist also nur für Senden relevant. > > MfG Spess Ja sorry mein Fehler, ich schaue damit natürlich, ob der Sendepuffer leer ist. >Sind Master und Slave identische Hardware? >Ansonsten nimmt der Master nicht schnell genug die Umschaltung vor. Die Hardware ist identisch. Aber vielleicht habe ich in der Software der Gegenseite einen Fehler und dort wird nicht schnell genug auf "Empfang" gestellt. Danke erstmal für die Hinweise, ich werde nochmal "wühlen" :)
Helmut Lenzen schrieb: > Kai I. schrieb: >> kannst Du mir das bitte näher erläutern? > > So wie im Beispiel. Muss diese Terminierung direkt hinter jeden RS485 Baustein? Also Master und auch Slaves?
Kai I. schrieb: > Muss diese Terminierung direkt hinter jeden RS485 Baustein? Also Master > und auch Slaves? Die Terminierung mit den 120 Ohm Widerstaenden gibt es nur 2 mal, am Anfang und am Ende der Leitung. Dazu reicht dann auch die Vorspannungserzeugung mit den beiden 1K.
Okay Danke. Wie lang darf denn eigentlich die Stechleitung vom Bus bis zum Slave sein?
Kai I. schrieb: > Wie lang darf denn eigentlich die Stechleitung vom Bus bis > zum Slave sein? Das haengt letztlich von der Geschwindigkeit (Baudrate) ab mit der die Daten auf dem Bus sind. Ein paar m duerften aber keine Probleme bereiten.
Danke. Ich werde das Gesagte umsetzen und mich dann wieder melden.
Also, durch die Terminierung auf beiden Seiten kann ich die Umschaltgeschwindigkeit leider nicht positiv beeinflussen. Es funktioniert nach wie vor nur, wenn ich nach dem Umschalten auf "Senden" 5ms warte bevor ich loslegen. Noch andere Ideen?
aus dem Datenblatt des sn75als176: tPZH Output enable time to high level: 80 ns tPZL Output enable time to low level: 30 ns Also sollte die Umschaltung auf Senden relativ schnell geschehen... die weiter oben im Thread geannten 2ms bzw 4ms Wartezeit sind evtl. durch andere Umstände bedingt
Okay, nur welche. Ich verwende dieses Board: http://shop.chip45.com/epages/es10644620.sf/de_DE/?ObjectPath=/Shops/es10644620/Products/Crumb128-4.0/SubProducts/crumb128-4.0-14 Anbei die Code-Auszüge, vielleicht habt Ihr noch eine Idee und ich sehe den Wald vor lauter Bäumen nicht mehr :)
1 | void RS485_transmit(void) |
2 | {
|
3 | (PORTD |= (1<<PD4)); // switch RS485 to transmit |
4 | _delay_ms(4); |
5 | }
|
6 | |
7 | void RS485_receive(void) |
8 | {
|
9 | while ( !( UCSR1A & (1<<TXC1)) ); // Wait for empty transmit buffer |
10 | UCSR1A |= (1<<TXC1); // clear txc flag |
11 | |
12 | (PORTD &= ~(1<<PD4)); // switch RS485-Bus to receive |
13 | }
|
14 | |
15 | void RS485_send_Packet(void) |
16 | {
|
17 | RS485_transmit(); // switch RS485-Bus to send |
18 | |
19 | uart1_putc(STARTBYTE); |
20 | for (uint8_t i=0; i < 8; i++) |
21 | {
|
22 | uart1_putc(RS485_send_Data[i]); |
23 | }
|
24 | uart1_putc(STOPBYTE); |
25 | |
26 | RS485_receive(); // switch RS485-Bus to receive |
27 | }
|
Nehme ich die Wartezeit in der RS485_transmit() runter, funktioniert meine Kommunikation nicht mehr. Die Funktionen sind auf Slave- sowie auf Masterseite identisch.
Kannst du mal ein Skope an die Leitungen haengen? Ein Kanal an dem Umschaltsignal der andere an die Transmitleitung. Dann sieht man wo es da knallt.
Am bestens mal mit dem Oszi nachschauen, ob nicht doch etwas Datenmäßig kollidiert. Z.B. PD4 von Master und Slave nachmessen... Was noch zu beachten wäre: die Daten, die vom µC gesendet werden, werden von diesem auch wieder Empfangen, sofern bei der UART der Empfang nicht deaktiviert ist.
sorry, letzteres stimmt nicht, weil ja beim Senden der Empfänger auf Transceiver-Seite deaktiviert ist
Genau so etwas habe ich auch einmal geschrieben :) Du musst auf zwei Dinge achten: - ist der Ringbuffer alle? - hat das hardware uart modul alles aus TXD herausgeschrieben? Wenn beide Bedingungen erfüllt sind kannst du umschalten. Es funktioniert ohne delay. Bei mir ist ein Problem mit EMI, Überläufen, offenen Leitungen und damit "verschluckten" Zeichen aufgetreten.
abc schrieb: > sorry, letzteres stimmt nicht, weil ja beim Senden der Empfänger auf > Transceiver-Seite deaktiviert ist Nicht unbedingt. Der 75xx176 hat 2 Eingaenge. Einer fuer den Sender und einen fuer den Empfaenger. Wenn man den Receiver disabelt geht sein Ausgang zum uC auf hochohmig. Hast du am Receiverausgang des 76xx176 auch einen Pullup geschaltet b.z.w. den internen Pullup eingeschaltet?
Nochwas. Der TxComplete Interrupt kommt wenn das Schieberegister leer ist. Dann kommt aber noch das Stopbit. Dh wenn man im TXC interupt die Richtung umschaltet schneidet man das Stopbit ab.
Fuenf Tassen schrieb: > Nochwas. > Der TxComplete Interrupt kommt wenn das Schieberegister leer ist. Dann > kommt aber noch das Stopbit. Dh wenn man im TXC interupt die Richtung > umschaltet schneidet man das Stopbit ab. Das könnte wohl das Problem sein. Ich habe jeweils am Master sowie am Slave den Richtungsumschaltungsport ans Oszi gehangen. Leider bekomme ich die Aufnahmen nicht auf den Rechner. Ich habe deswegen Paint bemüht ^^. Der Slave schaltet also schon auf transmit um zu antworten, bevor der Master auf receive geschaltet hat. Wenn ich nur in der Slaveroutine ein Delay von 500µs nach dem Umschalten einfüge funktionierts. Ich möchte das Ganze aber ohne Delays realisieren. Es sieht für mich nach Deinem hier beschriebenen Problem aus, dass ich das Stopbit abschneide. Wie verhindere ich das? Dazu muss ich noch sagen, dass meine Datenpakete von einem Startbit "&" und einem Stopbit "#" eingeschlossen sind. Evtl. empfängt der Slave das komplette Paket weil er alles innerhalb dieser beiden BITs bekommen hat und will sofort die Antwort schicken ob wohl nochwas im Receiver-Buffer hängt. Kann ich evtl. so eine Interrupt-Abfrage wie für den EMPTY-Transmitbuffer auch für den Receive-Buffer machen, bevor ich umschalte?
Kai I. schrieb: > Ich möchte das Ganze aber ohne Delays realisieren. > Es sieht für mich nach Deinem hier beschriebenen Problem aus, dass ich > das Stopbit abschneide. Wie verhindere ich das? Ohne es noch einmal gelesen zu haben, wer jetzt Master und wer Slave sind: der Empfang eines Bytes wird in der Mitte des Stoppbits als fertig signalisiert. Schaltet jetzt der Empfänger schnell auf Senden um, so ist das Stoppbit des vorherigen Senders noch aktiv. Hier findet die Kollision statt! Ganz ohne delay() wirst Du nicht auskommen, so blöd es auch sein mag.
Oh, Deinen letzten Text hattest Du noch nachträglich verändert. Um welche Baudrate geht es denn hier?
Kai I. schrieb: > Dazu muss ich noch sagen, dass meine Datenpakete von einem Startbit "&" > und einem Stopbit "#" eingeschlossen sind. Das sind weder Start- noch Stopbits, das ist Dein Protokollrahmen, der aber mit dem Problem nichts zu tun hat. Start- und Stopbits werden ohne Dein Zutun von der UART-Hardware selbst erzeugt, die Menge der Stopbits kann zwischen 1 und 2 konfiguriert werden, das Startbit ist immer da.
Ja okay, wie hilft mir das weiter? Momentan arbeite ich mit 57600 Baud.
Hi >Der TxComplete Interrupt kommt wenn das Schieberegister leer ist. Dann >kommt aber noch das Stopbit. Dh wenn man im TXC interupt die Richtung >umschaltet schneidet man das Stopbit ab. Seit wann denn das? Datenblatt zu TXC: This flag bit is set when the entire frame in the Transmit Shift Register has been shifted out and there are no new data currently present in the transmit buffer (UDRn). Und zum Frame gehören auch das/die Stoppbit(s). MfG Spess
Ja. Vielleicht. Ich hatte das Problem auch schon mal in genau dieser Konstellation. Mit dem Scope verifiziert. Und ein Delay for groesser-gleich einem Bit hat's dann geloest. Den Delay hab ich mit dem Timer gemacht.
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.