ATMega128 Timer zu langsam

Gast #922257
Lesenswert?
• ▲
▼
Hi..

Ich habe folgendes Problem. Und zwar versuche ich einen einen Timer 
einzustellen, der alle 25ms einen Interrupt auslöst.Im Betrieb ist der 
Timer allerdings zu langsam und mir schenint nicht klar warum.

Der Controller wird mit 14745600 Hz betrieben
1
#include <avr\io.h>
2
#include <avr\interrupt.h>
3

4
//Interrupt definieren
5
#define system_tick()  ISR(TIMER1_OVF_vect) 
6

7
system_tick()  {  
8
  
9
  //LEDS invertieren
10
  PORTA ^= 0xFF;  
11
}
12

13
int main(void){
14

15
  DDRA  = 0xFF;  
16
  PORTA = 0;
17
  
18
  //Timer Register auf 360 setzen
19
  TCNT1H = 0x01;
20
  TCNT1L = 0x68;
21
  
22
  //Overflow Interrupt aktivieren
23
  TIMSK |= (1<<TOIE1); 
24
  
25
  //TIMER1 Prescaler von 1024 einstellen und starten
26
  TCCR1B  |= (1<<CS12) | (1<<CS10); 
27
  
28
  //Interrupts Enable
29
  sei();
30
  
31
  for(;;){
32
  }
33
  
34
  //Interrupts Disable
35
  cli();
36

37
}

Wie man sieht ist der Prescaler auf 1024 eingestellt.

14745600  / 1024  = 14400
14400  / 360 = 40
1 / 40 = 0.025[s]

also sollte das soweit stimmen. Jedoch ist die Dauer im Test ca. 1 
Sekunde lang.

Hat Jemand eine Ahnung woran das liegen könnte?
#922292
Lesenswert?
• ▲
▼
Erstens zählt der Timer aufwärts und macht also bei einem Preload von 
360 immerhin 65536 - 360 = 65176 Schritte bis zum Überlauf, was ungefähr 
dem 180-fachen des gewünschten Wertes entspricht. Zweitens macht man 
sowas beim AVR nicht mit Timer-Vorladen, sondern mit der Compare-Einheit 
im CTC-Modus. So wie es oben steht wird das ganze sowieso nur einmal mit 
der gewünschten Zeit laufen, weil Du in der ISR das Timer-Zählregister 
nicht wieder lädst. Und da steht dann sowieso Null drin. Mit CTC 
brauchst Du nur einmal den Wert ins Compare-Register zu schreiben, den 
Rest macht der µC selbst.

BTW:
Weiß der µC überhaupt, dass er mit dem Quarz arbeiten soll (Fusebits 
korrekt gesetzt)?
Gast #922299
Lesenswert?
• ▲
▼
1
#include <avr\io.h>
2
#include <avr\interrupt.h>
3

4
//Interrupt definieren
5
#define system_tick()  ISR(SIG_OUTPUT_COMPARE1A)  //Compare Interrupt
6

7
system_tick()  {  
8
  //Timer zurücksetzen
9
  TCNT1H = 0x00;
10
  TCNT1L = 0x00;
11
  
12
  //LEDS invertieren
13
  PORTA ^= 0xFF;  
14
  
15
}
16

17
int main(void){
18

19
  DDRA  = 0xFF;  
20
  PORTA = 0;
21
  
22
  //Compare Register A  auf 360 setzten
23
  OCR1AH = 0x01;
24
  OCR1AL = 0x68;
25
  
26
  
27
  //Compare Interrupt aktivieren
28
  TIMSK |= (1<<OCIE1A);
29
  
30
  //TIMER1 Prescaler von 1024 einstellen und starten
31
  TCCR1B  |= (1<<CS12) | (1<<CS10); 
32
  
33
  //Interrupts Enable
34
  sei();
35
  
36
  for(;;){
37
  }
38
  
39
  //Interrupts Disable
40
  cli();
41

42
}

hat sich erledigt ;)

vielen dank
#922301
Lesenswert?
• ▲
▼
kalhou wrote:
>
1
> system_tick()  {
2
>   //Timer zurücksetzen
3
>   TCNT1H = 0x00;
4
>   TCNT1L = 0x00;
5
>
Timer Zurücksetzen kannst Du Dir sparen (und solltest Du auch, weil 
dadurch die Genauigkeit leidet). Im CTC-Modus wird der Timer automatisch 
beim Compare-Ereignis zurückgesetzt.

>
1
>   //Compare Register A  auf 360 setzten
2
>   OCR1AH = 0x01;
3
>   OCR1AL = 0x68;
4
>
Warum so kompliziert? Ein einfaches
1
OCR1A = 360;
tut's auch. Und vor allem nimmt der Compiler Dir dabei die Sache mit der 
richtigen Reihenfolge ab.

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.