Hallo,
ich habe mein erstes Programm geschrieben! Es ist ein Timer. Nun würde
ich gerne meinen Code auf Fehler überprüft wissen. Da jedoch die
Simulation bis 90 Sekunden funktioniert, interessiert mich vielmehr, ob
ich noch irgendetwas optimieren kann.
Hier die Funktionsweise:
Mit Hilfe der Variable "countdown" lege ich die Zeit (in Sekunden) bis
zum Ereignis fest. Hier sollen nach 90 Sekunden die Register 16-20 mit
0xFF geladen und der Timer-Interrupt ausgeschalten werden.
Der ATmega8 läuft mit 1MHz, der Prescaler mit 64. Somit benötigt man für
eine Sekunde rund 61 Overflows:
1.000.000 64 256 = 61,03515625 Overflows
Das entspricht einer Abweichung von -0,0576% und bedeutet, dass die Uhr
bei einer Stunde Laufzeit 2,0736 Sekunden vor geht.
1 | .include "m8def.inc"
|
2 |
|
3 | .def r_tmp = r16
|
4 | .def r_countdown = r17 ; In Sekunden
|
5 | .def r_overflow = r18
|
6 |
|
7 | .equ prescaler = 3 ; Entspricht 64
|
8 | .equ overflow = 61 ; Bei Prescaler = 3, muss hier 61 stehen!
|
9 | .equ countdown = 90 ; Countdown in Sekunden
|
10 |
|
11 | .org 0x0
|
12 | rjmp func_main
|
13 | .org OVF0addr
|
14 | rjmp int_timer0_overflow
|
15 |
|
16 |
|
17 |
|
18 | func_main:
|
19 | ; Stackpointer initialisieren
|
20 | ldi r_tmp, HIGH(RAMEND) ; HIGH-Byte der oberen RAM-Adresse
|
21 | out SPH, r16
|
22 | ldi r16, LOW(RAMEND) ; LOW-Byte der unteren RAM-Adresse
|
23 | out SPL, r16
|
24 |
|
25 | ldi r_countdown, countdown ; Countdown mit x Sekunden starten
|
26 | ldi r_overflow, overflow
|
27 |
|
28 |
|
29 |
|
30 | func_timer_initialisieren:
|
31 | ldi r_tmp, prescaler ; Prescaler
|
32 | out TCCR0, r_tmp
|
33 |
|
34 | ldi r_tmp, 1 ; Overflow-Interrupt aktivieren
|
35 | out TIMSK, r_tmp
|
36 |
|
37 | sei ; Globalen Interrupt aktivieren
|
38 |
|
39 | rjmp loop
|
40 |
|
41 |
|
42 |
|
43 | int_timer0_overflow: ; Timer0 Overflow Handler
|
44 | ; Bei 1MHz benötigt man für eine Sekunde,
|
45 | ; bei einem Prescaler von 64, rund 61 Overflows:
|
46 | ; 1.000.000 / 64 / 256 = 61,03515625 Overflows
|
47 | ; Das entspricht einer Abweichung von -0,0576%
|
48 | ; und bedeutet, dass die Uhr bei einer Stunde Laufzeit
|
49 | ; 2,0736 Sekunden vor geht.
|
50 |
|
51 | dec r_overflow ; Overflowzähler dekrementieren
|
52 | breq func_sekunde ; Wenn Overflowzähler = 0 (Zero-Flag)
|
53 | reti
|
54 |
|
55 |
|
56 |
|
57 | func_sekunde:
|
58 | ; Funktion wird jede Sekunde von int_timer0_overflow aufgerufen
|
59 | ldi r_overflow, overflow ; Overflowzähler zurücksetzen
|
60 | dec r_countdown ; Countdown dekrementieren
|
61 | breq func_zeit_abgelaufen ; Wenn Countdownzähler = 0 (Zero-Flag)
|
62 | reti
|
63 |
|
64 |
|
65 |
|
66 | func_zeit_abgelaufen:
|
67 | ldi r16, 0xFF
|
68 | ldi r17, 0xFF
|
69 | ldi r18, 0xFF
|
70 | ldi r19, 0xFF
|
71 | ldi r20, 0xFF
|
72 | ldi r_tmp, 0 ; Overflow-Interrupt deaktivieren
|
73 | out TIMSK, r_tmp
|
74 | reti
|
75 |
|
76 | loop: rjmp loop
|
Danke!
Daniel