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; }
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.