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