www.mikrocontroller.net

Forum: Compiler & IDEs Interrupt Verständnis Frage


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Nach Stundenlagem Suchen und vielen Testläufen habe ich jetzt nie Nase
voll und schreib euch :).

Also bin am Input Capture versuchen. Will die Zeit zwischen zwei
Impulsen aus einem Sensor. Doch was ich auch versuche er springt
einfach nicht in die Interrupt Routine.

PROG:

#include <stdlib.h>
#include <lcd.h>
#include <lcd.c>
#include <avr/interrupt.h>
#include <avr/signal.h>

unsigned int time = 0; //
unsigned int temp = 0; //
char buffer[20]; //buffer

SIGNAL(SIG_INPUT_CAPTURE1)
{
  temp = ICR1;
  //TCNT1 = 0;
}
void lcd(void)
{
  itoa( time , buffer, 10); //wandle integer in string
  lcd_gotoxy(0,1); // gehe zu LCD Position X Y
  lcd_puts(buffer); //schreibe auf den LCD den Inhalt von Var buffer
}

int main(void)
{
  TCCR1B |= (1<<CS10) | (1<<CS12); // Timer CPU-Takt / 1024

  lcd_init(LCD_DISP_ON);

  lcd_clrscr();
  lcd_init(LCD_DISP_ON);

  lcd_puts("Impulszeit\n");

  sei();

  for(;;)
  {
    time = temp;


    lcd(); // gehe in die Funktion LCD


  }
}

So da ist das übel. GCC Compeliert auch alles ohne zu mucken. Der LCD
zeigt auch den Text aber die Zahl verändert sich nicht. Das bedeutet er
geht nicht in die Routine.

MFG
Daniel

Autor: MasterFX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wie es für mich aussieht willst du das ding als Counter betreiben. Du
hast aber einenfach nen Teiler von 1024 eingestellt und nicht als
external Source Konfiguriert. Da kannst du auf den Pin geben was du
willst, der Wert wird nur durch den Takt/1024 verändert.

Autor: MasterFX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es heisst natürlich "einfach"
Wenn die Konfiguration wie beim Mega32 ist müsstest du
CS12, CS11 und CS10 auf 110 oder 111 setzen. Und das Timer/Counter
Interrupt Mask Register müsstest du auch noch konfigurieren.

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, Daniel,

Dein Listing ist unvollständig.
Bitte poste auch den Teil, in dem Du den Timer 1 initialisierst und
unter anderem das Bit TICIE1 setzt.

Ciao
Wolfgang Horn

Autor: Hugo Bossard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke das ist die Geschichte mit dem "volatile".

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich denke das ist die Geschichte mit dem "volatile".

Das denke ich auch.

Außerdem solltest Du bei Gelegenheit mal ne neue AVR-GCC-Version
installieren. SIGNAL ist veraltet!

Autor: Daniel (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal Danke für die ganzen und schnellen Antworten. Wollte früher
schreiben aber muss leider im mom von 2-10 Arbeiten (Spätschicht).

Wollte eigentlich die Zeit zwischen 2 Impulsen deswegen dachte ich ich
mache /1024 damit der Timer nicht so durchrennt.

Danke für den Tip wegen TICIE1 hab das jetzt eingefügt. Leider tut sich
immer noch nix. Mehr tue ich auch nicht initen für Timer 1.

Die Version von AVR ist jetzt so ca. 1/2 Jahre alt. Ist SIGNAL
veraltet? Was nimmt man den Stattdessen?

Und jetzt die beste Frage was bedeutet "volatile" was hat es damit
auf sich? Hoffe ich nerve nicht mit der Frage.

Zum Schluss noch der aktuelle Code als anhang.

Zum abschluss

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne jetzt das Pgm gross analysiert zu haben:
volatile sagt dem Compiler, dass er eine Variable
aus der Optimierung rausnehmen soll. Die macht man deshalb,
da die Variable ihren Wert ändern kann, ohne dass der
Compiler das mitkriegen würde.

Beispiel:

  for(;;)
  {
    time = temp;
    lcd(); // gehe in die Funktion LCD
  }

Wenn der Compiler diese Schleife übersetzt, könnte er auf
die Idee kommen, sich mal anzusehen, wie den eigentlich temp
verwendet wird. Nun, innerhalb der Schleife wird temp
nicht verändert. In der Funktion lcd() wird temp auch
nicht verändert. Für den Compiler ist daher die Sache
klar: da temp nie verändert wird, ist es auch sinnlos
den Wert dieser Variablen jedesmal neu aus dem Speicher
zu holen. Er könnte daher auf die Idee kommen, diesen
Wert nur einmal, vor Betreten der Schleife zu holen,
irgendwo in der CPU zwischenzuspeichern und dann innerhalb
der Schleife immer mit diesem zwischengespeichertem
Wert zu arbeiten. Aus der CPU können Werte wesentlich
schneller abgerufen werden als aus dem Speicher. Daher
würde das durchaus Sinn machen.

Das temp innerhalb der Interrupt Service Routine verändert
wird, interessiert den Compiler an dieser Stelle nicht.
Eine Interrupt Service Routine ist auch nur eine Funktion.
Und augenscheinlich (für den Compiler) wird diese Funktion
innerhalb der Schleife nicht aufgerufen.
Das es allerdings ein Hintertürchen gibt, und diese Funktion
aufgerufen werden kann ohne dass der Compiler einen expliziten
Aufruf dafür im Code findet, das kann der Compiler nicht wissen.
Daher helfen wir ihm ein bischen und deklarieren:

volatile unsigned int temp = 0;

und das volatile heist: Lieber Compiler, die Variable temp
kann ihren Wert acuh ändern, ohne dass du das im Code ablesen
kannst. Halte dich also mit möglichen Optimierungen erst mal
etwas zurück.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Version von AVR ist jetzt so ca. 1/2 Jahre alt. Ist SIGNAL
> veraltet? Was nimmt man den Stattdessen?

1) Es gibt eine neuere Version.
2) Schau ins AVR-gcc Tutorial. Da ist ein Abschnitt drüber.

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, Daniel,

streiche:
TIFR |= (1<<TICIE1); // Input Capture Interrupt Aktiviert

setze:
TIMSK |= (1<<TICIE1); // Input Capture Interrupt Aktiviert

Ciao
Wolfgang Horn

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also hab das mal getestet Wolfgang und es funktioniert. :) Wuste das es
nur was ganz kleines ist aber hab es leider nicht alleine gefunden.
Vielen dank jetzt bin ich schonmal wieder ein ganzes Stück weiter.

@Karl dann werde ich mal die neue Version runterladen. Mal gucken was
sich so getan hat.

Vielen dank nochmal an alle die gepostet haben.

Gruß Daniel

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, Daniel,

Danke für die Rückmeldung.

Gerade die einfachsten Problemchen sind die ärgerlichsten.

Ciao
Wolfgang Horn

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.