Ich möchte jede Sekunde eine Berechnung ausführen. Wobei es nicht supergenau auf die Sekunde ankommt. Kann auch paar Promille abweichen. 1. innerhalb der While(1) mit _delay_ms(1000) 2. mit Timer interrupt Ich denke 2. ist sauberer. Da stellen sich die Fragen: - mit CTC interrupt? - oder mit Timer Overflow interrupt? - Kann man das auch mit dem 8-Bit Timer realisieren oder brauchts den 16er ? - Andere meinen man soll den WDT nehmen..
Timer ist besser. Für sowas nimmt man eher den Overflow-Modus. Wenn der Timer zu schnell zählt, dann zählst du in der Timer-ISR eben noch eine zweite Variable mit, dann kommst du auch mit einem 8-Bit Timer aus.
@ Q_M (Gast) >Ich möchte jede Sekunde eine Berechnung ausführen. Wobei es nicht >supergenau auf die Sekunde ankommt. Kann auch paar Promille abweichen. Dann brauchst du einen Quarz an deinem AVR. >1. innerhalb der While(1) mit _delay_ms(1000) Nein. >2. mit Timer interrupt Ja. >Ich denke 2. ist sauberer. Ja. >- mit CTC interrupt? >- oder mit Timer Overflow interrupt? >- Kann man das auch mit dem 8-Bit Timer realisieren oder brauchts den >16er ? Geht mit allen drei Möglichkeiten, bei bestimmten Quarzfrequenzen mal etwas einfacher, mal etwas komplizierter. Siehe Timer. >- Andere meinen man soll den WDT nehmen.. Nein, der ist ungenau.
Dafür kommt einzig und alleine ein 8 Bit Timer mit dem "CTC-Interrupt" infrage. Ein 16 Bit Timer ist zu wertvoll und rausgeschmissene Recource. Eine while Abfrage für ein delay blockiert die ganze Schleife. Man könnte ein Timer auch mehrfach ausnutzen um Recourcen zu entlasten.
1 | init_timer_smh() { |
2 | /*
|
3 | cs02+01+00:
|
4 | 0 no clock
|
5 | 1 no presc
|
6 | 2 /8
|
7 | 3 /64
|
8 | 4 /256
|
9 | 5 /1024
|
10 | */
|
11 | |
12 | TCCR0A |= (1<<WGM01); |
13 | // 1; Timer0 Vorteiler: 64 -> bei 16 MHz:
|
14 | // 16.000.000 / 64 = 250000 Mal pro Sek gibts einen Takt an den Timer
|
15 | TCCR0B |= ((1<<CS02)|(1<<CS00));//1024 |
16 | |
17 | // Timer0 soll bei 250 einen Output Compare Interrupt auslösen ->
|
18 | // 250.000 / 250 = 1000 mal pro Sek gibts einen Interrupt
|
19 | OCR0A = 77; |
20 | |
21 | //Compare Interrupt aktivieren
|
22 | TIMSK0 |= (1<<OCIE0A); |
23 | |
24 | //Globale Interrupts aktivieren
|
25 | sei(); |
26 | }
|
27 | |
28 | |
29 | ISR(TIMER0_COMPA_vect) |
30 | {
|
31 | timer_proc_10ms(); |
32 | }
|
Timer für den m328 etc. bei 8MHz. Im timer_proc_10ms dann bis zu Sekunde hochzählen. Genauigkeit 100/255-> +-0,5%
grundschüler schrieb: > init_timer_smh() { > /* > cs02+01+00: > 0 no clock > 1 no presc > 2 /8 > 3 /64 > 4 /256 > 5 /1024 > */ > > TCCR0A |= (1<<WGM01); > // 1; Timer0 Vorteiler: 64 -> bei 16 MHz: > // 16.000.000 / 64 = 250000 Mal pro Sek gibts einen Takt an den > Timer > TCCR0B |= ((1<<CS02)|(1<<CS00));//1024 > > // Timer0 soll bei 250 einen Output Compare Interrupt auslösen -> > // 250.000 / 250 = 1000 mal pro Sek gibts einen Interrupt > OCR0A = 77; > > //Compare Interrupt aktivieren > TIMSK0 |= (1<<OCIE0A); > > //Globale Interrupts aktivieren > sei(); > } > > ISR(TIMER0_COMPA_vect) > { > timer_proc_10ms(); > } > > Timer für den m328 etc. bei 8MHz. Im timer_proc_10ms dann bis zu Sekunde > hochzählen. Genauigkeit 100/255-> +-0,5% Danke, ist genau mein System: mega328 mit 8Mhz extern. Aber dein Beispiel passt nicht zum Text, bzw. löst glaub alle 1ms aus. Wie hast du denn das OCR0A berechnet?
grundschüler schrieb: > ISR(TIMER0_COMPA_vect) > { > timer_proc_10ms(); > } Im Compare Modus wird der Timer nicht zurückgesetzt sondern läuft einfach weiter. Daher muss in der ISR der Counter "von Hand" zurückgesetzt werden (--> ergibt Ungenauigkeit bei jedem ISR-Eintritt). Daher lieber den Overflow-Modus anwenden, da braucht am Counter nichts gesetzt werden.
Counterdenker schrieb: > Im Compare Modus wird der Timer nicht zurückgesetzt sondern > . > Daher lieber den Overflow-Modus anwenden, da braucht am Counter Jetzt hab ich sämtliche Datenblätter durchschaut und finde weder "Compare Modus" noch "Overflow-Modus" darin. Von was sprichst du. Falls du mit Compare Modus den CTC (Clear Timer On Compare) Modus meinst: da wird der Timer sehr wohl zurückgesetzt.
Schau Dir diese beiden Links an: https://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC Beitrag "Die genaue Sekunde / RTC" wendelsberg
Q_M schrieb: > Wie hast du denn das OCR0A berechnet? ich habe auch 8MHz intern. Das OCR0A habe ich solange probiert, bis die geringste Gangabweichung der Uhr erreicht war. Etwa alle 5 Minuten 1sec Abweichung. Wenn das stört müsste man z.B. jede Stunde den Gangunterschied ausgleichen. Counterdenker schrieb: > Im Compare Modus wird der Timer nicht zurückgesetzt Das glaube ich nicht. Wenn das stimmen würde, hätte die Veränderung von OCR0A keinen Einfluss auf die Bestimmung der Uhrzeit. Hat sie aber.
Counterdenker schrieb: > Im Compare Modus wird der Timer nicht zurückgesetzt sondern > läuft einfach weiter. Daher muss in der ISR der Counter "von > Hand" zurückgesetzt werden (--> ergibt Ungenauigkeit bei > jedem ISR-Eintritt). Das ist mir aber neu. Es gibt sowas wie CTC - Clear Timer on Compare match, und wenn es kein PWM ist, benutzt man genau diesen Modus.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.