Hallo Leute, ich stehe vor einem sehr komischen Problem.
Ich will mit zwei Timern im Mega 8 zwei Frequenzen erzeugen. Das hat
bisher auch immer gut funktioniert.
Seit ein paar Tagen aber spuckt er mir immer die DREIFACHE Frequenz aus,
im vergleich zur Berechneten.
Dabei macht es keinen Unterschied ob ich Timer1 oder Timer2 verwende.
Initialisiert wird so:
1
voidtimer1_init(uint16_tfreq)
2
{
3
// Prescaler auf 1
4
TCCR1A=0;
5
TCCR1B=(1<<WGM12)|(1<<CS10);
6
7
// OutputCompare1A Register setzen
8
OCR1A=(uint16_t)((uint32_t)F_CPU/(2*freq)-1);
9
10
// OutputCompare1A Interrupt aktivieren
11
TIMSK|=(1<<OCIE1A);
12
}
Rufe ich jetzt timer1_init(10000) auf, erzeugt er mir eine Frequenz von
30kHz statt eine mit 10kHz. Die Formel habe ich in gleicher Form auch
sonst verwendet, da hat es Problemlos funktioniert.
An der Formel liegt es meines Erachtens nicht, denn wenn ich den OCR
wert von hand berechne (für 30000 OCR auf 121) erhalte ich die 3Fache
Frequenz
Ich kann zwar damit Leben aber ich finde es doch sehr verwunderlich.
Die Fuse Bits sind richtig gesetzt auf externes Quarz, die F_CPU im
Makefile stimmt auch.
Hat einer von euch eine Idee an was das liegen könnte?
Vielen Dank für eure Hilfe
Christian
Hallo Karl heinz!
Danke für die schnelle Rückmeldung.
Im Interrupt toggle ich nur nen Ausgang:
1
SIGNAL(SIG_OUTPUT_COMPARE1A)
2
{
3
PORTD^=(1<<PD7);
4
}
auch im main lass ich die Finger von irgendwelchen Registern die den
Timer beeinflussen könnten. main besteht momentan nur aus einer endlos -
Schleife...
Für weitere Ideen wäre ich sehr dankbar.
Hast Du irgendeine Möglichkeit, Dir den Inhalt von OCR1A ausgeben zu
lassen? Wenn der richtig berechnet ist, dann gibts noch die Möglichkeit,
dass doch irgendetwas an den Fuses nicht stimmt.
Oder der Quarz hat einen Schuß, den würde ich mal tauschen,
Kondensatoren am Quarz checken, Abblockkondensatoren an der
Spannungsversorgung checken.
Okay also ich habe mir gerade OCR1AH und OCR1AL (16Bit register)
nacheinander an der seriellen schnittstelle ausgeben lassen:
in dezimal:
OCR1AH = 1
OCR1AL = 111
das macht zusammen meines erachtens 256 + 111 = 367
Für 367 als OCR-Wert sollte damit laut Datenblatt eine Frequenz von
10.017Hz rauskommen:
(FCPU = 7372800)
f_oc = FCPU / (2 1 (1+367)) = 10,017 Hz
^-Prescaler = 1
Gemessen mit dem Frequenzzähler sinds aber genau 30,053 Hz(also fast
exakt das 3 fache)
Wenn ich den OCR manuell auf 121 setze, bekomme ich umgekehrt statt
30.216 Hz wieder 10.0xx Hz raus... komische sache.
Denkst du an irgendwelche speziellen FuseBits die nicht passen?
Der CPU Takt läuft richtig, da sonst die serielle Übertragung sonst ja
auch nicht funktionieren würde...
Sehr eigenartig das Ganze:
* Fakt: Der Timer kann nicht schneller laufen als der
Systemtakt d.h. ich glaube nicht, dass das irgendwas
mit den Fusebits zu tun hat.
* Ein Faktor von 3 ist ungewöhnlich. Wenns wenigstens irgendeine
2-er Potenz wäre.
Hast du schon mal mit anderen Zahlenwerten für OCR probiert?
Ich denke da zb. an 255 und 256 (OCR1H == 0 und OCR1H == 1).
Dass vielleicht beim Beschreiben von OCR irgendwas passiert.
Hast du dir schon mal den Ausgangspin am Oszi angesehen?
10.017 und 10,017 sind zwei völlig unterschiedliche Dinge. Bitte
entscheide Dich für die in Deutschland gebräuchliche ODER die im
angelsächsischen Raum verbreitete Schreibweise, aber nicht beides
durcheinander...
Und damit man Dir konkret helfen kann, schicke bitte mal etwas mehr von
Deinem Programm. Hast Du mal ein "UL" hinter die 7372800 in der
Frequenzdefinition geschrieben?
Auch ein neuer ATMEGA8 bringt nix. Gleiches verhalten wie zuvor. Fuses
wurden auf externes Quarz mit 3-8 MHZ , slowly rising power gesetzt
(siehe Screenshot).
Takt läuft definitiv richtig, ein _delay_ms funktioniert nämlich
korrekt.
Nur die Timer wollen nicht. sehr komisch..
Johannes M. wrote:
> 10.017 und 10,017 sind zwei völlig unterschiedliche Dinge. Bitte> entscheide Dich für die in Deutschland gebräuchliche ODER die im> angelsächsischen Raum verbreitete Schreibweise, aber nicht beides> durcheinander...
Meine Meinung:
Am besten überlässt man die Tausenderpunkte den Kaufleuten.
Stiften nur Verwirrung.
Karl heinz Buchegger wrote:
> Meine Meinung:> Am besten überlässt man die Tausenderpunkte den Kaufleuten.> Stiften nur Verwirrung.
Richtig. Ich verwende sie im deutschen auch nicht. Allerdings lese und
schreibe ich viel auf englisch, wo dann das 1000er-Komma und der
Dezimalpunkt angesagt sind. Und der OP hat beide Schreibweisen gründlich
durcheinandergewürfelt. Ist ja nicht so, dass ich es nicht auch so
kapiert hätte, nur wenn man einmal so schludrig anfängt, dann nimmt das
i.d.R. kein gutes Ende. "Wehret den Anfänge(r)n" heißt es doch so
schön...
@ Johannes M.:
-Entschuldigung für die Schreibweise, ich habe nicht alle Werte
umgeändert (Copy-Paste aus zwei verschiedenen Programmen) der
Unterschied ist mir aber völlig bewusst, von Hand wäre das nicht
passiert...
-Im Makefile ist F_CPU wie folgt definiert:
1
F_CPU=7372800
also OHNE UL (was meiner Meinung nach auch korrekt ist)
Ich habe jetzt folgende Testreihe aufgestellt:
OCR | f-Berechnet | (f-berechnet * 3) | f-gemessen
-----+-------------+-------------------+-----------
255 | 14,400kHz | 43,200kHz | 43,203kHz
256 | 14,343kHz | 43,029kHz | 43,035kHz
511 | 7,200kHz | 21,600kHz | 21,602kHz
512 | 7,185kHz | 21,555kHz | 21,559kHz
Meine Beobachtungen:
* Die Register OCR1AH und OCR1AL enthalten immer die richtigen
OCR-Werte.
* Die Abweichung von (f-berechnet * 3) und f-gemessen ist so gering dass
es sich dabei um keinen Zufall handeln kann.
Habe mein Programm jetzt auf das wesentliche reduziert und im Anhang
beigefügt. Vielleicht kann sich das ja mal jemand von euch anschauen...
Ich wäre für jeden weitern Tipp dankbar!
Benedikt K. wrote:
> Die Software sieht OK aus, bis du sicher, dass der Quarz nicht auf der> 3x Frequenz schwingt ?
Das wäre so oder so ähnlich jetzt auch meine Vermutung gewesen. Das
Programm an sich lässt so etwas nicht zu, und wenn F_CPU im makefile
angegeben ist, ist das auch OK. Ein Faktor 3 kann dann eigentlich nur
von außen kommen. Und ein Quarz, der auf dem 3. Oberton schwingt, ist
nicht ungewöhnlich. Quarze ab 20 MHz arbeiten praktisch alle auf dem 3.
bzw. 5. Oberton, und bei entsprechender Fehlanpassung der
Oszillatorbeschaltung kann sowas durchaus passieren.
Ja da bin ich definitiv sicher, habe gerade nochmal mit dem
Frequenzzähler nachgemessen. Das Quarz schwingt mit 7372800 Hz.
ausserdem würde bei falsch eingestelltem takt die serielle übertragung
wohl auch nicht funktionieren.
ich habe diesen codeschnipsel schon in zig anderen Programmen verwendet
in denen sie anstandsloß gelaufen sind.
naja ich werde jetzt doch mal die kondensatoren und das quarz
austauschen, sonst hab ich ja schon so gut wie alles probiert... danke
trotzdem
Chris wrote:
> Ja da bin ich definitiv sicher, habe gerade nochmal mit dem> Frequenzzähler nachgemessen. Das Quarz schwingt mit 7372800 Hz.
Na dann...
> ausserdem würde bei falsch eingestelltem takt die serielle übertragung> wohl auch nicht funktionieren.
Da in Deinem Code nichts von einer seriellen Übertragung steht, hättest
Du das vielleicht mal eher sagen können...
> ich habe diesen codeschnipsel schon in zig anderen Programmen verwendet> in denen sie anstandsloß gelaufen sind.> naja ich werde jetzt doch mal die kondensatoren und das quarz> austauschen,...
Wenn er doch mit 7,3728 MHz läuft, bringt das auch nichts.
EDIT:
Sehe grad, dass Du tatsächlich die serielle Übertragung in dem Posting
von 12:53 erwähnt hattest. Hab ich übersehen.
Mach mal folgendes:
TCCR1A = 0;
TCCR1B = (1 << WGM12) | 5;
// OutputCompare1A Register setzen
OCR1A = 3599;
// OutputCompare1A Interrupt aktivieren
TIMSK |= (1 << OCIE1A);
Und hänge eine LED an den Pin. Die müsste jetzt mit 1Hz blinken. Damit
kann man ausschließen, dass dein Frequenzzähler Mist misst.
Mit dem UART hast du rechnt, also bleibt nur das als Fehlermöglichkeit.
Überprüf mal in deinem HEX-File, ob die ISR-Vektoren vor dem
Output-Compare1A auch alle richtig gesetzt sind, bzw die anderen
Interrupts auch sicher ausgeschaltet sind.
Einen Faktor von drei könnt ich mir nur so erklären, dass auch zwei
andere IRQs von dem Timer ausgelöst werden (Compare1B und Overflow), und
diese eben fälschlicherweise auch dieselbe ISR ausführen...
@Ernst:
Naja, das trau ich dem AVR-GCC nicht zu, dass er solchen Mist macht.
Außerdem ist das OCR1B-Register nicht initialisiert, hat also den Wert
0, was ganz andere Effekte hätte, wenn dem so wäre.
@Chris:
Ist das Signal am Pin denn ein gleichmäßiges Rechteck-Signal (50%
Einschaltdauer)? Ansonsten folge mal Benedikts Vorschlag und mach es mit
einer sehr niedrigen Frequenz, bei der man selbst erkennen kann, ob das
Tastverhältnis stimmt.
Die LED blinkt - das ist allerdings schneller als 1 Hz -> 3Hz kommen
wohl eher hin!! sowas langsames kann ich aber leider nichtmehr mit dem
Frequenzzähler messen.
Habe jetzt neue 22pF Kondensatoren und ein neues Quarz eingebaut,
allerdings ohne wirkung. Faktor 3 bleibt da.
Das mit den ISR Vektoren klingt interessant, allerdings weiss ich nicht
wo ich aus dem hex file was rauslesen sollte... ich hab mal das hex file
angehängt, kann mir vllt jemand sagen wie ich das interpretieren kann?
Gibt es dazu irgendwo Hinweise`?
ein lss file habe ich auch, da steht überall ausser bei nummer 6 etwas
von "bad vector" ...
Das Hex-File sieht in Sachen Interrupt-Vektoren OK aus. Allerdings ist
das Hex-File definitiv nicht von dem oben geposteten Quellcode. Hast Du
mit dem gekürzten Programm auch das ganze ausprobiert? Wenn nicht, dann
tu das, oder schick den KOMPLETTEN Quellcode, der zu dem Hexfile gehört.
Ich habe mit dem gekürzten Quellcode alles oben genannte ausprobiert.
Hier das komplette übersetzte Projekt, passend zum oben geposteten
c-code als zip File.
Vielen Dank für eure rege Beteiligung und Unterstützung. Ich kann es
einfach nicht glauben. Es ist ja nicht so dass ich das zum ersten mal
mit timern arbeite aber ich bin langsam echt am (ver)zweifeln.. Aber mit
Hex files und assembler kenne ich mich nicht aus.
Hab das Hex-File mal durch den Simulator laufen lassen. Da sieht
zumindest alles OK aus. Hast ja anscheinend den Prescaler jetzt auf 1024
und OCR1A auf 3800 stehen. Müssten dann ja eigentlich knapp unter 1 Hz
rauskommen...
ja ich habe es so angepasst weil ich das 7,37Mhz Quarz durch ein 8MHz
Quarz ersetzt habe (hatte kein 7er mehr). deshalb der OCR1A auf 3800
damit ich 1.03 Hz bekomme. Aber es ist einfach immernoch das 3fache.
Nungut, da die Software anscheinend völlig i.O. ist habe ich wohl keine
andere Möglichkeit als eine Neue Platine aufzubauen.
Dass der uC kaputt ist ist auch ausgeschlossen da ich einen nigel nagel
neuen aus der OVP eingesetzt habe.
Vielen Dank trotzdem für eure Wertvollen Tips und die geopferte Zeit,
hoffe mich gelegentlich revanchieren zu können.
Wenn du rausfindest an was es lag, teile es uns mit.
Es muss irgendein dummer Fehler sein, denn eigentlich haben wir schon
ziemlich alles ausgeschlossen.