Forum: Compiler & IDEs 16-Bit Timer läuft zu schnell


von Paul P. (cesupa)


Lesenswert?

Hallo,

ich möchte für mein Projekt eine Uhr mit meinem Atmega32 realisieren. 
Der uC läuft mit 16MHz. Für meine Uhr und andere "Systemanwendungen" 
nutze ich einen Grundtakt von 10ms. Lasse ich die Uhr laufen, 
verstreichen die Sekunden jedoch zu schnell. Ungefähr 1/3 schneller, als 
eine Sekunde auf meiner normalen Uhr verstreicht. Woran könnte das 
liegen?
1
#define TICKS  10      //in ms, max. 1000
2
#define PRESCALER  64
3
#define COUNTER  65536
4
5
#if(TICKS>1000)
6
#error "TICKS IS TOO BIG!!!";
7
#endif
8
9
#define F_TIMER (1000/TICKS)
10
#define LOADER  (COUNTER-(F_CPU/(PRESCALER*F_TIMER)))
11
12
ISR(TIMER1_OVF_vect)
13
{
14
  /*
15
...
16
*/
17
  TCNT1=(uint16_t)LOADER;     //63036
18
}
19
20
int main()
21
{
22
23
  /*...*/
24
  
25
  /*using the 16-bit timer 1*/
26
  TCCR1B|=(1<<CS11)|(1<<CS10);  //prescaler=64
27
  TCNT1=(uint16_t)LOADER;      //63036->100ms
28
  TIMSK|=(1<<TOIE1);    //overflow interrupt
29
30
  
31
  sei();
32
33
  while(1)
34
  {
35
  }
36
  return 0;
37
}

Gruß
Paul

von Thomas F. (igel)


Lesenswert?

Wieso benutzt du nicht den CTC-Mode anstatt Overflow?
Du musst den Timer beim Überlauf nicht ständig neu laden.
Ich finde dies wesentlich komfortabler.

Thomas

von Stefan B. (stefan) Benutzerseite


Lesenswert?

>   TCNT1=(uint16_t)LOADER;      //63036->100ms

Dieser Kommentar ist verwirrend. Die ISR wird alle 10 ms aufgerufen. 
Vielleicht braucht dein /* ... */ Teil darin zu lange. Kann man aber 
nicht beurteilen, weil die Source fehlt. Ist nur geraten.

von Hc Z. (mizch)


Lesenswert?

Thomas Forster schrieb:
> Wieso benutzt du nicht den CTC-Mode anstatt Overflow?
> Du musst den Timer beim Überlauf nicht ständig neu laden.
> Ich finde dies wesentlich komfortabler.

Nicht nur komfortabler. Wozu so einen ungefähren Murks mit dem Neuladen 
des Timers machen, wenn es einen einfachen und jitterfreien Weg gibt? 
Es lohnt sich nicht, hier den Fehler zu suchen - CTC geht einfach, ist 
exakt und kostet weniger Code (spart das Neuladen).

von Paul P. (cesupa)


Lesenswert?

Hey Super, hat geklappt, hier noch mein code:
1
#define TICKS  10      //in ms, max. 1000
2
#define PRESCALER  64
3
4
#if(TICKS>1000)
5
#error "TICKS IS TOO BIG!!!";
6
#endif
7
8
#define F_TIMER (1000/TICKS)
9
#define LOADER  ((F_CPU/(PRESCALER*F_TIMER))-1)
10
11
ISR(TIMER1_COMPA_vect)
12
{
13
  tickTime();
14
  displayTime();
15
}
16
17
int main()
18
{
19
/*...*/
20
  
21
  /*using the 16-bit timer 1*/
22
  TCCR1B|=(1<<CS11)|(1<<CS10)|(1<<WGM12);  //prescaler=64
23
  OCR1A=(uint16_t)LOADER;      //10ms
24
  TIMSK|=(1<<OCIE1A);    //ctc interrupt
25
26
  
27
  sei();
28
29
  while(1)
30
  {
31
  }
32
  return 0;
33
}

Gruß
Paul

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
Noch kein Account? Hier anmelden.