Nachdem mein ursprüngliches Programm etwas zu schnell ablief hab ich es nun auf ein einfaches TimerTestprogramm reduziert. In der Timer-ISR wird meine Status-LED ein und ausgeschaltet. Leider geht das ganze vieeeeeel zu schnell. Eignetlich sollte zwischen den Ausführungen der Timer-ISR immer genau eine Sekunde liegen. Der AVR läuft über Quarz mit 8 Mhz. 8000000 : 256 (Prescaler) = 31250. Und diesen Wert hab ich als Comparewert geladen. D.h. der Timer führt 31250 Taktzyklen in der Sekunde aus und nach eben diesen 31250 Zyklen gibt es eine Compare Interrupt, also nach einer Sekunde. Leider läuft das ganze viel zu Schnell.. das eigentliche Programm sendete in der Timer-ISR über UART ein Signal an den PC, das ganze geschah ungefär 900 mal in der Sekunde, kann auch sein dass es durchaus öfter passiert wäre wenn die Senderoutine schneller gewesen wär. Wo steckt der Fehler im Code? mfg PoWl
1 | .include "m8def.inc" ; Deklarationen für ATmega8 |
2 | |
3 | |
4 | .cseg ; Programm-Flash |
5 | rjmp init ; Reset-Einsprung |
6 | |
7 | .org OC1Aaddr |
8 | rjmp timer ; Zu Timer ISR Springen |
9 | |
10 | |
11 | .org INT_VECTORS_SIZE ; Interrupteinsprünge übergehen |
12 | |
13 | |
14 | init: ldi R16, LOW(RAMEND) ; Stapel anlegen |
15 | out SPL, R16 |
16 | ldi R16, HIGH(RAMEND) |
17 | out SPH, R16 |
18 | |
19 | |
20 | sbi DDRB, 0 ; Status-LED Ausgang |
21 | |
22 | |
23 | ; Timer 1 Compare Wert |
24 | ldi R16, LOW(31250) |
25 | out OCR1AL, R16 |
26 | |
27 | ldi R16, HIGH(31250) |
28 | out OCR1AH, R16 |
29 | |
30 | ; Timer 1 CTC-Modus & Prescaler |
31 | ldi R16, (1 << CTC1 | 0b100 << CS10) |
32 | out TCCR1B, R16 |
33 | |
34 | ; Timer 1 OCA Interrupt aktivieren |
35 | ldi R16, (1 << OCIE1A) |
36 | out TIMSK, R16 |
37 | |
38 | |
39 | sei ; Interrupts aktivieren |
40 | |
41 | |
42 | |
43 | loop: rjmp loop ; Endlosschleife |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | ; Timer-ISR |
50 | |
51 | timer: |
52 | in R16, PORTB |
53 | com R16 |
54 | out PORTB, R16 |
55 | |
56 | reti |