Hallo!
Auf meinem Atmega32 hab ich schon einige male erfolgrich mit den Timern
gearbeitet, doch diesmal will es mir mit meinem Atmega 8 nicht gelingen
;(
Es geht draum, eine ISR(TIMER1_COMPA_vect) einmal pro Sekunde ausführen
zulassen. Wenn ich das richtig verstanden habe, benutzt der µC seinen
internen 1MHz Takt??! (Oder müssen da ncoh irgendwelche Fuses
umgestellt werden?)
Meine Rechnung:
(Quelltakt / Vorteiler)/ OCR1A = (Anzahl der Takte/sec am Ausgang/ISQ)
(1000000Hz / 1024 )/ 977 = 1/sec
Konfiguriert hab ich das Ganze daher so;
1
intmain(){
2
TCCR1B|=0b00000101;
3
TCCR1B&=0b11111101;
4
TCCR1A|=0b00000010;
5
TCCR1A&=0b11111110;
6
OCR1A=977;
7
TIMSK|=0b00010000;
8
sei();
9
10
while(1){}
11
return0;}
12
13
ISR(TIMER1_COMPA_vect){
14
//LED toogle...}
Mein Hauptproblem besteht draing, das in der Praxis die LED mehr als
zweimal in der Sekunde geschaltet wird, obwohl ich die Obergrenze OCR1A
schon = 65500; gesetzt habe.
Das ganze möchte ich mit GCC relisieren.
Vielen Danke für Eure Hilfe!!
Tobias Riegner schrieb:> Wenn ich das richtig verstanden habe, benutzt der µC seinen internen> 1MHz Takt??! (Oder müssen da ncoh irgendwelche Fuses umgestellt> werden?)
Du kannst genau diese Taktquelle mit Fuses einstellen. Und dann gibt es
noch die CLKDIV8. Wie sind deine Fuses eingestellt?
Schau dir mal an, welchen Timer Modus du da im TCCR1A setzt. CTC ist das
nicht und der Timer kann auch nicht höher als 511 laufen, also auch
nicht den im OCR1A gesetzten Wert von 977 erreichen.
Tausendmal schreiben: Du sollst zur Initialiserung von
Configurationstsregistern keine Bitfelder benutzen.
Also schreib das um in eine lesbare Form (1<< Bitname), und such den
Fehler.
Ach ja, CLKDIV8 hat ein Mega8 nicht, und weiter als bis 511 kann Timer 1
auch zählen (gibt es überhaupt Mikrocontroller mit 9-Bit Timern?). Daran
liegt es also nicht.
Oliver
Oliver S. schrieb:
.... und weiter als bis 511 kann Timer 1
> auch zählen (gibt es überhaupt Mikrocontroller mit 9-Bit Timern?). Daran> liegt es also nicht.
Ach? Noch einer, der ein Datenblatt nicht richtig lesen kann?
Edi R. schrieb:> Jetzt mach doch kein Geheimnis draus und klär uns endlich auf, was Du> meinst.
:)) Nein. Das würde doch dem Geist diesen Forums widersprechen.
(Vielleicht später, wenn die Lösung nicht auftauscht oder ich doch
falsch liegen sollte)
> Oder müssen wir alle erst die Bits in den Registern aufdröseln?
Ja, wenigstens der TE soll es tun ;-)
Oliver S. schrieb:> Also schreib das um in eine lesbare Form (1<< Bitname)
Dann aber bitte nicht diese << Dinger. Ab 4Bit kann das kein Mensch mehr
vernünftig lesen.
Man nimmt entsprechende konstanten. Das wird bei allen ausser ATMEL in
den Headern angeboten.
Und wer gar nicht ohne << kann, versteckt es in einem #define.
lesbarer code schrieb:> Oliver S. schrieb:>> Also schreib das um in eine lesbare Form (1<< Bitname)>> Dann aber bitte nicht diese << Dinger. Ab 4Bit kann das kein Mensch mehr> vernünftig lesen.
Also ich mag diese Dinger. Ich hab mir auch angewöhnt, alle Bits
anzugeben, und die nicht gesetzten dann mit (0 << Bitname)
hinzuschreiben. Dmait ist auf einen Blick klar was gesetzt ist und was
nciht, und ich kann auch kein Bit vergessen (bzw. bin gezwungen über
jedes Bit nachzudenken)
Wie würdest du nicht gesetzte Bits hinschreiben?
>// This is the central clock with 1 Hz (Not very stable, due to internal
4
>Clocksource
5
>TCCR1B=PRESCALER1|(1<<WGM12);// Prescaler 1024 and CTC Mode
6
>TCNT1=0;// Set to zero
7
>OCR1A=(F_CPU/1024);// 1 second value = 976
8
>
Wenn, dann würd ich statt PRESCALER1 als Name doch lieber PRESCALER1024
verwenden oder irgendwas, aus dem der Wert des Prescalers direkt
ersichtlich ist ;-)
@ lkmiller: Die Fuses sind folgendermaßen eingestellt: (SUT: 10
CKSEL:0001 ) An dem CLKDIV8 Hab ich nicht dran rumgeschraubt, weil dir
da ein anderer Beitrag wiedersprochen hat.
@ norbi: CTC, sprich ClearTimeronCompare soll ja aktiviert sein, damit
der Timer nach dem erfolgreichem Vergleich mit OCR1A wieder
zurückgesetzt wird. Das Zählregister des Timer1 sollte beim Atmega8
16Bit groß sein, deshalb hab ich die maximale Obergrenze auch als 65535
angenommen.
@oliverso: Ich hoffe das ist so lesbar genug, bin bisher nur mit der "
direkt in das 8-Bit Register reinschreib - Methode" vertraut.
TCCR1B |= 0b00000101; // (1<<CS12)^(1<<CS13) //Vorteiler: 1024
TCCR1B &= 0b11111101; // (0<<CS11) //Vorteiler: 1024
TCCR1A |= 0b00000010; // (1<<WGM10) // CTC Modus aktiv
TCCR1A &= 0b11111110; // (0<<WGM11) // CTC Modus aktiv
OCR1A = 977; // Vergleichswert 977 Wie gesagt auch bei =65500
immer noch viel zu schnell
TIMSK |= 0b00010000; // (1<<OCIE1A) //Interrupt für Compare1A
freigeben
TCNT1 =0; // Sicherheitshalber auch gesetzt.
Das Problem besteht weiterhin. Inzwischen bin ich mir sicher, dass ich
die Fuses reichtig gesetzt habe damit der interne CPU-Takt 1000000
verwendet wird. (SUT: 10 CKSEL:0001 )
Die Obergrenze habe ich jetzt mit 65535 angegegeben, um die ISr
möglichst langsam zu bekommen. Aus dem selben Grund ist mein gewählter
Vorteiler 1024.
Man könnte daher bei gegeben Werten folgende Rechnung aufstellen:
(1000000Mhz/1024)/65535 = 0.0149 pro Sekude ein Interrupt. => Alle 67
Sekunden ein Interrupt.
Dem ist aber leider nicht so, die LED blinkt einmal in der Sekunde =>
Zwei Interrupts pro Sekunde. Das ist mir immer noch viel zu schnell!
Danke für die bisherigen Antworten! Bitte entschuldigt meine späte
Antwort, ich hab in der Nacht tatsächlich auch noch geschlafen ;)
Hi
>TCCR1A |= 0b00000010; // (1<<WGM10) // CTC Modus aktiv>TCCR1A &= 0b11111110; // (0<<WGM11) // CTC Modus aktiv
Das ist kein CTC, sondern 'PWM, Phase Correct, 9-bit'. Für CTC muss
WGM12 in TCCR1B gesetzt werden.
MfG Spess
Hi
>Das war der entscheidende Hinweis! Das Register war offenbar falsch>eingestellt!!
Den Hinweis hättest du auch aus dem Datenblatt bekommen. Da gibt es eine
nette Tabelle mit den einzelnen Timermodi.
MfG spess
spess53 schrieb:> Hi>>>Das war der entscheidende Hinweis! Das Register war offenbar falsch>>eingestellt!!>> Den Hinweis hättest du auch aus dem Datenblatt bekommen. Da gibt es eine> nette Tabelle mit den einzelnen Timermodi.
War doch auch nicht sein Fehler. Lag doch am Register. Das war doch
falsch eingestellt...
Cyblord schrieb:
>War doch auch nicht sein Fehler. Lag doch am Register. Das war doch>falsch eingestellt...
Das mit der Ironie mußt Du aber noch ein wenig üben....
Das ist leider das einzige, was ich an diesem Forum nicht schätze die
Überheblichkeit Einzelner. Natürlich liegt der Fehler nie an dem µC
sondern an dem Benutzer, doch ich selbst konnte den Fehler leider nahe
zu unmöglich alleine lösen, weil in der "AVR-Formelsammlung" meiner
Schule scheinbar ein Fehler steckt. Wenn keine Probleme durch Menschen
auftreten würden, wäre das ganze Forum schließlich überflüssig.
Daher möchte ich diese einzelnen Personen, welche gleich auf die
Anfänger einhacken dazu auffordern den Neuankömmlingen mehr verständniss
entgegen zu bringen.
Tobias Riegner schrieb:> sondern an dem Benutzer, doch ich selbst konnte den Fehler leider nahe> zu unmöglich alleine lösen, weil in der "AVR-Formelsammlung" meiner> Schule scheinbar ein Fehler steckt. Wenn keine Probleme durch Menschen
Alles, was nicht vom Hersteller direkt kommt, kann Übertragungsfehler
enthalten. Formelsammlungen, Bücher, Internetseiten, ...
Also immer querchecken mit dem Datenblatt des Herstellers und auch da
können noch in ganz seltenen Fällen Fehler versteckt sein.
Also google dir das Datenblatt für den ATMega8 von ATMEL und versuche
den Unterschied zur Formalsammlung der Schule nachzuvollziehen.
Tobias Riegner schrieb:> doch ich selbst konnte den Fehler leider nahe> zu unmöglich alleine lösen, weil in der "AVR-Formelsammlung" meiner> Schule scheinbar ein Fehler steckt.
Also wieder andere Schuld? Was hat dich daran gehindert selbst ins
Datenblatt zu schauen?
> Daher möchte ich diese einzelnen Personen, welche gleich auf die> Anfänger einhacken dazu auffordern den Neuankömmlingen mehr verständniss> entgegen zu bringen.
Nahezu jeder Neuankömmling wird aufgefordert mal einen Blick ins DB zu
werfen. Tuts jemand? Hab ich noch nie gesehen. Also bleiben beides wohl
unerfüllbare Wünsche.
Tobias Riegner schrieb:> @oliverso: Ich hoffe das ist so lesbar genug, bin bisher nur mit der "> direkt in das 8-Bit Register reinschreib - Methode" vertraut.>> TCCR1B |= 0b00000101; // (1<<CS12)^(1<<CS13) //Vorteiler: 1024> TCCR1B &= 0b11111101; // (0<<CS11) //Vorteiler: 1024
Das macht das Leben nicht leichter, weil todsicher irgendwann die
Komentare nicht mitgeändert werden und nichts mehr zusammen paßt. Warum
schreibst du nicht direkt z.B.
TCCR1B |= (1<<CS12)|(1<<CS13) //Vorteiler: 1024
TCCR1B &= ~(0<<CS11)
Tobias Riegner schrieb:> Daher möchte ich diese einzelnen Personen, welche gleich auf die> Anfänger einhacken dazu auffordern den Neuankömmlingen mehr verständniss> entgegen zu bringen.
Dann solltest aber auch du "Verständniss" groß schreiben ;-)
Und jedem Neuankömmling steht es natürlich frei, hier vor seinem ersten
Post ein bisschen im Forum zu stöbern, um um die beliebtesten
Fettnäpfchen einen Bogen schlagen zu können.
Mike schrieb:> TCCR1B &= ~(0<<CS11)
Hi, Mike, gerade erst aufgestanden ;-)? Der Ausdruck oben ist ziemlich
sinnfrei. Normalerweise setzt man alle 0 und 1 in einem Rutsch, also
etwa so, wie BattMann schon vor ca 30 Stunden gepostet hat.
1
#define PRESCALER1024 ((1 << CS12) | (1 << CS10))
2
TCCR1B=PRESCALER1024|(1<<WGM12);// Prescaler 1024 and CTC Mode