Forum: Mikrocontroller und Digitale Elektronik Senden mit UART Tx-Interrupt


von H. G. (ledi)


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
}

von 123 (Gast)


Lesenswert?

Da gibt's sicher ein "TX Reg empty" Flag...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Guck mal in die UART Lib von Peter Fleury und schreibse dir passend um.
Stichwort FIFO und senden beim tx empty IRQ

von H. G. (ledi)


Lesenswert?

123 schrieb:
> Da gibt's sicher ein "TX Reg empty" Flag...

Habs mit
1
while(!(UCSRA & (1<<UDRE)))
schon versucht. Leider ohne Erfolg.

von Karl H. (kbuchegg)


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?

von H. G. (ledi)


Lesenswert?

Ja so ein kleines ; kann sehr böse sein ;-)

Danke!

Aber sollte das normalerweise nicht schon der Tx Interrupt alleine 
erledigen?
Ich meine der Tx Interrupt wird nur dann ausgeführt, wenn der Tx buffer 
leer ist. Oder irre ich hier?

von Karl H. (kbuchegg)


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.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Ich zietier mich mal selbst:
Martin Wende schrieb:
> Guck mal in die UART Lib von Peter Fleury
Also tuh das und dann siehst du was man in den Interrupt schreiben muss 
mit det tut was du willst.

Dein Code da oben is Käse :X
Der macht nichts weiter als immer das zu senden, was bereits im 
Senderegister steht.

von Reinhard Kern (Gast)


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

von Stefan E. (sternst)


Lesenswert?

Reinhard Kern schrieb:
> 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.

Schau nochmal genau hin. Die TX-ISR hat nur eine Zeile, der Rest ist 
wohl ein Auszug aus main.

von Reinhard Kern (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Die TX-ISR hat nur eine Zeile, der Rest ist
> wohl ein Auszug aus main.

Stimmt schon, aber das hat er wahrscheinlich auch nicht so gemeint. Mit 
den Klammern hat ers nicht so.

Gruss Reinhard

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.