Nimm doch für die Taktmessung den Timer 1.
Mit deiner Konfiguration wird alle 256 Perioden des Signals ein Timer 0 Overflow Interrupt ausgelöst.
Da der Timer 1 ein 16 Bit Timer ist passiert das dort nur alle 65536 Perioden.
Ich hab nen anderen C-Compiler als Du, deshalb kann ich deinen Code nicht direkt bearbeiten.
Ich würd mal so an die Sache rangehen.
1. Du muss die Controller Taktfrequenz wissen, mit welcher Du arbeiten willst.
Sagen wir mal 8 MHz.
Der Timer 0 bekommt dann einen Prescaler von 8.
Somit wird alle 2048 Takte ein Timer0 Overflow Interrupt ausgelöst.
In diesem Interrupt wird nun eine 16Bit Int Variable hochgezählt.
Wenn diese Variable den Wert 3906 hat ( >3906 ) wir der TCNT0 mit 192 vorgeladen. TCNT0=192;
Weil die eine Sekunde nicht genau in den 2048 Takte passt ist das notwendig = (2048-0,25*204
/8
Die Int Variable wird wieder auf 0 gesetzt.
Jetzt wird der Zähler TCNT1 und die dazugehörige Overflow Variable ausgelesen. Beide werden nun in Hilfsvariablen abgespeichert.
Dann wird TCNT1 und die zugehörige Overflow Variable auf 0 gesetzt.
Code:
void int tim0overflow(void)
{
ui_ov0count++
if(ui_ov0count>3906)
{
ui_counterlow=TCNT0;
TCNT0=192;
ui_counterhigh=ui_ov1count;
ui_ov1count=0;
ub_newflag=1;
};
};
2. Das Flag teilt der Hauptroutine mit, das neue Messwerte vorliegen und verarbeitet werden müssen.
Ist das in der Hauptroutine geschehen wird das Flag ub_newflag wieder auf 0 gesetzt.
Damit wäre dann das Torzeitproblem erschlagen.
Wie lange das Programm wirklich braucht, teste ich immer mit dem Simulator vom AVRSTUDIO aus.
Eventuell müssen da Anpassungen gemacht werden, da der Timer ja ach während des Programmablaufes weiter läuft.
Code:
void int tim1overflow(void)
{
ui_ov1count++
};
Die Timer 1 Overflow Routine ist erfreulich kurz - es wird nur die Hilfsvariable hochgezählt.
Code:
void main (void)
{......
while(1)
{
if(ub_newflag>0)
{li_frequenz=(ui_counterhigh*65536)+ui_counterlow;
/*Es sollte auch li_frequenz=(ui_counterhigh<<16)|ui_couterlow; gehen*/
displayout(li_frequenz);
ub_newflag=0;
}
}
}
Die beiden Hilfsvariablen werden dann in der Hauptroutine weiter verarbeitet in eine Long Int Variable gepackt und ausgegeben.
Du kannst natürlich auch mit anderen Quarzfrequenzen und Teilerfaktoren für den Timer0 arbeiten. Letztlich soll sich aber möglichst genau 1 Sekunde dabei rauskommen.
Lesezeichen