Forum: Compiler & IDEs Interrupt Verständnis Frage


von Daniel (Gast)


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

von MasterFX (Gast)


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.

von MasterFX (Gast)


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.

von Wolfgang Horn (Gast)


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

von Hugo Bossard (Gast)


Lesenswert?

Ich denke das ist die Geschichte mit dem "volatile".

von johnny.m (Gast)


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!

von Daniel (Gast)


Angehängte Dateien:

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

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von Wolfgang Horn (Gast)


Lesenswert?

Hi, Daniel,

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

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

Ciao
Wolfgang Horn

von Daniel (Gast)


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

von Wolfgang Horn (Gast)


Lesenswert?

Hi, Daniel,

Danke für die Rückmeldung.

Gerade die einfachsten Problemchen sind die ärgerlichsten.

Ciao
Wolfgang Horn

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.