AVR ATMega8 Timer: Code optimieren?

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

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.