ISR fuer UART in AVR

OP #1000547
Lesenswert?

Hallo,

ich benutze AT90CAN128 von Atmel und habe eine ISR-Funktion und eine 
User-Funktion für UART geschrieben. Baudrate = 19,200 bits/s, Quarz = 8 
MHz.
1
SIGNAL(SIG_UART0_RECV)
2
{
3
  receive_uart_data = UDR0;  // Datenbyte speichern
4
  new_receive_uart_data = 0x01;  // Mitteilung vom neuen Datenbyte
5
}
6

7
void user_application()
8
{
9
  if (new_receive_uart_data == 0x01)  
10
  {
11
  // Datenbyte bearbeiten
12
  new_receive_uart_data = 0x00;
13
  }
14
}
Frage : Kann das passieren, dass UART-Daten verloren gehen, wenn 
UART-Daten zu schnell ankommen ?

Gruss
Senmeis
Persönliche Seite #1000571
Lesenswert?

Ja. Es können Verluste an mehreren Stellen auftreten.

1/ Die ISR läuft und es kommt ein neues Zeichen in der UART Hardware an. 
Wenn das nicht gespeichert werden kann, geht es verloren. Eher 
unwahrscheinlich bei Baudrate = 19,200 bits/s, Quarz = 8 MHz, aber je 
nach dem Restcode kann man das provozieren.

2/ user_application() wird zu selten ausgeführt. Der Puffer 
receive_uart_data ist nur ein Byte gross. Wenn zwischen zwei ISR 
Aufrufen kein user_application() Aufruf ist, geht das ältere Byte 
verloren.

3/ Man sieht die Definition von new_receive_uart_data nicht, 
insbesondere ob es volatile typisiert ist. Der Compiler kann in 
user_application() Code produzieren, der nicht berücksichtigt, dass eine 
ISR diese Variable zu einem beliebigen Zeitpunkt ändert.
OP #1009305
Lesenswert?

Hallo,

danke für die Hinweise.

Noch eine Frage zur angegebenen Anleitung "Interrupt". Zitat aus der 
Anleitung:
"D.h. während der UART selbsttätig das Zeichen sendet ist die CPU zum 
Warten verdammt."

Im Gegensatz habe ich immer folgenden Code benutzt, um ein Byte zu 
senden, also keine Interrupts.
1
// einzelnes Senden
2
void USART0_Tr_UINT8(UINT8 num8)
3
{
4
  while(!(UCSR0A&(1<<UDRE0)));
5
  UDR0 = num8;
6
}
Kann das Programm hier blockiert werden? Bisher habe ich noch keine 
Probleme gehabt.

Gruss
Senmeis
Gast #1009370
Lesenswert?

>Kann das Programm hier blockiert werden? Bisher habe ich noch keine
>Probleme gehabt.

Nein, eigentlich nur, wenn das Senden nicht gestattet ist (TXEN muß zum 
Senden gesetzt sein).

>Der UART ist ein oft benutztes Modul eines Mikrocontrollers. Anfänger >nutzen ihn 
meist im sogenannten Polling Betrieb (engl. to poll, abfragen).
>"D.h. während der UART selbsttätig das Zeichen sendet ist die CPU zum
>Warten verdammt."

Aus dem Zusammenhang gerissen kann man einen anderen Sinn hinter der 
Aussage vermuten.

>Im Gegensatz habe ich immer folgenden Code benutzt, um ein Byte zu
>senden, also keine Interrupts.

Bei einem gepufferten UART (zwei Bytes werden gespeichert) und geringer 
Datenmengen spricht nichts gegen die Poll-Methode.
Wenn man aber viele Daten (vielleicht auch noch relativ schnell) 
verschicken will, sollte man das "im Hintergrund" per ISR und 
Daten-Puffer lösen. Der Controller führt zwischen zwei Interrupts 
mindestens eine Anweisung aus.
#1009721
Lesenswert?

@ Owen Senmeis (senmeis)

>Kann das Programm hier blockiert werden?

Sicher durch die While-Schleife. Wobei das keine Blockieren im Sinn von 
endlos festfressen ist, sondern halt warten bis der FIFO des UARt 
leer ist.

> Bisher habe ich noch keine Probleme gehabt.

Das hat ja auch keiner behauptet, aber die CPU muss dennoch warten, wenn 
du z.b. einen String mit 10 Zeichen senden willst.

MFG
Falk

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