simpler Sekunden-Timer mit AVR

Gast #4114393
Lesenswert?
• ▲
▼
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..
#4114416
Lesenswert?
• ▲
▼
@ 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.
Gast #4114422
Lesenswert?
• ▲
▼
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.
Gast #4114434
Lesenswert?
• ▲
▼
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%
Gast #4114460
Lesenswert?
• ▲
▼
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?
Gast #4114466
Lesenswert?
• ▲
▼
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.
Gast #4114482
Lesenswert?
• ▲
▼
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.
Gast #4114543
Lesenswert?
• ▲
▼
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.
(Firma: Vescomp) #4114544
Lesenswert?
• ▲
▼
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.