Forum: Mikrocontroller und Digitale Elektronik RS485 wartezeit nach Umschaltung auf senden notwendig, warum?


von Myjestic E. (myjestic)


Lesenswert?

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
von Christian B. (luckyfu)


Lesenswert?

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...

von Myjestic E. (myjestic)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Myjestic E. (myjestic)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

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...

von Helmut L. (helmi1)


Angehängte Dateien:

Lesenswert?

Kai I. schrieb:
> kannst Du mir das bitte näher erläutern?

So wie im Beispiel.

von (prx) A. K. (prx)


Lesenswert?

Wieso liegt der Thread eigentlich in "GCC"?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Wieso liegt der Thread eigentlich in "GCC"?

Weil ihn niemand vor dir gemeldet hat. ;-)

von spess53 (Gast)


Lesenswert?

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

von Gregor B. (Gast)


Lesenswert?

Sind Master und Slave identische Hardware?
Ansonsten nimmt der Master nicht schnell genug die Umschaltung vor.

von Myjestic E. (myjestic)


Lesenswert?

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" :)

von Myjestic E. (myjestic)


Lesenswert?

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?

von Helmut L. (helmi1)


Lesenswert?

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.

von Myjestic E. (myjestic)


Lesenswert?

Okay Danke. Wie lang darf denn eigentlich die Stechleitung vom Bus bis 
zum Slave sein?

von Helmut L. (helmi1)


Lesenswert?

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.

von Myjestic E. (myjestic)


Lesenswert?

Danke. Ich werde das Gesagte umsetzen und mich dann wieder melden.

von Myjestic E. (myjestic)


Lesenswert?

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?

von abc (Gast)


Lesenswert?

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

von Myjestic E. (myjestic)


Lesenswert?

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.

von Helmut L. (helmi1)


Lesenswert?

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.

von abc (Gast)


Lesenswert?

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.

von abc (Gast)


Lesenswert?

sorry, letzteres stimmt nicht, weil ja beim Senden der Empfänger auf 
Transceiver-Seite deaktiviert ist

von Anon Y. (avion23)


Lesenswert?

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.

von Helmut L. (helmi1)


Lesenswert?

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?

von Fuenf Tassen (Gast)


Lesenswert?

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.

von Myjestic E. (myjestic)


Angehängte Dateien:

Lesenswert?

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?

von Willi (Gast)


Lesenswert?

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.

von Willi (Gast)


Lesenswert?

Oh, Deinen letzten Text hattest Du noch nachträglich verändert.
Um welche Baudrate geht es denn hier?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Myjestic E. (myjestic)


Lesenswert?

Ja okay, wie hilft mir das weiter? Momentan arbeite ich mit 57600 Baud.

von spess53 (Gast)


Lesenswert?

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

von Fuenf Tassen (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.