Forum: Mikrocontroller und Digitale Elektronik Atmel 32U4 Uart Richtungsumkehr


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
Hallo, schon lange her das ich mich mit AVRs beschäftigen musste.

Ich habe ein Problem mit der Richtungsumkehr der Uart.

Nach dem Empfang eines Frames soll auf diesen geantwortet werden. Die 
sende Routine alleine funktioniert aber nicht nach dem Empfang eines 
Paketes.

Ich sehe das EN Bit was den Treiber umdreht und auch wo der Antwort 
Frame sein sollte aber es werden keine Daten auf den TX geschrieben.

Folgende Bedingung sollten erfüllt sein.

- UDRIEn 1 -> UDRx frei
- UCSRxB TXENx  1

trotzdem hat das schreiben auf das Register UDRx keine Wirkung, als 
würde das UDRx nicht frei sein. Kann es sein das der RX durch den 
default Pegel des Treibers blockiert wird ? Also dieser immer weiter 
Daten einließt und mir deshalb den UDR nicht frei gibt?

Was nicht unerwähnt sein sollte ich muss im Telegramm ein Break erzeugen 
mit umschalten der Baudrate.

: Bearbeitet durch User
von H.Joachim S. (crazyhorse)


Bewertung
0 lesenswert
nicht lesenswert
Ausser dem Namen fürs Datenrgister (UDRn) und und dem gleichen 
Baudratengenerator für beide haben Sender und Empfänger nichts 
miteinander zu tun. Und da es erwiesenermaßen bei anderen funktioniert, 
wird es wohl an deinem Programm liegen (den seltenen Fall eines 
Hardwaredefekts mal ausgeschlossen.

von Marco H. (damarco)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin auch ein Blödmann ....

Also mal in die Referenz geschaut und zwischen den Zeilen gelesen.

bevor man ins UDR schreibt muss man das TXCn im CSRnA erst löschen. 
Damit schaltet man das UDR Register um. Mit einer ISR wird dies 
automatisch erledigt.  Es hat trotzdem nicht funktioniert -> ich 
Blödmann habe nicht erkannt das das Devices gar nicht antworten kann so 
lange der Master den TX oben hält wenn dieser im reinen DMX Mode läuft, 
kehrt der auch die Richtung nicht um. Steckt man ihn ab hängt das ganze 
in der Luft.

Na ein paar kleinen Änderung die nicht ganz 8bit like waren hat das RDM 
Projekt sofort auf dem Atmel 32U4 funktioniert.


Unten das mit der 15 in der UID ist der AVR ;)


Vom Memory liege ich so bei 44% der 1k ;) wohl gemerkt 29 Parameter.

Das lässt sich sicherlich noch optimieren. Subdevices sind aber auf 
Grund des mangeln Speichers problematisch.  Der Sam3x auf dem das gebaut 
wurde hatte 100k ;)

von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Marco H. schrieb:
> bevor man ins UDR schreibt muss man das TXCn im CSRnA erst löschen.
> Damit schaltet man das UDR Register um.

Nein, da hast Du irgendwas gründlich fehlinterpretiert.

von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
Das steht aber so in der Referenz und ist auch logisch. Ich lösche das 
Bit -> schreibe ins UDR und warte bis es draußen ist. Dann kommt das 
nächste ...

"Note that the TXCn Flag must be cleared before each transmission 
(before UDRn is written) if it is used for this purpose."

"The TXCn Flag bit is automatically cleared when a transmit complete 
interrupt is executed, or it can be cleared by writing a one to its bit 
location.
The TXCn Flag is useful in half-duplex communication interfaces (like 
the RS-485 standard), where a
transmitting application must enter receive mode and free the 
communication bus immediately after completing
the transmission."

von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
Das ist so ähnlich wie das Ding mit dem Status Register beim lesen.

Erst  UCSRA auslesen und dann das UDR...
Aber ich lasse mich gerne belehren wenn doch anderes ist ... Das mit dem 
Umschalten war ewt. nicht korrekt.  Es sind ja zwei UDR Register die man 
über eine Adresse anspricht. Es wird wohl nach lesen bzw. schreiben 
selektiert.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Trotzdem ist es eine Fehlinterpretation. Das UDR fasst zwei Register in 
einem zusammen, das Senderegister und das Empfangsregister. Die Auswahl 
des jeweiligen Registers erfolgt durch die Art des Zugriffs - das 
Senderegister kann nur beschrieben werden, das Empfangsregister hingegen 
kann nur gelesen werden.

Das TXCn-Flag dient lediglich dazu, festzustellen, daß die UART das 
letzte geschriebene Byte bereits gesendet hat; wenn Du den Satz vor dem 
ersten von Dir zitierten Satz Dir auch angesehen hättest, sähest Du das 
auch:

> The TXCn Flag can be used to check that the Transmitter has
> completed all transfers (...)

Das ist wichtig, wenn man ein Protokoll wie RS485 implementieren will, 
weil man den RS485-Treiber umschalten muss, wenn man mit dem Senden 
eines kompletten Datensatzes fertig ist. Dieses Bit hilft einem dabei, 
den entsprechenden Zeitpunkt festzustellen; Du kannst es entweder pollen 
(d.h. zyklisch abfragen), dann musst Du es selbst vor dem Senden 
zurücksetzen, oder aber Du kannst es einen Interrupt auslösen lassen, 
dann musst Du Dich um das Zurücksetzen nicht kümmern.

In der ISR musst Du dann feststellen, ob der komplette Datensatz 
gesendet ist, und kannst dann die Steuerleitung für den RS485-Treiber 
entsprechend ansteuern.

Aber das hat mit der UART selber nichts zu tun, sondern ist eine 
Protokollebene oberhalb dessen, was die UART macht.

von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
1
for(int i=0;i<length;i++){
2
    
3
UCSR1A|= (1<<TXC1);
4
UDR1 = data[i];  
5
while(!(UCSR1A&(1<<TXC1)));
6
}
1
UCSR1A|= (1<<TXC1);
  entfernt man das schweigt das ganze...

Ich rufe für das senden keine ISR auf, ich schalte auch alle ISRs aus da 
das antworten zeitkritisch ist.

von c-hater (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Marco H. schrieb:

> Also mal in die Referenz geschaut und zwischen den Zeilen gelesen.

Das glaubst höchstens du.

> bevor man ins UDR schreibt muss man das TXCn im CSRnA erst löschen.

Unsinn. TXCn ist hyperfluid für den eigentlichen UART-Sendeverkehr. Der 
wird nämlich über UDREn als "Kontrollinstanz" abgewickelt.

TXCn braucht man nur dann, wenn man aus irgendeinem Grunde die 
Sende-Hardware der UART mal explizit komplett ausleeren muss, ohne den 
Inhalt dessen zu beschädigen, was an Bits noch in der Hardware-Queue 
rumlungert, sondern sicherstellen will oder muss, dass auch diese noch 
komplett gesendet wird.

Also eher selten... Eine typische Anwendung wäre allerdings irgendwas 
mit RS485, weil das nunmal simplex ist, d.h.: umschalten auf Empfang 
darf man erst, wenn die Sendung nachweislich komplett 'raus ist. Da darf 
und sollte man dann TXCn beschäftigen.

Dein Problem ist offensichtlich, dass du die Funktionsweise der USART 
nicht wirklich kapiert hast...

von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe es schon verstanden was ihr meint, das Problem ist das es nicht 
funktioniert.

1
for(int i=0;i<length;i++){
2
3
UDR1 = data[i];     
4
UCSR1A|= (1<<TXC1);
5
6
while(!(UCSR1A&(1<<TXC1)));
7
}

kehrt man die Reihenfolge um funktioniert nur kurz dann ist Feierabend 
der code hängt dann in der schleife und der BUS wird durch den TX 
blockiert.
1
for(int i=0;i<length;i++){
2
3
UDR1 = data[i];     
4
5
while(!(UCSR1A&(1<<UDRE1)));
6
}

kommt es zu packet errors ..

Auch wenn man auf das TXC1 wartet .. Das UDREn sagt ja das UDR ist frei, 
TXCn alle Daten sind raus ..

von spess53 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
HI

>while(!(UCSR1A&(1<<UDRE1)));

Ob UCR frei ist prüft man vor dem

>UDR1 = data[i];

Siehe Datenblatt.

MfG spess

von Marco H. (damarco)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Das mache ich auch bevor ich in die sende Routine komme.

Den timer brauche ich um das RX timeout festzustellen, ja das könnte man 
auch in der ISR aber den Timer brauche ich auch so das die Antwort min 
176µ nach dem RX erfolgen muss.  Man könnte auch den Überlauf checken ca 
4ms oder den counter checken dann hat das erzeugen der Antwort zu lange 
gedauert, da lief dann etwas schief. So zerstört man kein DMX Paket vom 
Bus.

Auch das berechnen der BAUD rate könnte man verbessern, aber beim break 
ist der Fehler ziemlich Wurst.

von Marco H. (damarco)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe die Routine nochmal verändert und zwar in der Hinsicht 
getrennte Buffer für RDM und DMX zu verwenden. Es gab eine Laufzeit 
abhängigen Fauxpas, der AVR war an einer stelle nicht flott genug die 
Daten weg zu kopieren.

Das Signal wird jetzt auf Gültigkeit geprüft. -> kein geflacker mehr mit 
dem Finger in der Dose ;) usw.

Dem Dimmer wurden folgende Modi hinzugefügt.

- 8bit RGB Mode
- 16bit RGB Mode
- 8bit RGB Fader Mode -> 1 Channel ist Master
- switch Mode

wie immer alles steuerbar über RDM

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.