Hi Leute, ich bin neu in uC versuche gerade den genauen/gravierenden Unterschied zwischen den beiden CTC Modes (Mode4 und Mode12) zu verstehen. So wie ich das Datenblatt verstehe, besteht der einzige Unterschied darin, in welches Register der Wert geschrieben wird, bei dem ein Compare Match auftritt. Bei Mode 4 ist es OCR1A und bei Mode 12 ist es ICR1. Jetzt frage ich mich allerdings, welcher der beiden Modes zu empfehlen/vorzuziehen ist, wenn wir von Timern sprechen. Oder wird das erst später von Interesse sein, wenn man vielleicht noch mal eine PWM mit einbauen will? Denn bei meinem aktuellen Stand sind beide Modi gleich mit Ausnahme des unterschiedlichen Registers. Vielen Dank für eure Hilfe. Anbei mein C Code:
1 | #include <avr/io.h> |
2 | #include <util/delay.h> |
3 | #include <avr/interrupt.h> |
4 | |
5 | void MODE4(void); |
6 | void MODE12(void); |
7 | |
8 | int main(void) |
9 | {
|
10 | |
11 | MODE12(); |
12 | |
13 | while(1) |
14 | {
|
15 | |
16 | }
|
17 | }
|
18 | |
19 | void MODE4(void) |
20 | {
|
21 | |
22 | DDRB |= (1<<PB1); // PB1 as output (DDRB must be set to enable the output driver) |
23 | OCR1A |= 976; // Value determines interrupt request every second |
24 | // 16bit equals 65536 and uC runs with 1MHz => 1us
|
25 | // With prescaler set to 1024 one period is then 1us*1024=1024us, counter increases every 1024us
|
26 | // For 65536 we need 65536*1024us=67.1s
|
27 | // For 1s we need 65536*1s/67.1 = 976
|
28 | // Note that for different prescales other values for OCR1A are needed but the principle
|
29 | // calculation remains the same
|
30 | |
31 | TCCR1B |= (1<<WGM12); // CTC with OCR1A |
32 | TCCR1B |= (1<<CS12) | (1<<CS10); // Sets prescaler to 1024 |
33 | TIMSK |= (1<<OCIE1A); // Output Compare A Match Interrupt Enable |
34 | sei(); // Enable interrups (SEt Interrupts) |
35 | }
|
36 | |
37 | void MODE12(void) |
38 | {
|
39 | DDRB |= (1<<PB1); // PB1 as output (DDRB must be set to enable the output driver) |
40 | ICR1 |= 976; // Value determines interrupt request every second |
41 | // 16bit equals 65536 and uC runs with 1MHz => 1us
|
42 | // With prescaler set to 1024 one period is then 1us*1024=1024us, counter increases every 1024us
|
43 | // For 65536 we need 65536*1024us=67.1s
|
44 | // For 1s we need 65536*1s/67.1 = 976
|
45 | // Note that for different prescales other values for ICR1 are needed but the principle
|
46 | // calculation remains the same
|
47 | TCCR1B |= (1<<WGM12) | (1<<WGM13); // CTC with ICR1 |
48 | TCCR1B |= (1<<CS12) | (1<<CS10); // Sets prescaler to 1024 |
49 | TIMSK |= (1<<OCIE1A); // Output Compare A Match Interrupt Enable |
50 | sei(); // Enable interrups (SEt Interrupts) |
51 | }
|
52 | |
53 | |
54 | // Interrupt routine makes LED blink every second for 100ms
|
55 | ISR(TIMER1_COMPA_vect) |
56 | {
|
57 | PORTB |= (1<<PB1); |
58 | _delay_ms(100); |
59 | PORTB &= ~(1<<PB1); |
60 | }
|