AVR ATMega8 Timer: Code optimieren?

Gast #979659
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren