Forum: Mikrocontroller und Digitale Elektronik UART - RXEN wegen echo disablen


von FalkS (Gast)


Lesenswert?

Guten Abend,

ich habe eine Gerät, welches über UART angesprochen wird.
RX und TX sind dabei fest verbunden.
Wenn ich nun einen Befehl an das Gerät sende erhalte ich den Echo meines 
Befehls und die Antwort.

Ist es eine valide Lösung RXEN zu disablen und danach zu enablen, oder 
funktioniert das unter bestimmten Umständen nicht korrekt?

Etwa so:
1
UCSR1B &= ~(1 << RXEN1);
2
uart_puts("Command!\n");
3
UCSR1B |=  (1 << RXEN1);
4
uart_gets(&buffer);

Beste Grüße!

von Max D. (max_d)


Lesenswert?

FalkS schrieb:
> Ist es eine valide Lösung RXEN zu disablen und danach zu enablen, oder
> funktioniert das unter bestimmten Umständen nicht korrekt?

Aufgrund der präzisen Angaben zum Zielsystem und dem Inhalt der 
Funktionen kann man zu 100% sagen, dass es mögliche Szenarien gibt in 
denen dieses Konstrukt nicht funktionieren wird ......

von Theor (Gast)


Lesenswert?

Hm. Super. Wir haben eine Lösung. Jetzt fehlt nur noch das Problem dazu. 
:-)

von FalkS (Gast)


Lesenswert?

Upps. Es geht um den ATMega1284P.

von H.Joachim S. (crazyhorse)


Lesenswert?

Da du weisst, was du gesendest hat, ist es doch leicht, das identisch 
empfangene in Papierkorb zu werfen? Gleichzeitig erkennst du, ob evtl. 
ein anderer Sender auch versucht hat was zu senden und du 
dementsprechend davon ausgehen musst, dass die eigene Botschaft 
verfälscht wurde.
Ich lass den Empfänger immer an.

von Karl M. (Gast)


Lesenswert?

Hallo,

Bei mir ist das so ich sende Ihnen einen FIFO Puffer, der asynchron über 
die serielle Schnittstelle im Interrupt Betrieb sendet.

Somit funktioniert dein Konstrukt nicht.

von Wilhelm M. (wimalopaan)


Lesenswert?

Das nennt sich half-duplex oder one-wire Betrieb. Ist üblich und 
funktioniert so, wie Du es beschreibst (naja, man weiß nicht so genau, 
was uart_puts(...)) macht.

Wenn Du mehrere Teilnehmer hast und Kollisionen detektieren muss, dann 
solltest Du allerdings den RX enabled lassen und die ge-echo-ten Zeichen 
mit den gesendeten vergleichen.

In den vielen (neueren) µC können intern RX und TX gekoppelt werden und 
auch Open-Drain-Mode (mehrere Teilnehmer) eingestellt werden.

von Peter D. (peda)


Lesenswert?

FalkS schrieb:
> Etwa so:
> UCSR1B &= ~(1 << RXEN1);
> uart_puts("Command!\n");
> UCSR1B |=  (1 << RXEN1);
> uart_gets(&buffer);

Nein, so nicht. Du mußt warten, bis das letzte Stop-Bit angefangen 
wurde.

von FalkS (Gast)


Lesenswert?

> Nein, so nicht. Du mußt warten, bis das letzte Stop-Bit angefangen wurde.

Ich bin mir nicht sicher, ob ich keine Erklärung verstehe.
Um auf die Beendigung der Übertragung zu warten, könnte ich da soetwas 
machen?
1
uart_rx_disable();
2
uart_puts(request);
3
while (!(UCSR1A & (1 << UDRE1)));  /* warten bis Senden vorbei */
4
uart_rx_enable();

Auszug aus der Wiki:

UDRE (UART Data Register Empty)

    Dieses Bit zeigt an, ob der Sendepuffer bereit ist, um ein zu 
sendendes Zeichen aufzunehmen. Das Bit wird vom AVR gesetzt (1), wenn 
der Sendepuffer leer ist.

von Dietrich L. (dietrichl)


Lesenswert?

FalkS schrieb:
> UDRE (UART Data Register Empty)

So wie ich das sehe, brauchst du:

"Bit 6 – TXCn: USART Transmit Complete
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)."

UDREn sagt nur, das der Sendepuffer frei ist und du weitere Sendedaten 
nachladen kannst. Das Schieberegister muss dann noch nicht leer sein.

von H.Joachim S. (crazyhorse)


Lesenswert?

Ja, aber das heisst nicht, dass das letzte Zeichen auch schon gesendet 
ist. Das kann noch ganz oder teilweise im Schieberegister stecken.

von FalkS (Gast)


Lesenswert?

Ja, habe ich auch erst angenommen, aber in der Wiki steht:

TXC (UART Transmit Complete)

    Dieses Bit wird vom AVR gesetzt, wenn das im Sende-Schieberegister 
befindliche Zeichen vollständig ausgegeben wurde und kein weiteres 
Zeichen im Sendedatenregister ansteht. Dies bedeutet also, dass die 
Kommunikation vollumfänglich abgeschlossen ist.
    Dieses Bit ist wichtig bei Halbduplex-Verbindungen, wenn das 
Programm nach dem Senden von Daten auf Empfang schalten muss. Im 
Vollduplexbetrieb brauchen wir dieses Bit nicht zu beachten.

Weiter steht dort:
1
Das Bit wird nur dann automatisch gelöscht, wenn der entsprechende Interrupthandler aufgerufen wird, ansonsten müssen wir das Bit selber löschen.
2
Um das Bit zu löschen muss eine 1 an die entsprechende Position geschrieben werden!

Da ich den UART nicht im Interrupt-Betrieb benutzte, ist dieses Bit 
doch für mich nicht zu gebrauchen, oder?

Danke übrigens soweit für eure Hilfe.

von H.Joachim S. (crazyhorse)


Lesenswert?

Hat doch nichts mit Interrupt oder nicht zu tun.
UDRE:  du kannst ein neues Zeichen nach UDR schreiben, weil das vorher 
dort befindliche ins Ausgangsregister befördert wurde (das sind 2 
verschiedene Register).
TXC: das Schieberegister ist tatsächlich leer, d.h. alle Bits incl. 
Stopbit(s) sind raus und der Transmitter fummelt nicht mehr an der 
Leitung.
Ist übrigends auch ein oft gemachter Fehler bei RS485 (gleiche 
Problematik) - der Transceiver darf erst umgeschaltet, wenn alles raus 
ist.

von Dietrich L. (dietrichl)


Lesenswert?

FalkS schrieb:
> Da ich den UART nicht im Interrupt-Betrieb benutzte, ist dieses Bit
> doch für mich nicht zu gebrauchen, oder?

Doch!
Die Bedeutung des Bits ist dadurch nicht anders. Nur das Löschen 
passiert nicht automatisch im Interrupt, sondern du musst es nach 
Erkennen selber löschen.

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.