mikrocontroller.net

Forum: Compiler & IDEs Codeoptimierungsproblem


Autor: Polat (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}}

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil Du bereits den allerersten Punkt der FAQ nicht
gelesen hast. ;-)

Die Frage kommt nun wirklich in der Woche dreimal...

http://savannah.nongnu.org/download/avr-libc/doc/a...

Von dort zur FAQ weiterklicken (den Rest aber auch mal mit
lesen ;-).

Autor: Christian Schifferle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: mikki merten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Polat (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Polat (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.