Dort findet man zum Beispiel das:
Code:
;***** Simple time-based scheduler ********
;
;The goal is to allow several tasks to execute at a regular rate
;without making a HUGE timer ISR. The timer 0 interrupt just
;decrements counters which are tested in a loop to dispatch
;subroutines. Timer 0 ticks at a mSec rate in this code.

;Task descriptions:
; task 1: blink LED 0 2/sec
; task 2: blink LED 1 1/sec
; task 3: Detect button 0 and change task 1 blink rate if the button is down
; 
;********************************
;You will need to CHANGE this path
,nolist
.include "c:\avrtools\appnotes\8515def.inc"
.list

;********************************
;define registers
.def	save	=r1
.def	temp	=r16	;temporary register
.def	LED	=r17	;the actual LED value to display
.def	reload	=r18	;holds timer reload value

;Specify the interval for each task to execute:
;since we are toggling LED state on each task entry,
;the task times are 1/2 the desired blink times
.equ	t1	=250	;250 mSec
.equ	t2	=125	;125 mSec - Task2 will need to have another counter
.equ	t3	=30	;30 mSec interval for the keyboard scanner

;********************************
;RAM locations:

;Task execution time intervals 
.dseg
time1:	.byte 1
time2:	.byte 1
time3:	.byte 1

;Task2 state variable needed to 
;count 4 times the 1/4 second secheduled time
tsk2c:	.byte 1

;message from task3 to task1 to change rate
tsk3m:	.byte 1

;*******************************
; Initialization
.cseg
.org $0000
	rjmp RESET	;reset entry vector
	reti		
	reti
	reti
	reti
	reti
	reti
	rjmp TIMER
	reti
	reti		
	reti
	reti	
	reti

RESET:
	ldi	Temp, LOW(RAMEND) 	;setup stack pointer
	out 	SPL, Temp
	ldi	Temp, HIGH(RAMEND)
	out	SPH, Temp

	;set up the PORTs
	ser	Temp		;set PORTB to be
	out	DDRB,Temp	;all outputs
	ldi	Temp, 0xff	;turn off LEDs
	out	PortB, Temp

	clr	Temp		;set PORTD to be
	out	DDRD,Temp	;all inputs

	;set up timer 0 for 1 mSec ticks
	ldi	Temp,exp2(TOIE0);enable timer interrupt
	out	TIMSK, Temp
	ldi 	Temp, 3		;prescale timer by 64
	out 	TCCR0, Temp
	ldi	Reload,256-62	;preload timer since
	out 	TCNT0, Reload	;62.5 x (64x.25) microSec = 1.0 mSec.

	;initialize task timers
	ldi	temp, t1	;mSec
	sts	time1, temp
	ldi	temp, t2
	sts	time2, temp
	ldi	temp, t3
	sts	time3, temp

	;initialize LED state
	ldi	LED, 0xff	;all LEDs off

	;initialize task2 state variable (4 times thru equals 1/2 sec)
	ldi	temp, 4
	sts	tsk2c, temp

	;initalize task3 message to zero (don't modify task1 rate)
	ldi	temp, 0
	sts	tsk3m, temp
	
	;Start the clock ticking
	sei			;enable all interrupts	

******************************************************************
;Now start scheduling events.
;This is the main program loop.
;All tasks are subroutines called from here when
;their respective timers reach zero.

Sched:		
tsk1:	lds	temp, time1	;test for first task ready
	tst	temp
	brne	tsk2		;if not then skip it
	rcall	Task1
	
tsk2:	lds	temp, time2	;test for second task ready
	tst	temp
	brne	tsk3		;if not then skip it
	rcall	Task2

tsk3:	lds	temp, time3	;test for third task ready
	tst	temp
	brne	Sched		;if not then skip it
	rcall	Task3
	
	rjmp	Sched
	
;*****************************************************************
;The three actual tasks:
;******************************
;LED 0 2/sec (but modified by Task 3)
Task1:	lds	temp, tsk3m	;get the message from task 3
	tst	temp		;and test it for "fast/normal"
	brne	t1fast

	;if we get here the message from task 3 ="normal rate"
	ldi	temp, t1	;reinit time counter
	sts	time1, temp
	rjmp	t1blk

	;if we get here the message from task 3 ="fast rate"
t1fast:	ldi	temp, t1	;reinit time counter
	lsr	temp		;divide time by four
	lsr	temp
	sts	time1, temp
	
	;now toggle the LED
t1blk:	mov	temp, LED	;isolate the zero bit
	andi	temp, 0b00000001; and invert it
	andi	LED,  0b11111110
	com	temp
	andi	temp, 0b00000001
	or	LED, temp	
	out	PORTB, LED

	ret			;go back to scheduler

;******************************
;LED 1 1/sec
Task2: 	ldi	temp, t2	;reinit time counter
	sts	time2, temp

	lds	temp, tsk2c	;find out if 4 counts have occured
	dec	temp		;so that we can count to 1/2 second
	sts	tsk2c, temp
	tst	temp	
	brne 	t2exit		;if not then leave

	;if we get here, then 1/2 second has passed and we
	;should toggle the LED
	mov	temp, LED	;isolate the zero bit
	andi	temp, 0b00000010;  invert it
	andi	LED,  0b11111101;  then combine it with LED again
	com	temp
	andi	temp, 0b00000010
	or	LED, temp	
	out	PORTB, LED	

	ldi	temp, 4		;and reset the state variable
	sts	tsk2c, temp

t2exit:	ret			;go back to scheduler

;******************************
;Button detect and modify Task 1 blink rate
Task3: 	ldi	temp, t3	;reinit time counter
	sts	time3, temp

	in	temp, PIND	;get all the buttons
	com	temp		;convert a button-down to a one
	andi	temp, 0b00000001;isolate button 0
	brne	t3modt

	;if we get here then set message to "normal" task1 rate
	ldi	temp, 0		;set message value 
	sts	tsk3m, temp	;and store it
	rjmp	t3exit

	;if we get here then set message to "fast" task1 rate
t3modt:	ldi	temp, 1		;set message value
	sts	tsk3m, temp	;and store it

t3exit:	ret			;go back to scheduler


;**************************************************************
;timer 0 ISR (timer-zero overflow)
;Enters every 1.0 mSec

TIMER:	in	save, SREG
	out 	TCNT0, Reload	; keeps clock ticking at 1 mSec
	push 	temp		; use temp in ISR
	
	;update each of the three timers
	;for the three tasks
	;BUT if the count is zero don't do anything until the process
	;resets it

	lds	temp, time1
	tst	temp	
	breq	t0t2
	dec	temp	
	sts	time1, temp
	
t0t2:	lds	temp, time2
	tst	temp	
	breq	t0t3
	dec	temp	
	sts	time2, temp

t0t3:	lds	temp, time3
	tst	temp	
	breq	t0end
	dec	temp	
	sts	time3, temp

t0end:	pop	temp
	out	SREG, save
	reti			;back to backgound tasks
;**************************************************************
Ist glaub für Mega32