Codeoptimierungsproblem

Gast #6619
Lesenswert?
• ▲
▼
Hallo zusammen,
kann mir jemand sagen warum der Code nicht funktioniert??

Problem ist, dass die Interruptroutine mehrmals ausgeführt wird, obwohl 
ich nur ein Zeichen über die Serielle Schnittstelle sende.

Meine Vermutung war, dass die Variable "UART_ReceivedChar " nicht 
richtig funktioniert obwohl es als volatile deklariert ist 
(Codeoptimierung)
deshalb die Frage auch wie ich die Codeoptimierung ausschalten kann.

SIGNAL(SIG_UART_RECV)
{
    /* Indicate that the UART has received a character */
    UART_RxChar = inp(UDR);
    gemessen_2 = (gemessen_2 + 1);
    UART_ReceivedChar = 1;
    cli();

    /* Store received character */

}


int main (void) {
 for (;;) {
 sei();

    while(!UART_ReceivedChar)
    UART_ReceivedChar = 0;
    UartPrintF ("test %05d ", gemessen_2);
    gemessen_2=0;
}}
Gast #6621
Lesenswert?
• ▲
▼
Warum schaltest du die Interrups immer an und aus.
Es reicht, wenn du den Befehl sei() vor der for-Schleife einbaust. Das 
cli() in der Interrupt-Routine kannst du weglassen.
Ich gehe mal davon aus, dass du den UART Receive Interrupt aktiviert 
hast.

Gruss
Christian
#6622
Lesenswert?
• ▲
▼
cli(); im Interrupt ist Blödsinn, das ist doch schon aus.

Es sei denn der Compiler ist so verrückt und schummelt Dir im 
Interrupteintritt ein "SEI" mit rein.

Dann muß es nämlich krachen, da das Interruptflag erst beim Lesen von 
UDR gelöscht wird. Und daher ruft sich der Interrupt nach dem 
eingeschmuggelten "SEI" einfach wieder selber auf.

Sieh Dir doch mal das Assemblerlisting an, ob da ein fehlerhaftes "SEI" 
mit drin ist.


Peter
Gast #6623
Lesenswert?
• ▲
▼
@polat
Du solltest dich mal mit dem UART Status-Register UCSRA bzw. USR 
beschäftigen. Der RX Interrupt wird ja auch ausgeführt, wenn ungültige 
oder gar kein Zeichen im Receive-Buffer steht. Mal ganz abgesehen von 
dieser unsinnigen CLI/SEI Sequenz.
Gast #6624
Lesenswert?
• ▲
▼
@Peter: nein, der Compiler macht das nicht freiwillig.
Eine mit SIGNAL() deklarierte ISR läßt die Interrupts
abgeschaltet.  Lediglich eine mit INTERRUPT() deklarierte
würde sie einschalten.  RTFdoc.
Gast #6625
Lesenswert?
• ▲
▼
Hallo nochmal,
Danke, dass ihr euch das Problem angeschaut habt.
Ich habe aber inzwischen heraus gefunden, dass ich nach der While 
schleife keine Geschweifte-klammern hatte und dadurch eben die nächste 
Anweisung (UART_ReceivedChar = 0;) immer ausgeführt wurde.Mit Klammern 
siehe unten funktioniers.

while(!UART_ReceivedChar) {}
    UART_ReceivedChar = 0;

<<Warum schaltest du die Interrups immer an und aus.
Die For-Schleife zählt eigentlich eine Variable hoch und in der Zeit 
darf keine Interrupt ausgelöst werden.

Nochmal Danke!
Gast #6626
Lesenswert?
• ▲
▼
<<Warum schaltest du die Interrups immer an und aus?

also jetzt habe ich den Code nochmal angeschaut, und würde gern wissen, 
wie Ich alle interrupts in der Zeitkritischen Pfase (mein For Schleife) 
ausschalten kann.Würde der Code unten funktionieren?

int main (void) {

 sei();
   for (;;) {

    sei();
          while(!UART_ReceivedChar){}
          UART_ReceivedChar = 0;
    cli();
          For (......){ Zähler++;
          }
   }
}

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.