Im Code ist erst mal so kein Fehler erkennbar, ausser der von Nils
etdeckte Ziffernsturz. Aber der macht keinen Faktor 10 aus.
Auch die Berechnung stimmt.
Ev. ein Messfehler? Wie gehts weiter? In welchem Umfeld benutzt du den
Code?
Die Gefahr von unterschiedlichen Zahlen bei der Zuweisung an High und
Low Register kannst du vermeiden, indem du die Aufdröselung den Compiler
machen lässt.
oliver schrieb:> Mein timer 1 läuft auf einem ATMEGA 32 mit 3,6864MHz im CTC Mode.>> Hier die initialisierung:>> void timer1_init()> {> TCCR1A = 0x00;
OK.
> TCCR1B = (1<<WGM12)
Table 47
4 0 1 0 0 CTC OCR1A Immediate MAX
OK.
> | (1<<CS12) | (1<<CS10); // 1024 ??
Table 48
1 0 1 clkI/O/1024 (From prescaler)
OK.
> TCNT1H = 0;> TCNT1L = 0;
OK.
> OCR1AH = ((3599) >> 8);> OCR1AL = (3559);
^
n. OK.
OCR1A Wert um alle 1s einen Timer/Counter1, Output Compare A Match
Interrupt zu bekommen: 3686400 / 1024 - 1 = 3599
> TIMSK = (1<<OCIE1A);
OK.
> leider erhalte ich genau den Faktor 10. zu schnell!!
Wie gemessen? Bist du sicher, dass die nicht im Code gezeigte ISR
angesprungen wird und nicht der AVR sich alle 100ms resettet?
Der kleine Niels schrieb:> Da fällt mir auf:> 3,6864MHz klingt nach STK500 Takt... liegt vielleicht dort der Hund> begraben?
Hab ich mir auch schon gedacht.
Aber spielen wir das mal durch.
Bei einem Faktor von 10, selbst wenn man nicht rechnet, müsste die
CPU-Frequenz dann entweder 368kHz oder 36Mhz sein.
Das eine ist zu klein, das andere zu gross. 368kHz würde die CPU zwar
noch mitmachen, aber ob sie mit 36Mhz noch läuft, bezweifle ich mal.
Faktor 10 ist aber auch ein ungewöhnlicher Faktor.
der Controller läuft definitiv mit externem takt lt fuses.
gemessen, naja, ich habe eine serielle ausgabe, die mir halt jede
sekunde etwas anzeigt, anstatt alle 10s.
Desweiteren habe ich keinen Reset, da ich diesen am anfang der main per
RST ausgeben lasse, dies funktioniert auch gut z.b. per resetknopfdruck.
also: kein reset!
oliver schrieb:> der Controller läuft definitiv mit externem takt lt fuses.>> gemessen, naja, ich habe eine serielle ausgabe, die mir halt jede> sekunde etwas anzeigt, anstatt alle 10s.
Moment.
Du willst 10 Sekunden?
Zeig doch mal das komplette Programm
ich arbeite mit einem externen Takt von 3,6864MHz.
Die Baudraten, die ich bisher und jetzt auch! daraus errechne,
funktionieren super! D.H., der Takt ist wohl sauber!
aber das 2.If ist ja dann immer wahr, damit braucht du es nicht
[c]
if(!train_begin)
{
//uputs("T00000000000100000000000101EA00000001 ZUG BEGIN\r\n");
train_begin = 1;
//uputs(s);
}
if(train_begin)
[\c]
dann klappts auch mit dem 'nur einmal ausgeben'.
Das else ist ein deutliches Indiz, dass der von ihm abhängige Teil in
irgendeiner Form mit dem if davor verknüpft ist und das man diese beiden
Ausführungspfade in ihrer Gesamtheit sehen muss um zu verstehen was da
vor sich geht. Lass dir diese 'Dokumentationsmöglichkeit' nicht
entgehen, sie hat nur Vorteile. Schon alleine der Umstand, dass die 2-te
Bedingung damit automatisch das Gegenteil von der ersten ist, ohne dass
du sie hinschreiben musst, ist den Minderaufwand schon wert.
Wenn du die Variable dann auch noch 'sendOverflowMessage' oder so
ähnlich nennst, dann kann man das auch lesen. Sonst fragt sich jeder,
wie da jetzt ein Zug ins Spiel kommt und ob da wohl der ICE damit
gemeint ist.