Forum: Mikrocontroller und Digitale Elektronik AVR ATMega162 USART Senden im Rx Interrupt?


von Jens (Gast)


Lesenswert?

Hallo zusammen,
da ich noch nicht meine Testboards habe, bzw. die Mikrocontroller, 
wollte ich hier schon einmal fragen, ob sich hier jemand mit meinem 
Problem auskennt :)

Also: Ich habe vor, dass 2 ATMEGA 162 mit einander über die USART 
Schnittstelle kommunizieren.

Der eine sendet immer eine Anfrage, und der andere soll darauf 
antworten. Da diese Kommunikation höchste Priorität hat wollte ich es 
direkt im Interrupt machen.

Also wenn der eine Controller 5 Bytes empfangen hat, soll beim 5ten mal 
direkt im Rx Interrupt ein Byte gesendet werden. Sobald das Byte 
gesendet wurde ruft er ja den Tx Interrupt auf und dort soll er dann 
noch weitere Bytes senden. Geht so etwas???

Kann ich einfach im Rx Interrupt am ende "UDR1 = ucByte;" schreiben und 
der schmiert mir nicht dabei ab?

Ich hoffe es kann mir schonmal jemand ein paar nützliche Tips und Tricks 
verraten. Habe leider meine Controller noch nicht sonst würd ich einfach 
mal drauf los programmieren.

Gruß
Jens

von Johannes M. (johnny-m)


Lesenswert?

Jens wrote:
> Kann ich einfach im Rx Interrupt am ende "UDR1 = ucByte;" schreiben und
> der schmiert mir nicht dabei ab?
Warum sollte er das? Die USART-Sende- und Empfangsregister heißen zwar 
beide UDR und liegen an der selben Adresse im I/O-Space, aber es sind 
zwei getrennte Register. Bei Lesen von UDR wird eben auf das 
Empfangsregister zugegriffen und beim Schreiben auf das Senderegister.

Kollisionen kann es nur geben, wenn Du in den Sendepuffer schreibst, 
bevor der leer ist. Das sollte sich aber i.d.R. vermeiden lassen (auch 
ohne Warten auf UDRE).

> Sobald das Byte
> gesendet wurde ruft er ja den Tx Interrupt auf und dort soll er dann
> noch weitere Bytes senden. Geht so etwas???
Mach das nicht mit dem TxC-Interrupt, sondern besser mit UDRE.

von Jens (Gast)


Lesenswert?

Danke für die Antwort!

Lieber mit dem UDRE ??? der UDRE wird doch immer aufgerufen wenn er leer 
ist. Wenn nun aber 8 Bytes gesendet wurden soll er wieder andere Sachen 
machen, bis er neue Daten empfängt.

Der UDRE wird doch dann immer wieder ausgelöst oder ich müsst das Flag 
im Controllregister löschen oder seh ich das falsch?

Oder meinst du nun nur das UDRE Flag was mir angibt ob das Register 
Empty ist? quasi ne Endlosschleife in dem Rx Interrupt laufen lassen wo 
immer das Flag kontrolliert wird und er dann Byte für Byte sendet? Somit 
blockiere ich aber den Controller für rund 121µs (bei 1 MBaud[11 Bytes]) 
Das wollte ich eigentlich vermeiden. Nebenbei soll er später eventuell 
mal ein PWM Signal nebenbei verarbeiten, würde das dann nciht stören 
wenn ich den immer solange blockiere? Oder klappt das alles weil der 
Timer ja anscheinend wirklich alles alleine macht wenn er einmal als PWM 
Konfiguriert ist?

von pacer (Gast)


Lesenswert?

ich lasse meine UART auch im Interrupt empfangen. Wenn das letzte 
Zeichen gesendet wird, schalte ich den Interrupt UDRE innerhalb der ISR 
wieder ab. Wenn ich das nicht tue, springt er immer wieder in die 
zugehörige ISR. Dann läuft aber auch das Hauptprogramm nicht mehr.

von Falk B. (falk)


Lesenswert?

@ pacer (Gast)

>Zeichen gesendet wird, schalte ich den Interrupt UDRE innerhalb der ISR
>wieder ab.

Genau so macht man das auch.

> Wenn ich das nicht tue, springt er immer wieder in die
>zugehörige ISR. Dann läuft aber auch das Hauptprogramm nicht mehr.

Logisch.

MfG
Falk

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.