Mal diverse Anmerkungen in wahlloser Reihenfolge.
1 | #define TL 0xf7
|
2 | #define TH 0xc2
|
3 | ...
|
4 | TCNT1L = TL;
|
5 | TCNT1H = TH;
|
Sorry, aber das würde ich als ,,Assemblerprogrammierung mit
C-Syntax''
bezeichnen. (Selbst in Assembler kann man das besser formulieren.)
Ich würde das so schreiben:
1 | #include <stdint.h>
|
2 |
|
3 | #include <avr/io.h>
|
4 |
|
5 | #define F_CPU 16000000ul
|
6 |
|
7 | #define TMR1_PRESCALER 1024
|
8 | /* 1-second overflow preset value */
|
9 | #define TMR1_PRESET ((uint16_t)(-(F_CPU / TMR1_PRESCALER)))
|
10 |
|
11 | void ioinit(void)
|
12 | {
|
13 | ...
|
14 | TCNT1 = TMR1_PRESET;
|
15 | }
|
Diese Variable sollte static innerhalb der ISR sein, denn nur dort
wird sie gebraucht.
1 | TCCR1B |= (1<<CS00) | (1<<CS02);
|
Schönheitsfehler: du setzt Timer 1, aber nimmst die Definitionsbits
von Timer 0.
Meine Variante:
1 | #include <stdint.h>
|
2 |
|
3 | #include <avr/interrupt.h>
|
4 | #include <avr/io.h>
|
5 | #include <avr/sleep.h>
|
6 |
|
7 | #define F_CPU 16000000ul
|
8 |
|
9 | #define TMR1_PRESCALER 1024
|
10 | /* 1-second overflow preset value */
|
11 | #define TMR1_PRESET ((uint16_t)(-(F_CPU / TMR1_PRESCALER)))
|
12 |
|
13 | void ioinit(void)
|
14 | {
|
15 | /* Enable pullups */
|
16 | PORTD |= (1<<PD2) | (1<<PD3);
|
17 | /* LED outputs */
|
18 | DDRB = 0xff;
|
19 |
|
20 | /* Prepare timer 1... */
|
21 | TCNT1 = TMR1_PRESET;
|
22 | TIMSK |= (1<<TOIE1);
|
23 | /* ...and kick it. */
|
24 | TCCR1B |= (1<<CS10) | (1<<CS12);
|
25 |
|
26 | sei();
|
27 | }
|
28 |
|
29 | ISR(TIMER1_OVF_vect)
|
30 | {
|
31 | uint8_t i;
|
32 |
|
33 | TCNT1 = TMR1_PRESET;
|
34 | i = PORTB;
|
35 | PORTB = (i & ~7) | (((i & 7) + 1) & 7);
|
36 | }
|
37 |
|
38 | int
|
39 | main(void)
|
40 | {
|
41 | ioinit();
|
42 | for (;;)
|
43 | sleep_mode();
|
44 | return 0;
|
45 | }
|
(Für avr-libc < 1.4.x musst du ISR durch SIGNAL ersetzen und den alten
Vektornamen benutzen.)
Im Simulator blinkt zumindest die LED im Sekundentakt.
Das Ganze hat natürlich rein akademischen Wert: in der Praxis würde
ich statt der umständlichen und mit Jitter behafteten Methode des
Overflow-Interrupts den CTC-Modus des Timers nehmen.