Ein Beispiel für Timer-Programmierung hab ich im Wiki.

https://www.roboternetz.de/wissen/in...LED_blinken%29

Das ist zwar C, aber das Vorgehen in Assembler ist das gleiche.

Code:
    TCCR1A = 0;

    // Timer1 ist Zähler: Clear Timer on Compare Match (CTC, Mode #4)
    // Timer1 läuft mit vollem MCU-Takt: Prescale = 1
   TCCR1B = (1 << WGM12) | (1 << CS10);
Im Assembler schreibst du also 0 nach TCCR1A und (1 << WGM12) | (1 << CS10) nach TCCR1B

Mit den anderen SFRs wie TIMSK entsprechend. Falls dein Assembler diese Konstrukte nicht frisst (ich weiß net ob Atmel-Assembler so was kann, bei GNU-Assembler geht es. Dasz einfach ein #include <avr/io.h> machen).

Falls es nicht geht muss eben im Manual schauen, wo sich diese Bits befinden. CS10 ist glaub bit 0 in TCCR1B. Das musst du eben setzen.
Den Wert für OCR1A lässt du den Preprozessor (GNU) berechnen oder machst es von Hand aufm Tacshenrechner.

In dem Beispiel benutze ich den OCR1A-Interrupt. GNU-Assembler trägt den in die VECTAB ein, bei Atmel-Assembler musst du das händisch machen. Ist im Wiki ASM-Tutorial beschrieben.

Nach der Initialisierung der Timers kannst du IRQs aktivieren (sei). Die Interrupt-Routine musst du noch implementieren, also den COde, den er bei einem Interrupt ausführen soll.

Das Problem mit Warteschleifen ist, daß während einer Schleife die Maschine brach liegt. Bei simplen Sachen ist das nicht schlimm, aber wenn es komplizierter wird und man hat das ganze Design drauf ausgelegt, wird's ätzend.

Was die Timer angeht lies mal das Handbuch, das ist echt gut geschrieben. Zum Einstieg die Kapitelzusammenfassung oder Überblick über die Timer-Register.