16-Bit Timer läuft zu schnell

OP #1812032
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
#1812072
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).
OP #1812174
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

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