TIMER1 ist viel zu schnell

OP #3624632
Lesenswert?

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
int main(){
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
return 0;}
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!!
Angehängte Dateien:
#3624698
Lesenswert?

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
Gast #3624701
Lesenswert?

Das macht man so:
1
#define PRESCALER1    ((1 << CS12)|  (1 << CS10))  
2

3
// This is the central clock with 1 Hz (Not very stable, due to internal Clock source
4
  TCCR1B = PRESCALER1 | (1 << WGM12);// Prescaler 1024 and CTC Mode
5
  TCNT1 = 0;        // Set to zero
6
  OCR1A = (F_CPU/1024);      // 1 second value = 976
Gast #3624720
Lesenswert?

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 ;-)
Gast #3624736
Lesenswert?

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.
(Firma: Brainit GmbH) #3624758
Lesenswert?

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?
Gast #3624759
Lesenswert?

BattMan schrieb:
> Das macht man so:
>
>
1
> #define PRESCALER1    ((1 << CS12)|  (1 << CS10))
2
> 
3
> // This is the central clock with 1 Hz (Not very stable, due to internal 
4
> Clock source
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 ;-)
OP #3624910
Lesenswert?

@ 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 ;)
Gast #3624927
Lesenswert?

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
Gast #3624961
Lesenswert?

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
OP #3624993
Lesenswert?

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.
Gast #3625004
Lesenswert?

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.
#3625005
Lesenswert?

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.
Gast #3625009
Lesenswert?

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)
Gast #3625012
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren