Forum: Compiler & IDEs Problem mit USART


von jens1186 (Gast)


Lesenswert?

Hallo!

Ich habe eine Frage zur Programmierung eines Atmel ATxmega 128A1.
Ich möchte interrupt gesteuert über einen USART Daten lesen und 
schreiben.
Habe mir ein Bsp. Programm angesehen, verstehe allerdings die 
verwendeten Interrupt-Routinen nicht so ganz.
1
ISR( USARTC0_RXC_vect )
2
{
3
    USART_RXComplete( &USART_data );
4
}
5
6
ISR( USARTC0_DRE_vect )
7
{
8
    USART_DataRegEmpty( &USART_data );
9
}

Kann mir jemand das Prinzip (die Aktion, die nach einem Interrupt in 
diesem Falle durchgeführt wird) kurz erklären?
Kann ich in diesen Routinen auch z.B. definieren, dass nach einem 
Interrupt z.B. PortX gesetzt werden soll?

von Timmo H. (masterfx)


Lesenswert?

Naja die ISR
1
ISR( USARTC0_RXC_vect )
wird aufgerufen wenn ein oder mehrere Bytes empfangen wurden. Die 
Funktion USART_RXComplete scheibt die empfangenen Daten in den Buffer 
USART_data.

die ISR
1
ISR( USARTC0_DRE_vect )
wird aufgerufen wenn das DataRegister leer ist. Dann werden über die 
Funktion
USART_DataRegEmpty die Daten aus dem Buffer USART_data (bzw. ein 
Zeichen) versendet.

Und ja du kannst auch Ports setzen etc. Nur solltest du zusehen, dass 
eine ISR möglichst schnell abgearbeitet sein sollte um nicht andere ISRs 
wie Timer etc zu blockieren.
Port setzen geht natürlich schnell, aber du solltest nicht anfangen in 
einer ISR einen riesen String zu analysieren. Das sollte man in einer 
anderen Funktion machen, die z.B. auf ein Flag pollt welches 
Signalisiert, dass ein neuer String eingetroffen ist.

von jens1186 (Gast)


Lesenswert?

Danke erstmals!

Das heißt, wenn ich jetzt z.B. meinen String empfangen habe, wird 
automatisch ein Interrupt ausgelöst und die erste ISR abgearbeitet?
Und wenn der String komplett gesendet wurde, wird die zweite ISR 
abgearbeitet?
Seh ich das so richtig?

Und nach den ISR wird wieder die Hauptschleife ausgeführt, also z.B. 
weitere Daten gesendet bzw. empfangen?

von Karl H. (kbuchegg)


Lesenswert?

jens1186 schrieb:
> Danke erstmals!
>
> Das heißt, wenn ich jetzt z.B. meinen String empfangen habe, wird
> automatisch ein Interrupt ausgelöst und die erste ISR abgearbeitet?

Nein.
Deine USART weiß nix von Strings.

Nach jedem Byte!

> Und wenn der String komplett gesendet wurde, wird die zweite ISR
> abgearbeitet?
> Seh ich das so richtig?

Aus 2 Gründen: Nein.
1) Wieder: Da ist nix mit Strings! Auf der Ebene USART arbeitet man mit 
Bytes
2) Die eine ISR ist für Empfangen zuständig. Die andere für Senden.
   Data Register Empty bedeutet: Der µC hat gerade ein Byte 
rausgeschickt.
   Sein Datenregister ist soweit leer, dass das Programm das nächste
   zu versendende Byte einschreiben könnte.

von jens1186 (Gast)


Lesenswert?

OK, d.h. nach jedem rausgeschickten bzw. empfangenen Byte springt er in 
die jeweilige ISR?

Und eine Frage habe ich noch: Zum globalen Aktivieren der Interrupts 
reicht doch normalerweise sei().

Was machen dann diese Befehle genau (aus einem Bsp. Programm):
1
USART_InterruptDriver_Initialize(&USART_data, &USART, USART_DREINTLVL_LO_gc);
2
3
USART_RxdInterruptLevel_Set(USART_data.usart, USART_RXCINTLVL_LO_gc);
4
5
PMIC.CTRL |= PMIC_LOLVLEX_bm;

Der erste initialisiert eig. nur den Buffer, soweit ich das sehe?
Werden die anderen für die Befehle in den ISRs benötigt?

von DNS (Gast)


Lesenswert?

Vielleicht liest du mal das Datenblatt. Die XMEGAs haben 3 
Interrupt-Level, die aktiviert werden müssen... sei() alleine reicht 
nicht.

von jens1186 (Gast)


Lesenswert?

Und wenn ich weitere USARTs verwenden will, muss ich dann für jeden Port 
wieder diese Interrupts aktivieren?

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.