www.mikrocontroller.net

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


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.


.include "m8def.inc"

.def r_tmp       = r16
.def r_countdown = r17  ; In Sekunden
.def r_overflow  = r18

.equ prescaler = 3  ; Entspricht 64
.equ overflow  = 61 ; Bei Prescaler = 3, muss hier 61 stehen!
.equ countdown = 90 ; Countdown in Sekunden

.org 0x0
    rjmp func_main
.org OVF0addr
    rjmp int_timer0_overflow



func_main:
    ; Stackpointer initialisieren
    ldi r_tmp, HIGH(RAMEND) ; HIGH-Byte der oberen RAM-Adresse
    out SPH, r16
    ldi r16, LOW(RAMEND)    ; LOW-Byte der unteren RAM-Adresse
    out SPL, r16

    ldi r_countdown, countdown ; Countdown mit x Sekunden starten
    ldi r_overflow, overflow



func_timer_initialisieren:
    ldi r_tmp, prescaler    ; Prescaler
    out TCCR0, r_tmp

    ldi r_tmp, 1            ; Overflow-Interrupt aktivieren
    out TIMSK, r_tmp

    sei                   ; Globalen Interrupt aktivieren

    rjmp loop



int_timer0_overflow:      ; Timer0 Overflow Handler
    ; Bei 1MHz benötigt man für eine Sekunde,
    ; bei einem Prescaler von 64, 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.

    dec r_overflow    ; Overflowzähler dekrementieren
    breq func_sekunde ; Wenn Overflowzähler = 0 (Zero-Flag)
    reti



func_sekunde:
    ; Funktion wird jede Sekunde von int_timer0_overflow aufgerufen
    ldi r_overflow, overflow  ; Overflowzähler zurücksetzen
    dec r_countdown           ; Countdown dekrementieren
    breq func_zeit_abgelaufen ; Wenn Countdownzähler = 0 (Zero-Flag)
    reti



func_zeit_abgelaufen:
    ldi r16, 0xFF
    ldi r17, 0xFF
    ldi r18, 0xFF
    ldi r19, 0xFF
    ldi r20, 0xFF
    ldi r_tmp, 0      ; Overflow-Interrupt deaktivieren
    out TIMSK, r_tmp
    reti

loop:   rjmp    loop

Danke!

Daniel

Autor: Carsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dreh doch die Endlosschleife gleich nach der Initialisierung

> loop:   rjmp    loop

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.