Forum: Mikrocontroller und Digitale Elektronik AVR ATMega8 Timer: Code optimieren?


von Daniel (Gast)


Lesenswert?

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

von Carsten (Gast)


Lesenswert?

dreh doch die Endlosschleife gleich nach der Initialisierung

> loop:   rjmp    loop

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
Noch kein Account? Hier anmelden.