Senden mit UART Tx-Interrupt

OP #3013876
Lesenswert?
• ▲
▼
Hallo,

ich habe eine Frage zum Senden per UART Tx Interrupt.
Ich verwende das EUSART Register (Controller = AT 90PWM316), da ich auch 
auf 16 Bit umschalten können muss.

Das Problem ist, dass wie hier im Beispiel ersichtlich, die Daten AA, 
BB, CC und DD nur dann erfolgreich hintereinander gesendet werden, wenn 
ich zwischen jedem UDR ein kleines delay von 10ms einbaue.

Hat jemand einen Vorschlag, wie ich das eleganter lösen kann?

Hier mein Codeausschnitt:
1
ISR (USART_TX_vect)
2
{
3
       UCSRB |= (1 << RXCIE) + (1 << RXEN);    //enable RX
4
}
5

6
if (value[0] == 0x77)            
7
{
8
      TIMSK0   &= ~(1<<TOIE0);              // Timer0 overflow interrupt enable
9
      UCSRB   &= ~((1 << RXCIE) + (1 << RXEN));    // disable RX 
10
      EUDR  = 0;                 // Oberes Datenregister (MSB)   (Muss zuerst beschrieben werden!)
11
      UDR    = 0xAA;             // Unteres Datenregister (LSB)   (Daten werden erst mit UDR übertragen!)
12
      UDR    = 0xBB;
13
      UDR    = 0xCC;
14
      UDR    = 0xDD;
15
}
#3013931
Lesenswert?
• ▲
▼
H. G. schrieb:
> 123 schrieb:
>> Da gibt's sicher ein "TX Reg empty" Flag...
>
> Habs mit
>
1
> while(!(UCSRA & (1<<UDRE)))
2
>
> schon versucht. Leider ohne Erfolg.

Wundert mich so nicht.
Da fehlt noch was.
Denn was soll denn passieren, solange die Bedingung erfüllt (die UART 
also nicht bereit zum versenden des nächsten Zeichens) ist?

Es muss gewartet werden! Also nichts tun!
1
  while(!(UCSRA & (1<<UDRE)))
2
    ;

Der einzelne Strichpunkt ist 'nichts tun'. Eine leere Anweisung.


Hast du denn den Code aus dem Tutorial gesehen? Hast du ihn auch 
eingehend studiert und dir von jedem Buchstaben da drinn klar gemacht, 
warum er da steht?
#3013979
Lesenswert?
• ▲
▼
H. G. schrieb:
> Ja so ein kleines ; kann sehr böse sein ;-)
>
> Danke!
>
> Aber sollte das normalerweise nicht schon der Tx Interrupt alleine
> erledigen?

Der Interrupt tut von alleine überhaupt nichts.
Der Interrupt ist die Benachrichtigung von der UART "Jetzt ist das 
Zeichen komplett rausgeblasen". Was du dann mit dieser Information 
anfängst ist dein Bier.

Wurde ja schon gesagt:
Hol dir die Fleury Lib und sieh dir mal an, wie das dort gemacht ist.

> Ich meine der Tx Interrupt wird nur dann ausgeführt, wenn der Tx buffer
> leer ist. Oder irre ich hier?

Das heisst aber nicht, dass du erst mal unbegrenzt Zeichen in die USART 
stopfen kannst. Der Interrupt ist die Benachrichtigung 'Ich wär jetzt 
wieder soweit. Wenn du willst kannst du mir das nächste Zeichen ins UDR 
geben'.


Daraus dann Funktionalität aufzubauen, der du einen ganzen String 
übergibst, der von der Funktion zwischengespeichert wird und sukzessive 
bei jedem ISR Aufruf Zeichen für Zeichen rausgeblsen wird, sodass der 
Aufrufer erst mal nicht warten muss, bis der String komplett draussen 
ist .... das ist dein Bier. Der µC stellt dir die Mittel dafür zur 
Verfügung. Aber der Programmierer bist immer noch du.
Gast #3014109
Lesenswert?
• ▲
▼
Martin Wende schrieb:
> Dein Code da oben is Käse :X

Ganz so käsig ist er garnicht, er hat nur nicht begriffen, dass der Tx 
IRQ primär dazu da ist, das nächste Zeichen ins UART zu stopfen und 
nicht einen ganzen Text. Ist das Zeichen verarbeitet, kommt nämlich ein 
neuer Tx Interrupt für das 2. Zeichen usw.

Gruss Reinhard

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren