Hallo, folgender Sachverhalt: Ich nutze den Timer1 des Atmega128 als Counter (Counter1). Dieser zählt externe Impulse (ca. 1-2Khz). Wenn ein gewisser Schwellwert erreicht ist (z.b. 20), so wird der TIMER1_COMPA_vect Interrupt ausgelöst, der wiederum eine Variable X hochzählt (bzw. runterzählt). Dann nutze ich die Int2 und Int3 Eingänge als externe Interrupts. Diese dienen dazu, die Zählrichtung zu ändern. Sprich: Int2 sorgt dafür, dass die Variable X hochgezählt wird, Int3 sorgt dafür, dass die Variable X runtergezählt wird. Das alles funktioniert auch problemlos. Jedoch ergibt sich beim Zählrichtungswechsel eine Verfälschung der Ergebnisse. Folgende Ausgangssituation: Die Variable X wird hochgezählt, der Counter1 Zählerstand ist z.b. gerade bei 18. Der Interrupt soll bei 20 auslösen und damit die Variable X incrementieren. Nun kommt Int3, so dass die Variable X von nun an runter gezählt werden soll. Da der Counter1 seine Zählrichtung nicht ändern kann, zählt er also beim nächsten einkommenden Impuls auf 19, dann 20 und löst den interrupt aus, der die Variable X um 1 dekrementiert. Jedoch soll die Variable X erst nach 18 Impulsen decrementiert werden, da die 18 Impulse ja zuvor hochgezählt wurden. Meine Lösung wäre folgende: Bei Int3 weise ich dem Vergleichsregister OCR1A den wert von TCNT1 zu und setze TCNT1 anschließend zurück auf 0. Dann zählt der Zähler bis 18 und dekrementiert dann Variable X: tmp_sreg = SREG; cli(); if (TCNT1 >=0){ temp_counter=TCNT1; TCNT1=0; OCR1A=temp_counter; } SREG = tmp_sreg; Funktioniert aber nicht. Kann ich das so nicht machen?
bd schrieb: > Meine Lösung wäre folgende: Bei Int3 weise ich dem Vergleichsregister > OCR1A den wert von TCNT1 zu und setze TCNT1 anschließend zurück auf 0. > Dann zählt der Zähler bis 18 und dekrementiert dann Variable X: Aber dann musst du danach nicht vergessen dein OCR1A Wert wieder auf 20 zurückzustellen. Meine Lösung wäre TCNT auf 2 (20-18) zu stellen und OCR1A nicht anzufassen:
1 | tmp_sreg = SREG; |
2 | cli(); |
3 | if (TCNT1 >=0){ |
4 | TCNT1 = OCR1A - TCNT1; |
5 | }
|
6 | SREG = tmp_sreg; |
DISCLAIMER: Keine Ahnung ob das funktioniert 8-) EDIT: Und 2 Interrupts für die Drehrichtung ist murks. Du brauchst nur einen, um Richtung zu wechseln. :-)
:
Bearbeitet durch User
bd schrieb: > Jedoch ergibt sich beim Zählrichtungswechsel eine Verfälschung der > Ergebnisse. Nein, alles macht genau, was du ihm gesagt hast, was es machen soll. Wenn du das Ergebnis für falsch hältst, hast du der Sache einfach nur nicht gesagt, was du tatsächlich machen willst. Sowas nennt man einen logischen Programmierfehler. Nix Schlimmes, machen alle (zumindest hin und wieder). Das Problem bei dir ist halt nur: du bist nichtmal in der Lage, formal auszudrücken, was du eigentlich willst. Das ist natürlich eine ganz schlechte Voraussetzung dafür, deine Intention in so etwas Formalem wie einer Programmiersprache korrekt auszudrücken. Da hilft nur eins wirklich: Lernen. Garnicht mal so sehr das Programmieren, sondern einfach nur logisch zu denken und das Problem formal logisch korrekt zu formulieren. Konkret geht es hier eigentlich nur um das Problem, TCNTx und OCRx nach eine Anweisung zur Zählrichtungsänderung korrekt vorzubesetzen, damit der OC-Interrupt im gewünschten Moment erfolgt. Das ist trivialste Mathematik. 3. Klasse oder so, Rechnen mit "Ganzen Zahlen"... Und übrigens: Sehr sinnvoll ist deine "Lösung" insgesamt sowieso nicht. Denn bei dem, was du eigentlich willst, bringt die Verwendung der Hardware eigentlich nur Nachteile. Sprich: es wäre viel einfacher, das rein in Software umzusetzen, insbesondere wohl für dich... Warum versuchst du es also in Hardware? Da braucht man nicht lange raten: Da ist noch anderer Code im Spiel, der quasi "parallel" ablaufen soll, aber entgegen jeder Warnung der Erwachsenen mit Delays programmiert wurde... Stimmt's oder hab' ich Recht?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.