RS485 wartezeit nach Umschaltung auf senden notwendig, warum?

OP #2703830
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?
#2704782
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...
Gast #2705172
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
OP #2705314
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" :)
Gast #2729596
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
OP #2729601
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.
Gast #2729615
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.
#2729664
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.
#2729822
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?
Gast #2729853
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.
OP #2729978
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?
Angehängte Dateien:
Gast #2730005
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.
Persönliche Seite #2730013
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.
Gast #2730032
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
Gast #2730174
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren