Eine teufliche Fußangel hast du noch drin.
Da ist zunächst deine Hauptschleife:Das sieht ganz unschuldig aus.Code:loop: cpi zaehler, 0b00101000 ;Wenn Zählregister = 14 ist breq zeitum ;dann spring zu "zeitum:" rjmp loop ;Immer wieder selbst aufrufen -> Endlosschleife
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:Das inc erhöht zaehler um 1 und setzt u.a. das Z-Flag: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
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







Zitieren

Lesezeichen