PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Konfiguration: Timer als Counter gesucht



robodriver
09.02.2008, 13:53
Hallo leute,

ich tüftle hier momentan an etwas, wo ich net so ganz auf die korrekte Kinfiguration des Timers komme. Vielleicht könnt ihr mir ja weiter helfen.

Ich nutze ein Mega168.
Am Eingang T1 hängt ein Radencoder.

Nun brauche ich folgendes Szenario: Immer bei steigender Flanke an T1 soll der Counter um eins erhöht werden.
Wenn dann der Counter bei 255 ist, dann soll ein Interrupt ausgelöst werden.

Ich hab den Timer jetzt wie folgt konfiguriert:



Config Timer1 = Counter , Edge = Rising , Capture Edge = Rising , Compare A = Toggle

Compare1a = 255

On Oc1a Toggle_led
Enable Interrupts

Tcnt1l = 1



Aber diese Konfiguration muss irgendwie falsch sein.
Denn der Interrupt wird nie ausgelöst.
Zu Diagnose hab ich mir auf einem Display einfach mal den Tcnt1l-Wert anzeigen lassen. und dieser zählt einwandfrei hoch bis 255 und danach geht er auf 0.

Wenn ich den Oc1a-Pin mal mit dem Messgerät messe, dann beobachte ich folgendes: Der Pin ist anfangs auf 0V
Wenn der Counter dann auf 255 springt, geht der Pin auf 5V.
Allerdings bleibt er dann auf ewig auf 5V... Egal wie oft der Counter noch über die 255 springt.

Ich vermute mal das da auch irgendwo der Fehler liegt: Denn der Interrupt wird ja nur bei fallender Flanke ausgelöst...

Komm da irgendwie nimmer weiter...

Hoffe mir kann jemand helfen.

Danke schonmal im Voraus.

Gruß Robodriver

Sauerbruch
10.02.2008, 12:15
Hast Du denn den Output-Compare-Interrupt auch aktiviert? Das kannst Du überprüfen, indem Du Dir den Inhalt des TIMSK1-Registers ansiehst. Um genau zu sein, muss das Bit TIMSK1.1 gesetzt sein.

Ist dieser Interrupt nämlich nicht aktiviert, passiert folgendes: Der Zähler zählt hoch, beim OCR1A-Wert von 255 wird der OC1A-Pin getoggelt und geht auf High. Das Low-Byte vom Timer1 zählt von 255 natürlich auf 0 weiter (kann ja gar nicht anders bei 8 bit) - aber die kompletten 16 Bits des Timer1 zählen brav weiter: 256, 257, 258,... bis 65535. Und deshalb gibt´s erstmal ganz, ganz lange keinen Output Compare-Match mehr - und OC1A bleibt die ganze Zeit High. Und so sieht´s im Moment doch aus, oder?

Also:

- Output-Compare-Interrupt aktivieren
- In der der Output-Compare-ISR den ganzen (!) Timer auf 0 setzen, nicht nur das Low-Byte

Gutes Gelingen!

robodriver
10.02.2008, 12:28
Hey, du hast recht.
Da fehlt der Befehl
Enable Oc1a

Wusste vorher gar net das es einen solchen gibt...
So funktionierts jetzt auf jeden Fall.

Hab aber mittlerweile noch eine andere Lösung gefunden:
Man kann einen Interrupt auf den Timer Overflow legen. der kommt auch immer wenn der Timer von 255 auf 0 springt (vorrausgesetzt TCNT1H ist auf 255) Somit setze ich jetzt einfach die High-Byte auf 255 und das Low-Byte auf 0.
Nach 255 Incrementen kommt dann der Overflow und somit mein Interrupt.
Unter Bascom gibt es dafür noch einen bequemen Befehle:
Load Timer1, 255
Dann berechnet der Compiler alles so, das nach 255 Incrementen ein Interrupt erfolgt.
Das ganze hat den Riesen Vorteil, das ich nun auch auf dem Timer 0 indirekt einen "Compare" habe. Bzw. richtiger ausgedrückt: Einen Interrupt nach einer bestimmten Anzahl an Incrementen.
(In meiner Anwendung benötige ich auch die Fälle, das der Interrupt nach z.B. 100 Incrementen erfolgen soll. Desshalb hatte ich die Idee mit dem Compare...

Gruß Robodriver

Sauerbruch
10.02.2008, 12:41
Alle Interrupts sind erst dann aktiv, wenn die globale Interrupt-Freigabe (enable Interrupts) und die spezielle Freigabe des jeweiligen Interrupts erfolgt ist. Wenn Du mit dem Overflow-Interrupt arbeiten möchtest (auch ´ne gute Lösung), musst du entsprechend "enable timer1" schreiben, um diesen Interrupt zu aktivieren.

robodriver
10.02.2008, 12:42
Ja genau. Das hab ich auch so gemacht jetzt und es funktioniert ja supi :)

danke