Eine teufliche Fußangel hast du noch drin.
Da ist zunächst deine Hauptschleife:
Code:
loop:
cpi zaehler, 0b00101000 ;Wenn Zählregister = 14 ist
breq zeitum ;dann spring zu "zeitum:"
rjmp loop ;Immer wieder selbst aufrufen -> Endlosschleife
Das sieht ganz unschuldig aus.
Jetzt stell dir vor, nach dem cpi gibt es einen IRQ (Interrupt ReQuest), daß also eine Interrupt Anforderung vorliegt.
Mit cpi hast du das SREG (Status Register) verändert.
Es hat verschiedene Flags, die das Ergebnis des Vergleiches darstellen wie 'größer als', 'gleich', etc.
Danach testest du mit breq das Z-Flag (Zero). Es ist gesetzt, wenn zahler-0b00101000 gleich 0 ist. In diesem Falle springst du nach zeitum.
Aber erst kommt deine Interrupt Service Routine (ISR) zum Zug:
Code:
pruefZaehler:
inc zaehler ;Zählregister um 1 erhöhen
ldi tmp, time ;Hier wird der Timer vorgelaen und zwar mit 255-90
out TCNT0, tmp ;Er läuft 90 mal durch, bevor ein Interrupt auftritt
reti ;wieder zurück, wo du hergekommen bist
Das inc erhöht zaehler um 1 und setzt u.a. das Z-Flag:
Z=1, falls das Ergebnis=0 ist; Z=0 sonst.
Die darauf folgenden Befehle tasten das Z nicht mehr an, und nach dem reti landest du beim breq von loop.
Das breq wird also dann verzweigen, wenn
- zaehler=0b00101000 (=0x28 = 40) ist, und es nach den cpi kein IRQ gibt oder
- zaehler=0b11111111 ist in loop, und es nach dem cpi ein IRQ gibt.
Auf das SREG kannst du mit in und out zugreifen, da fällt dir bestimmt was ein...
Gruß, Georg-Johann
Lesezeichen