Forum: Compiler & IDEs Atmega2560 Timerproblem


von RobertmcDonald (Gast)


Lesenswert?

Hallo ich will meinen Timer vom Atmgea auf ein externes Uhrenquarz 
umstellen. Davor hatte ich den Timer auf TIMER1_COMPA_vect verglichen 
und er hat funktioniert sobald ich auch ohne den Uhrenquarz umstelle 
funzt das ganze nicht mehr. Hier der Code (Die alte Variante 
auskommentiert):

ISR(TIMER1_OVF_vect)//Interruptroutine für Uhrzeit
{
//... BLAbLA
}

void Time_Init(void)
{
Message_Out_Str("A",1);
/*
//Prescaler Variante
//CTC Modus
TCCR1A &= ~(1<<WGM10);
TCCR1A &= ~(1<<WGM11);
TCCR1B |= (1<<WGM12);
TCCR1B &= ~(1<<WGM13);

//Output Compare A true
TCCR1C |= (1<<FOC1A);

//Prescaler auf 1024
TCCR1B |= (1<<CS12);
TCCR1B &= ~((1<<CS10)|(1<<CS11));

//Output Compare auf 100ms setzen
//16000000/(256)*1000/1000=6250
//256 Prescaler, 1000 da jede 100ms auslösen soll, :1000 umrechnung von 
ms auf s
//125 sehalb damit Erg. gerade --> Fehler klein halten
OCR1A=6250;

//Output Compare Interrupt aktivieren
TIMSK1 |= (1<<OCIE1A);
*/

//Normaler Modus
TCCR1A &= ~(1<<WGM10);
TCCR1A &= ~(1<<WGM11);
TCCR1B &= ~(1<<WGM12);
TCCR1B &= ~(1<<WGM13);

//Mit Uhrenquarz (rising edge)
TCCR1B |=((1<<CS10)|(1<<CS11)|(1<<CS12));


//Output Compare Interrupt aktivieren
TIMSK1 |= (1<<TOIE1);
//Rest vorsichtshalber deaktivieren
TCCR1C &= ~((1<<FOC1A)|(1<<FOC1B)|(1<<FOC1C));
TIMSK1 &= ~((1<<OCIE1A)|(1<<OCIE1B)|(1<<OCIE1C));

//Zähler am Anfang auf 0 setzen
TCNT1=0;

sei();//Interrupts an

zeit_h = ZEIT_DEFAULT/60;
zeit_m = ZEIT_DEFAULT%60;
}

von RobertmcDonald (Gast)


Lesenswert?

Das wäre viell. auch noch wichtig obwohl es ja etwas mit dem Interrupt 
zu tun hat:

#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>

#include "zeit.h"



#define F_CPU 16000000        //Prozessortakt      //CPU-Takt im MHz

volatile uint8_t  zeit_h,zeit_m,zeit_s, zeit_ms_128;  //Zahlenbereich 
0-255

Sowie die Header Datei:
////////////////////////////////////////////////
#ifndef ZEIT_H_
#define ZEIT_H_

#include <avr/io.h>

uint8_t Set_Time(uint8_t stunden,uint8_t minuten);
uint8_t Check_Time(uint16_t minuten);
uint16_t Get_Time_Minuten();
void Get_Timestamp(char *s);

#endif

von Helfer (Gast)


Lesenswert?

main.c
1
#ifndef F_CPU
2
#define F_CPU 16000000UL
3
#endif /* F_CPU */
4
5
#include <avr/io.h> // ++
6
#include <avr/interrupt.h>
7
#include <string.h>
8
#include <stdlib.h>
9
#include "zeit.h"
10
11
#define UHRENQUARZ 1
12
13
//Zahlenbereich 0-255 ausreichend
14
volatile uint8_t zeit_h, zeit_m, zeit_s, zeit_ms_128;  
15
16
// Aufruf alle 
17
//   100ms bei Takt F_CPU
18
//   125ms bei Takt Uhrenquarz
19
ISR(TIMER1_COMPA_vect)//Interruptroutine für Uhrzeit
20
{
21
  //... BLAbLA
22
}
23
24
void Time_Init(void)
25
{
26
  /* CTC Variante
27
  Output Compare auf 100ms setzen
28
29
  Fall #1: Clock Source = F_CPU
30
  Takte / s bei Prescaler 1 = 16000000
31
  Takte / s bei Prescaler PRESCALER = 16000000 / PRESCALER 
32
  Takte / 100ms bei Prescaler PRESCALER = 16000000 / PRESCALER / 10
33
34
  Prescaler OCR1A+1  Anm. 
35
  =======================================================
36
  1         1600000  Nicht benutzbar weil 16-Bit Overflow
37
  8          200000  Nicht benutzbar weil 16-Bit Overflow
38
  16         100000  Nicht benutzbar weil 16-Bit Overflow
39
  64          25000  Benutzbar
40
  256         4494,4 Bruch ist ungünstig
41
  1024        1562,5 Bruch ist ungünstig
42
  => Optimale Einstellung: PRESCALER 64 (CS10 und CS11) 
43
44
  Fall #2: Clock Source = Uhrenquarz
45
  PRESCALER = 1
46
  Clock on falling Edge: 
47
48
  Takte / s bei Prescaler 1 = 32768
49
  Takte / s bei Prescaler PRESCALER = 32768 / 1 = 32768
50
  Takte / 100ms bei Prescaler PRESCALER = 32768 / 10 = 3276,8
51
52
  100ms lassen sich nicht mit einer geraden Zahl von Takten erreichen!
53
  was geht: 
54
  IRQ alle 125ms (32768/8 = 4096) oder alle 62,5ms (32768/16 = 2048) 
55
  */ 
56
57
#if UHRENQUARZ
58
  // COMPA alle 125 ms
59
  OCR1A = (32768U/8)-1; // Fall #2: Clock Source = Uhrenquarz
60
#else
61
  // COMPA alle 100 ms
62
  OCR1A = ((F_CPU/64)/10)-1; // Fall #1: Clock Source = F_CPU
63
#endif /* UHRENQUARZ */
64
65
  TCCR1A = 0;
66
#if UHRENQUARZ
67
  //CTC Modus #5 (WGM12) und 
68
  //External clock source on Tn pin. Clock on falling edge
69
  TCCR1B = (1<<WGM12) | (1<<CS12)| (1<<CS11);
70
#else
71
  //CTC Modus #5 (WGM12) und 
72
  //Prescaler auf 64
73
  TCCR1B = (1<<WGM12) | (1<<CS11)| (1<<CS10);
74
#endif /* UHRENQUARZ */
75
76
  //Output Compare Interrupt aktivieren
77
  TIMSK1 |= (1<<OCIE1A);
78
}
79
80
int main(void)
81
{
82
  Time_Init();
83
  sei(); 
84
  while(1) {
85
  }
86
}

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.