Ist das Datenblatt des AVR ATmega32 falsch?

Ich verwende derzeit einen ATmega32, um die Zeit zu halten, also habe ich das Datenblatt sorgfältig gelesen und den Timer 1 so konfiguriert, dass er jede Sekunde einen Interrupt generiert.

Gemäß der folgenden Formel auf dem Datenblatt sollte ich mit einem 16-MHz-Takt, einem Vorteiler von 256 und OCR1A = 31249 eine Frequenz von 1 Hz im CTC-Modus erhalten:

F Ö C N A = F C l k _ ICH / Ö 2 N ( 1 + Ö C R N A )

Diese Formel ist auf Seite 99 des ATmega32-Datenblatts verfügbar .

Ich habe Timer 1 wie folgt konfiguriert:

TCCR1A = 0;
TCCR1B = (1<<WGM12)|(1<<CS12);
OCR1A = 31249;
TIMSK = (1<<OCIE1A);

Hier ist der Interrupt-Code

ISR(TIMER1_COMPA_vect){
    sec++;
}

Dann verwende ich ein LCD, um den Wert von sec kontinuierlich zu drucken , und ich bekomme ein Timing von 0,5 Sekunden. Mit anderen Worten, für jede verstreichende Sekunde generiert der Timer zwei Interrupts.

Zuerst dachte ich, ich hätte vielleicht die Sicherungen falsch gemacht, aber das scheint nicht der Fall zu sein, da Verzögerungen gut funktionieren. Wie auch immer, hier ist, wie ich die Sicherungen konfiguriert habe:

-U lfuse:w:0xff:m -U hfuse:w:0x99:m

Ich habe absolut keine Ahnung, was los ist, ich habe alles doppelt überprüft, einen anderen ATmega32 ausprobiert, einen anderen 16-MHz-Quarzoszillator ausprobiert, und ich bekomme immer noch das gleiche Ergebnis.

Ist das Datenblatt falsch oder übersehe ich hier etwas?

TL;DR Antwort: Nein. Nein, ist es nicht. ;-)

Antworten (2)

Wenn der Systemtakt 16 MHz und der Prescaler 256 beträgt , läuft Ihr Timer weiter 16 M H z 256 = 62500 H z , also wird es in jedem eine Erhöhung geben 1 62500 H z = 16 μ S . Ein Interrupt wird generiert, wenn der Wert des Zählers 31249 ist . Wenn wir diese Zeit berechnen: 16 μ S × 31250 T ich C k S = 0,5 S , was genau das gleiche Ergebnis ist, das Sie haben.

Die Gleichung im Datenblatt dient einem anderen Zweck:

Zum Generieren einer Wellenformausgabe in C T C Modus, der Ö C 1 A Der Ausgang kann so eingestellt werden, dass er seinen logischen Pegel bei jeder Vergleichsübereinstimmung umschaltet, indem die Vergleichsausgangsmodus-Bits auf den Umschaltmodus gesetzt werden ( C Ö M 1 A 1 : 0 = 1 ) . Der Ö C 1 A Der Wert ist auf dem Port-Pin nicht sichtbar, es sei denn, die Datenrichtung für den Pin ist auf Ausgabe eingestellt ( D D R Ö C 1 A = 1 ) . Die erzeugte Wellenform hat eine maximale Frequenz von F Ö C 1 A = F C l k ICH / Ö / 2 Wenn Ö C R 1 A wird auf Null gesetzt ( 0 X 0000 ) . Die Wellenformfrequenz wird durch die folgende Gleichung definiert: (...)

Wenn Sie die Frequenz eines bestimmten Pins messen würden, wäre es meiner Meinung nach 1 Hz.


Um eine 1 s zu erreichen , 16 μ S × 62500 = 1 S Interrupt-Generierung benötigen Sie 62500 Ticks und da der Zähler bei 0 beginnt, setzen Sie OCR1A auf 31250 × 2 1 = 62499 , und da Timer1 ein 16-Bit-Timer ist, ist dieser Wert nicht zu hoch (< 65535, 2 16 1 ).

Es ist tatsächlich 62499, und Sie müssen 1 addieren, bevor Sie mit der Taktperiode multiplizieren.
Oh! Ich fühle mich gerade so dumm, dass ich nicht bemerkt habe, dass es den Stift umgeschaltet hat, also habe ich einfach angenommen, dass es die gleiche Formel war !! Also, wenn ich genau 1 Sekunde will (so genau wie der Kristall ist), sollte ich OCR1A = 62499 verwenden, richtig? Nach der Formel (jetzt die 2 fallen lassen) sollte mir das genau 1 Sekunde geben.

Diese Formel gilt für die Ausgangsfrequenz des OCnA-Pins ("Zum Generieren eines Wellenformausgangs im CTC-Modus kann der OC1A-Ausgang so eingestellt werden, dass er seinen logischen Pegel bei jeder Vergleichsübereinstimmung umschaltet, indem die Vergleichsausgangsmodus-Bits auf den Umschaltmodus gesetzt werden (COM1A1: 0 = 1).[...] Die Wellenformfrequenz wird durch die folgende Gleichung definiert:"). Da Sie stattdessen den Interrupt verwenden, erhalten Sie zwei Vergleiche pro Periode. Lassen Sie die 2 vom Nenner weg, um die Unterbrechungsfrequenz zu berechnen.