Forum: Mikrocontroller und Digitale Elektronik ATmega128 u Timer2


von Niels H. (monarch35)


Lesenswert?

Hallo Allerseits,

ich mache irgendwo einen groben Denkfehler bei der Programmierung eines 
Timer2_Overflow interrupts und find ihn nicht. Ziel des Ganzen soll es 
sein, den auf 8Mhz getakteten ATmega128 den Timer2 so zu programmieren, 
das ich eine routine ziemlich genau 1200mal pro sekunde aufrufe.

Über den TCCR2 wähle ich zunächst einen 8er von  f/io Prescaler, so das 
ich in der Vorstufe schonmal einen 1Mhz Takt für TCNT2 erhalten sollte. 
Nun lade ich TCNT2 mit dem Wert 13 vor überlauf (256-13) in der 
Initialisierung und bei jedem Interruptaufruf. Ein Softwareteiler, der 
bis 64 zählt, sollte nun meine gewünschnten 1200ints/s (ca, muss nicht 
genau sein) bringen. Aufstellnung:

8.000.000 Hz interner RCTakt
1.000.000 Hz nach prescaler (TCCR2=CS21)
   76.923 Hz nach Autoreload (TCNT2=(256-13))
    1.200 Hz nach Software (zähler bis 64)

Der Code funktioniert auch, nur der Takt, mit dem meine Routine 
aufgerufen wird, ist doppelt so schnell (2400ints/s), als von mir o.g. 
berechnet.

Ansich kein Problem; ich setzte einfach den Softwarezähler auf 128 und 
gut ist. Das Problem, das ich damit habe: ich verstehs nicht. Der 
Interne RC-Resonator kann unmöglich mit 16Mhz laufen und es gäbe auch 
sonst nirgens eine 16Mhz quelle. Die lfuse steht eindeutig auf 8Mhz.

von Johannes M. (johnny-m)


Lesenswert?

>    76.923 Hz nach Autoreload (TCNT2=(256-13))
Autorelaod gibts bei den AVRs überhaupt nicht. Und wenn Du den 
Reload-Wert in der ISR von Hand da reinschreibst: Lass es. Benutze die 
Compare-Einheit des Timers dafür (entweder CTC-Modus oder Timer einfach 
durchlaufen lassen und nur in der Compare-ISR zum Compare-Register die 
Zykluszahl addieren).

Ansonsten kann ich mir nicht vorstellen, was dazu führen könnte, dass 
doppelt so viele Interrrupts kommen wie berechnet...

von Niels H. (monarch35)


Lesenswert?

Und ich dachte noch "schick gleich quelltext mit". Man fällt aber auch 
immer wieder drauf rein, oder?

#define TC2Prescale CS21
TCCR2 = TC2Prescale

Na, wo ist das fehlerchen? :)

von Johannes M. (johnny-m)


Lesenswert?

Niels Hüsken wrote:
> Na, wo ist das fehlerchen? :)
Ich sehe mindstens zwei Fehler. Einer davon ist ein Syntaxfehler durch 
ein fehlendes Semikolon. Beim anderen kann man sich aussuchen, was man 
haben möchte. Entweder ist das #define unsinnig oder die Zuweisung...

von Niels H. (monarch35)


Lesenswert?

abgesehen von dem fehlenden Semicolon...

CS21 representiert per define die BitNUMMER. Um das entsprechende Bit zu 
setzen, müsste es entweder

#define TC2Prescale _BV(CS21)
oder
#define TC2Prescale (1<<(CS21))

heissen...

Aber es freud' mich zu sehen, daß Andere das auch übersehen und nicht 
nur ich so schäl bin :)

von Johannes M. (johnny-m)


Lesenswert?

Niels Hüsken wrote:
> CS21 representiert per define die BitNUMMER. Um das entsprechende Bit zu
> setzen, müsste es entweder
>
> #define TC2Prescale _BV(CS21)
> oder
> #define TC2Prescale (1<<(CS21))
>
> heissen...
Das ist mir schon klar. Oder aber das #define so lassen wie es ist und
1
TCCR2 = 1 << TC2Prescale;
schreiben. Genauso, wie ich es oben angedeutet habe. Eine der beiden 
Zeilen ist eben falsch. Kannst Dir aussuchen, welche der beiden.

> Aber es freud' mich zu sehen, daß Andere das auch übersehen und nicht
> nur ich so schäl bin :)
Wer hat denn hier was übersehen? Wenn Du keinerlei Code postest, dann 
kann man in dem Code auch nichts übersehen. Im Moment bist DU hier der 
einzige, der das übersehen hat!

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.