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
> 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.