www.mikrocontroller.net

Forum: Compiler & IDEs Verständnisproblem


Autor: Sandmännchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wollte mal wieder ein wenig herumspielen mit WinAVR udn ein kleines
Programm schreiben, welches folgendermaßen aussieht

(die verwendete UART.c hab ich nicht inkludiert, da diese mit dem
Problem denke ich nichts zu tun hat)


int main(void)
{
  init_uart();
  unsigned int wert,overflows,timerstand = 0;
  unsigned char buffer[10];


  uart_puts("Controller online.....  OK\n\r");

  TCCR0 = _BV(CS00) | _BV(CS02);  //1024 prescaler
  TIMSK = _BV(TOIE0);       //Timer0 Overflow Interrupt Enable
  sei(); // enable all interrupts

  while(1)
  {
    if(wert == 10)
    {
      uart_puts("Timerstand:");
      itoa(timerstand,buffer,10);
      uart_puts(buffer);
      wert = 0;
    }


  }



  ISR(TIMER0_OVF_vect)
  {

      overflows++;
      timerstand = TCNT0;

      if(overflows == 256)
      {
        wert++;
        uart_puts("Wert wurde um 1 erhöht!");
      }

  }

}


Das ich hier den Timerstand ausgebe, ist natürlich Unsinn und hat keine
spezielle Funktion. SOllte nur zum Testn sein..

Im main programm sollte in der Endlosschleife der leztzte erfasste
TImerstand rausgesendet werden.
Die if  Abfrage in der ISR und im Main Programm sollten nur eine
Verzögerung bewirken, d.h. das der Timer öfter überlaufen muss, um ein
wenig Zeit zu gewinnen....


Tatsache ist, dass der Timerstand NIE ausgegeben wird, das Programm
hängt jedoch in einer Endlosschleife, wo es nicht sollte.. denn es wird
der String "Controller online.....  OK    (sollte nur einmal bei Beginn
gesendet werden) in einer Endlosschleife rausgeschickt und sonst gar
nichts...

Ich nehme an, es ist wieder ein typischer Anfängerfehler, jedoch komm
ich nicht dahinter...

Danke im Voraus!

Autor: Sandmännchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.: Ich habe den Verdacht, dass da irgendwas wegoptimiert wird?! Muss
ich da irgendwo ein "static volatile" oder sowas in der Art
benutzen??

Und warum läuft der in einer "anderen" Endlosschleife?!

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"timerstand" sollte in der Tat volatile sein, da er zwischen einer
ISR
und dem Hauptprogramm Daten austauscht.

Du hast versucht, eine ISR innerhalb einer Funktion geschachtelt zu
definieren.  Bitte definiere sie auf der obersten Ebene.

Autor: Sandmännchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine ISR innerhalb einer Funktion geschachtelt zu definieren? Wie ganau
meinst du das?

Das die ISR in der Funktion main() steht ?
Sollte die ISR vor dem main() stehen?

Was ich noch wissen möchte, in welcher Reihenfolge beginnt der Compiler
beim Übersetzen? Ich dachte immer bei main().....

Denn wenn ich z.B.: die ISR

ISR(interrupt)
{

...

}

Außerhalb von main() schreibe, bekomme ich Fehler, dass er bestimmte
Variablen nicht kennt... Wenn das main Programm aber schon übersetzt
wurde, müsste er die doch Variablen kennen....?!

Wie ist das dann, wennd die ISR vor dem Hauptprogramm steht?!

Danke!

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja du solltest sie vor der Main definieren. Und damit er auch dann die
Variablen kennt, definiere sie als globale volatile Variablen.

Eigentlich sollte man doch alle Funktionen vor der Main definieren oder
nicht?

Gruß Marian

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Variablen, die im IR benutzt werden, müssen global declariert werden,
d.h. sie müssen ausserhalb einer Funktion (in Deinem Fall main) stehen.

Variablen, die innerhalb einer Funktion stehen, werden auf dem Stack
angelegt. Die Stackadresse kann aber bei jedem Aufruf der Funktion
unterschiedlich sein. Deine Interrupt-Funktion "weiss" also nicht, an
welcher Adresse die Variable steht.

Was bei Dir auch fehlt, ist die Declaration als volatile. Siehe diverse
BEschreibungen dazu hier im Forum.


Probier Deinen Code so umzubauen:

//*** Variablendeklaration ausserhalb einer Funktion: ****
volatile unsigned int wert,overflows,timerstand = 0;
volatile unsigned char buffer[10];

int main(void)
{ .... }

ISR(TIMER0_OVF_vect)
{ .... }


Gruß, Stefan

Autor: Winne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR im Besonderen, sonst kann man sie nur während der Laufzeit der
Funktion in der sie definiert sind erreichen. Das dürfte zum sicheren
Absturtz führen , wenn der IRQ mal eben vorher vorbeikommt.
;-)

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin noch nie auf die Idee gekommen, Funktionen innerhalb von Funktionen
zu definieren.

Wer mit Assembler angefangen hat, macht sowas nicht, denn da gehts
definitiv schief.

Wußte garnicht, daß sowas überhaupt geht.

Warscheinlich wird dann die Funktion nicht mehr als Interrupthandler
erkannt, denn für einen freigegebenen Interrupt ohne Handler ist es
typisch, daß das Programm immer wieder von vorne anfängt.


"Was ich noch wissen möchte, in welcher Reihenfolge beginnt der
Compiler beim Übersetzen? Ich dachte immer bei main()....."

Nein.

Er übersetzt immer von oben nach unten und von links nach rechts bzw.
entsprechend den Vorrangregeln.


Peter

Autor: Sandmännchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, alles klar...Danke für alle Antworten, werde das heute ändern und
nochmal probieren!

Thx!

Autor: Heinrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, nach diesen Umstellungen/Korrekturen läuft alles so , wie ich mir
das gedacht habe!

Jetzt werd ich mich noch damit beschäftigen, wie ich genaue delays
(z.B.: genau eine schöne sekunde lang) erzeuge und was für timermodi es
alles gibt bzw. wo man die einsetzt! Das mit dem capture/compare oder
CTC mode ist mir noch zu hoch ;-)

Ein Danke an alle

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.