Forum: Compiler & IDEs Interrupt mit Overflow Timer


von DPlöching (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich möchte Testweise zum Interrupt einen Atmega 168 Controller so 
Programmieren das auf dem Display von 100 nach oben gezählt wird.
Folgenden Code habe ich programmiert, jedoch funktioniert mein 
gewünschtes Ergebnis nicht.
Woran könnte das liegen?
Die Interrupt Routine wird anscheinend nicht ausgeführt.

von Karl H. (kbuchegg)


Lesenswert?

1
volatile int i;

und das 'int' solltest du dir nochmal ganz genau überlegen. Wenn es 
nicht notwendig ist, benutzt man kein int. Und in dem Fall schon gleich 
gar nicht, denn dann wird das Thema gleich nochmal komplizierter, weil 
dann zusätzlich auch noch atomarer Zugriff sicher gestellt sein muss.

FAQ: Was hat es mit volatile auf sich

von Karl H. (kbuchegg)


Lesenswert?

Und poste deinen Code nächstes mal als normale Programmdatei. Du kannst 
dein C-File ruhig problemlos hier anhängen.

In deinem Programm sind nämlich noch ein paar andere Dinge. Nur hab ich 
jetzt ehrlich gesagt keine Lust, die aus dem Bild abzutippen. Postest du 
dein Programm als stink normalen Text, dann nehm ich Strg-C und Strg-V 
um mir die relevanten Teile rauszuschneiden.

In Summe ist das für dich weniger Arbeit und für uns auch.

von DPlöching (Gast)


Angehängte Dateien:

Lesenswert?

okay danke,
hier wäre die c-datei

von Karl H. (kbuchegg)


Lesenswert?

Kurz gesagt, dreht sich dein Problem darum, dass du zwar innerhalb des 
abhängigen Teils vom if die Ausgabe machst, dort dann aber auch immer i 
auf 100 setzt.
Wird die Ausgabe gemacht (wegen dem if), dann nicht ohne vorher i auf 
100 gesetzt zu haben. Lässt du aber das i in Ruhe (weil der vom if 
abhängige Teil nicht genommen wird), so dass die ISR den Wert hochzählen 
könnte, dann wird auch keine Ausgabe gemacht (weil ja der if-Teil nie 
genommen wird).

von Dome (Gast)


Lesenswert?

Okay, die if-Schleife ist in diesem Fall nicht notwendig.
Aber wie kann ich die Variable so definieren das mit dem Interrupt 
gezählt werden kann?

von Karl (Gast)


Lesenswert?


von DPlöching (Gast)


Lesenswert?

Danke Karl, hilft mir enorm weiter!

von Karl H. (kbuchegg)


Lesenswert?

Na ja ein bischen nachdenken musst du schon auch selber.
Das sind 3 Baugruppen und ich stoss dich schon mit der Nase auf die 
Problemstellen.

Du hast
1
   wiederhole
2
   {
3
4
      wenn Taster gedrückt
5
      {
6
         setzte zaehler auf 100
7
8
         gib zaehler aus
9
      }
10
   }


Du willst aber
1
    wiederhole
2
    {
3
4
       wenn Taster gedrückt
5
       {
6
          setze zaehler auf 100
7
       }
8
9
       gib zaehler aus
10
    }


denn die Ausgabe muss ja auch dann erfolgen, wenn der Taster nicht 
gedrückt ist. Schliesslich verändert ja die Interrupt Routine auch den 
Zaehler. Und das möchtest du ja auch auf der Anzeige sehen. Also darf 
die Ausgabe nicht davon abhängen, ob die Taste gedrückt ist oder nicht.

Das die Variable volatile sein muss, hab ich dir ja schon gesagt.
Also rann ans Werk und die Logik des Programms verändern.

von DPlöching (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe das Programm jetzt folgendermaßen geändert,
der Interrupt funktioniert jedoch immer noch nicht :-(

von Karl H. (kbuchegg)


Lesenswert?

>   TCCR0A = (1<<CS02);        //TIMER definieren


Das CS02 Bit ist im Register TCCR0B und nicht TCCR0A.

> der Interrupt funktioniert jedoch immer noch nicht :-(

Schon wieder die falsche Diagnose.
Dein Timer läuft nicht, weil du keinen Vorteiler gesetzt hast.
Hat der Timer den erst mal, dann funktioniert der Interrupt wunderbar.

von DPlöching (Gast)


Lesenswert?

Okay, aber mit
>           TCCR0B = (1<<CS02);

ist der Vorteiler gesetzt?

Funktioniert aber trotzdem leider nicht.

von Karl H. (kbuchegg)


Lesenswert?

DPlöching schrieb:
> Okay, aber mit
>>           TCCR0B = (1<<CS02);
>
> ist der Vorteiler gesetzt?

Ähm.
Schau halt ins Datenblatt. Dazu gibt es das ja.
Da ist eine schöne Tabelle, in der die Vorteiler aufgeführt sind und 
welche Bits dafür jeweils zu setzen sind. Dann zu den Registern scrollen 
und nachsehen welches Bit in welchem Register sitzt.

> Funktioniert aber trotzdem leider nicht.

Bei mir in der Simulation aber schon.
Gut, ich hab den LCD-Teil rausgeworfen, weil ich den hier nicht 
simulieren kann. Der Timer läuft, die ISR wird aufgerufen, die Variable 
i zählt hoch. Alles so wie es sein soll.

von Karl H. (kbuchegg)


Lesenswert?

> if ( PINB & (1<<0))

Was hängt da eigentlich drann?

Wenn das ein Taster in der üblichen Verschaltung (Taster schaltet auf 
Masse durch, interner Pullup aktiviert) ist, dann ist das klar. Bei 
jedem Durchlauf durch die Hauptschleife wird i wieder auf 100 gesetzt. 
Da wird sich die ISR schwer tun, die Variable hochzuzählen.

Ich kann dich nur warnen: Dinge wie Tastenabfragen musst du im Schlaf 
beherrschen! Sonst kommst du nie weiter.

Schmeiss doch den ganzen Dreck mal raus. Alles was für deinen Test nicht 
absolut notwendig ist, wirfst du aus dem Programm raus. Das sind alles 
erst mal Fehlerquellen, in denen du Fehler einbaust, die du selbst nicht 
mehr findest und korrigieren kannst. Brauchst du einen Taster um den 
Timer, bzw. den Overflow Mechanismus zu testen? Nein, brauchst du nicht. 
Also weg damit.

Und PS: Um einen unsigned Wert auszugeben (wie zb uint8_t) heißt die 
Funktion dafür utoa und nicht itoa. OK; Spielt jetzt bei dir zufällig 
keine große Rolle. Trotzdem ist es gut, da ein wenig sorgfältig zu sein.
1
int main()
2
{
3
4
....
5
  i = 100;
6
7
  while(1)
8
  {
9
    char Buffer[20];
10
    utoa( i, Buffer, 10 );
11
12
    lcd_setcursor( 0, 2 );
13
    lcd_string( Buffer );    //Ausgabe LCD
14
  }
15
}

von DPlöching (Gast)


Lesenswert?

Jetzt funktioniert das Zählen,
habe jetzt die zweite Ausgabe auf dem Display, also
>    lcd_string("uSiemens");
rausgenommen und jetzt funktionierts.
Danke für die Hilfe!

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.