Forum: Mikrocontroller und Digitale Elektronik Interrupts, wie muss ich das hier machen


von reflection (Gast)


Lesenswert?

Salu zusammen

Irgendwie drängen sich immer noch Fragen auf, ich weiss nicht genau ob 
ich da grundsätzlich einen Überlegungsfehler drin habe, oder ob es so 
einfach nicht funktionieren kann.

Folgendes:

Ich habe eine Interruptroutine die angesprochen wird wenn Zeichen im 
Uart RX reinkommen:

unsigned char nmeabuffer[512];

interrupt (UART1RX_VECTOR) usart1_rx(void)
    {
       _DINT();
          {
          nmeabuffer[j] = RXBUF1;
           j++;
       }
       _EINT();
    }

Im main habe ich dann einfach irgendwo gefragt

if(j > 505)
{
....
}

Nun ist mir das immer abgestürzt.

Habe es nun folgendermassen gelöst:

interrupt (UART1RX_VECTOR) usart1_rx(void)
    {
       _DINT();
       if(j < 505)
       {
          nmeabuffer[j] = RXBUF1;
           j++;
       }
       _EINT();
    }

if (j >= 504)
  {
  ....
         }

das läuft, aber ich frage mich ob das so richtig ist. Eigentlich möchte 
ich nicht irgendwann nachdem die 505 Zeichen im nmeabuffer erreicht sind 
den buffer verarbeiten sondern DIREKT nachdem er voll ist. Wie löse ich 
das? Ich programmiere auf einem MSP430 mit mspgcc

Danke schonmal im Voraus

Greets

von Ronny (Gast)


Lesenswert?

Ich vermute mal,das j ein Integer ist. Sonst wären nämlich nur 256 Byte 
im Puffer ansprechbar.

Lösung 1:

Woher weiß der Interrupt, dass dein Puffer voll ist? Richtig,garnicht. 
Und so wird munter alles Überschrieben was darin und dahinter im 
Speicher steht.

Lösung 2:

Das geht, da nur in den Speicher geschrieben wird, wenn j nicht ein 
Element hinter dem Array indiziert.

Grundsätzlich solltest du den Zugriff auf j in main() verriegeln. Was 
passiert denn, wenn in main gerade auf j zugegriffen wird und in mitten 
der Operation ein Interrupt auftritt der j hochzählt? Dann hast du 
vielleicht das niedere Byte von j angefangen zu verarbeiten und dann 
kommt der Interrupt und schreibt einen neuen Wert in j. Dann wären LOW 
und High-Part von j inkonsitent.

Das mit dem vollen Puffer kann man auch über ein Flag lösen, dass im 
Interrupt gesetzt wird, wenn der Puffer voll ist. Dann kann man anhand 
des Flags auch im Isr sehen, dass keine Daten mehr in den Puffer 
geschrieben werden dürfen. Angenehmer Nebeneffekt: Ein Byte-Zugriff muss 
dann auch nicht zwingend verriegelt werden.

von Falk B. (falk)


Lesenswert?

Was soll denn _DINT und _EINT in einem Interrupt? Das ist Unsinn und 
ggf. auch schädlich. Lass es weg!

MFG
Falk

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.