mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega8, Timer1 läuft viel zu schnell?


Autor: Paul H. (powl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachdem mein ursprüngliches Programm etwas zu schnell ablief hab ich es 
nun auf ein einfaches TimerTestprogramm reduziert. In der Timer-ISR wird 
meine Status-LED ein und ausgeschaltet. Leider geht das ganze vieeeeeel 
zu schnell. Eignetlich sollte zwischen den Ausführungen der Timer-ISR 
immer genau eine Sekunde liegen.

Der AVR läuft über Quarz mit 8 Mhz. 8000000 : 256 (Prescaler) = 31250. 
Und diesen Wert hab ich als Comparewert geladen. D.h. der Timer führt 
31250 Taktzyklen in der Sekunde aus und nach eben diesen 31250 Zyklen 
gibt es eine Compare Interrupt, also nach einer Sekunde.

Leider läuft das ganze viel zu Schnell.. das eigentliche Programm 
sendete in der Timer-ISR über UART ein Signal an den PC, das ganze 
geschah ungefär 900 mal in der Sekunde, kann auch sein dass es durchaus 
öfter passiert wäre wenn die Senderoutine schneller gewesen wär.

Wo steckt der Fehler im Code?

mfg PoWl
.include "m8def.inc"          ; Deklarationen für ATmega8


.cseg                  ; Programm-Flash
    rjmp  init          ; Reset-Einsprung

.org  OC1Aaddr
    rjmp  timer          ; Zu Timer ISR Springen


.org  INT_VECTORS_SIZE        ; Interrupteinsprünge übergehen


init:  ldi    R16, LOW(RAMEND)    ; Stapel anlegen
    out    SPL, R16
    ldi    R16, HIGH(RAMEND)
    out    SPH, R16


    sbi    DDRB, 0          ; Status-LED Ausgang

    
    ; Timer 1 Compare Wert
    ldi    R16, LOW(31250)
    out    OCR1AL, R16

    ldi    R16, HIGH(31250)
    out    OCR1AH, R16

    ; Timer 1 CTC-Modus & Prescaler
    ldi    R16, (1 << CTC1 | 0b100 << CS10)
    out    TCCR1B, R16    

    ; Timer 1 OCA Interrupt aktivieren
    ldi    R16, (1 << OCIE1A)
    out    TIMSK, R16


    sei                ; Interrupts aktivieren



loop:  rjmp  loop          ; Endlosschleife





; Timer-ISR

timer:
    in    R16, PORTB
    com    R16
    out    PORTB, R16

    reti


Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  ldi    R16, LOW(31250)
>  out    OCR1AL, R16

>  ldi    R16, HIGH(31250)
>  out    OCR1AH, R16
Ganz typischer Fehler: Bei solchen 16-Bit-Doppelregistern muss IMMER 
erst das High-Byte und dann das Low-Byte geschrieben werden. Das 
High-Byte wird in einem temporären Register gepuffert. Der Zugriff auf 
das Low-Byte "triggert" den eigentlichen Schreib- bzw. Lesevorgang. 
Also:
- Beim schreiben erst High-, dann Low-Byte
- Beim Lesen erst Low-, dann High-Byte

Du schreibst das Low-Byte, was dazu führt, dass das (noch leere) 
temporäre Register ins High-Byte übernommen wird. Das anschließende 
Schreiben des High-Bytes hat überhaupt keinen Effekt mehr, weil der Wert 
erst beim Schreibzugriff auf das Low-Byte ins Register übernommen werden 
würde.

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achte bei den 16-bit Registern auf die Reihenfolge....

Kennt der Assembler eigentlich die Namen aus den Datasheet ?
;...
    ; Timer 1 Compare Wert

    ldi    R16, HIGH(31250) ; die Reihenfolge ist wichtig!
    out    OCR1AH, R16

    ldi    R16, LOW(31250)
    out    OCR1AL, R16

    ; Timer 1 CTC-Modus & Prescaler
;    ldi    R16, (1 << CTC1 | 0b100 << CS10)
; Geht das nicht als
    ldi    R16, (1<<WGM12 )|(1<<CS12) ; 0b101<<CS0 ergibt 1024 als Prescaler
    out    TCCR1B, R16    

    ; Timer 1 OCA Interrupt aktivieren
    ldi    R16, (1 << OCIE1A)
    out    TIMSK, R16
;...
SO, Ich glaube,  jetzt hab ich das Kapitel Timer im Datasheet 
gründlicher gelesen als du ;)

hth. Jörg

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.