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.
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
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.
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).
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.
> 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.
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.
> 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.
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!