Forum: Mikrocontroller und Digitale Elektronik Senden von Daten in einer ISR


von Daniel (Gast)


Lesenswert?

Hallo Zusammen,

Mal ne kurze Frage.
Bringt es etwas auf einen leeren Sendebuffer (UDRE0) zu warten wenn ich 
dies in der ISR ausführe? Oder kann ich die Daten auch sofort schicken

ISR(PCINT3_vect)      // Pin wurde getoggelt
{
  while ( !(UCSR0A & (1<<UDRE0)) )  // Wait for empty transmit buffer
  {
  }
  UDR0 = 0x40;  // send data "0x40"
}

von Boris (Gast)


Lesenswert?

Warten in einer Interruptroutine ist gaaaaanz schlechter 
Programmierstil.

Die übliche Vorgangsweise wäre:

In der Interruptroutine wird ein Flag gesetzt, z.B.
pin_toggled = 1;
und die ISR wird danach sofort wieder verlassen.

In der Hauptschleife wird geprüft, ob das Flag gesetzt und ob der buffer 
leer ist. Wenn beide Bedingungen wahr sind, dann die Daten in den buffer 
schieben und das Flag zurücksetzen.

von Daniel (Gast)


Lesenswert?

Ich hab das ganze jetzt umgeschrieben. Würde dies hier passen?

while(1)  // infinite loop
{
  while(wait_for_data == 0)  // wait for incoming data
  {
    if (overload_flag == 1 && UDRE0 == 1)
    {
      UDR0 = 0x40;      // send data
                        overload_flag=0;  // reset overload_flag
    }
  }
}

ISR(PCINT3_vect)
{
   overload_flag=1;
}

von Zac Hobson (Gast)


Lesenswert?

Nein, lass das Warten...

while(1)  // infinite loop
{
  if(wait_for_data == 0)  // wait for incoming data
  {
    if (overload_flag == 1 && UDRE0 == 1)
    {
      UDR0 = 0x40;      // send data
                        overload_flag=0;  // reset overload_flag
    }
  }

... next ...

}

von J.-u. G. (juwe)


Lesenswert?

Daniel schrieb:
> Würde dies hier passen?

Nein.

Das hier:
> UDRE0 == 1

wird nicht funktionieren. Die Abfrage, ob der Sendepuffer leer ist, war 
ja in Deiner ursprünglichen Version durchaus richtig und kann hier 
direkt übernommen werden.

von Daniel (Gast)


Lesenswert?

Die while schleife ist schon gewollt so, denn das Programm soll dort 
drinnen verharren bis "wait_for_data" von der --> ISR(USART0_RX_vect) 
gesetzt wurde.

Ja die Abfrage mit dem UDRE0 funktioniert so laut Simulator nicht!

if (overload_flag==1 && UDRE0==1)
{
   UDR0 = 0x40;        // send the "Overload" bit
   overload_flag = 0;  // reset the "overload_flag"
}

Wie kann ich denn aber das hier was funktioniert oben in die if Abfrage 
reinpacken? --> while ( !(UCSR0A & (1<<UDRE0)) )

Etwa so?

if (overload_flag==1 && while ( !(UCSR0A & (1<<UDRE0)) ))

von J.-u. G. (juwe)


Lesenswert?

Daniel schrieb:
> Etwa so?
>
> if (overload_flag==1 && while ( !(UCSR0A & (1<<UDRE0)) ))

Nein.

Du musst zwischen "while-Schleife" bzw. "if-Abfrage" und "Bedingung" 
unterscheiden. In Deinem Fall ist die Übernahme der Bedingung gefragt.

von Daniel (Gast)


Lesenswert?

Achso ich glaube ich hab verstanden was du meinst.

while(wait_for_data == 0)  // wait for incoming data from USART0
{
   if (overload_flag==1)  // if "overload_flag" is set
   {
  while (!(UCSR0A & (1<<UDRE0)))  // Wait for empty transmit buffer
  {
        }
  UDR0 = 0x40;      // send the "Overload" bit
  overload_flag = 0;    // reset "overload_flag"
  }
}

Sobald das overload flag gesetzt wurde, können Daten an die USART 
gesendet werden. Müsste meiner Meinung so jetzt stimmen?

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.