Morgen leute!!!!

also, ich fang am besten mal von vorne an. Ich habe für meinen vater und dessen Hühner eine automatische klappe gebastelt, die auf Helligkeit reagiert und die Klappe entsprechend bewegt. hat seit rund 2 monaten alles wunderbar funktioniert, kein huhn war bisher unter der klappe o.ä.
nun seit geraumer zeit, macht die klappe allerdings komische gestalten. Immer (nicht immer, geht mal 2-5 tage gut, aber immer in der herabbewegung) beim herabfahren, reagiert der ATmega8 nichtmehr. der motor dreht munter weiter und nur ein ausschalten der schaltung bringt diesen zum stoppen. Ich hab mittlerweile den µC, den LDR und die komplette Schaltung getauscht, ohne erfolg.

zum aufbau am besten mal ein Schaltplan:
http://img44.imageshack.us/img44/4396/huehnerklappe.png
ich denke, die anschlussbelegung sollte klar sein, Motor, LDR und Endschalter als abschaltende begrenzung.

zum Programm:
ich erkläre mal kurz, was ich mir dabei gedacht habe
also, ich setze den C für rund 4 min schlafen, und überprüfe dann den Spannungswert am ADC. sollte eine änderung eingetreten sein, wird entsprechend reagiert.
haupt:
in "haupt" wird die Spannung abgefragt und bei einer änderung entsprechend verzweigt.
slep:
legt den C für 4 min schlafen.
auf/ab:
setzt die ausgänge entsprechend fürs hinauf/abfahren und wartet bis ein schalter auslöst oder die zeit für die bewegung beendet ist (sicherheit).
entprellen:
entprellt die mechanischen Endschalter. hierfür wird auch die software-warteschleife ms10 benötigt.
zeitaktiv_auf/ab:
hier wird der Timer gesetzt, solange die bewegung maximal dauern darf (für hoch und runter unterschiedliche zeiten, weil der auffahren länger dauert)
timer0:
ist die reaktion auf die abgelaufene zeit ( ausgänge abschalten, und timer rücksetzen)

daher kommt auch meine annahme das der µC abschmiert, weil er weder auf die zeit, noch auf die endschalter reagiert. und die ausgäng bleiben tatsächlich bis zum abschalten gesetzt, ich habe entsprechend LED´s dran gelötet.
habe das programm nun schon nach nem überlaufenden stack hin untersucht, leider nichts gefunden. vielleicht schaut mal schnell ein profi drüber ob er einen fehler findet, bzw. ob er eine andere vermutung hat.
ich danke deshalb schonmal im voraus für eure hilfe, bin gerade leicht am verzweifeln =P

Code:
.equ zeit = 1700					;für die MS10 routine, 10ms warteschleife
.equ schleife_durch = 10 ;10				;für entprellroutine durchläufe
.equ schleife_sleep = 4	 ;4			;schleifendurchläufe für timer. 1 durchlauf = 67 sekunden.
.equ slep_tcnt_vorladen = 1		 	;zum vorladen des register tcnt des timers 1, um feiner abstufungen zu erreichen. Normal=0
.equ adc_wert = 130		;100		;vergleichswert für adc und lichtsensor
.equ Zeit_hochfahren = 33 ;33		;Wert zur einstellung der Zeit, die für das hochfahren der klappe verantwortlich ist.
.equ Zeit_runterfahren = 24 ;24		;wert zur einstellung der Zeit für das Herunterfahren
									;4 => 1 sec. (1zyklus = 261,1 ms)

; = 4.22V am LDR = 21.14Uhr am 24.07.09
;   4.66V am LDR = 21.23Uhr
;	differenz rund 0.44 V

;***definitionsdatei***

.include "m8def.inc"

;***interrupt adressen***

.org 0x000	rjmp reset		;Programm start
;.org 0x001	rjmp stop		;Näherungsschalter
;.org 0x002	rjmp aus		;Interrupt schalter
.org 0x008  rjmp timer		;Timer für sicherheit, wird aktiviert nach dem schalten der ausgänge
.org 0x009  rjmp timer0		;Timer0 für das hoch/runterfahren der tür

		; Stack initialisieren
reset:
		ldi 	r16, LOW(RAMEND)
		out 	SPL, r16
		ldi 	r16, HIGH(RAMEND)
		out 	SPH, r16

		;Ein/Ausgänge konfigurieren

		ser		r16			;ausgang
		out		DDRB, r16
		clr 	r16			;Eingang
		out 	DDRC, r16	
		out 	DDRD, r16

		;sleep mode aktivieren
		
		ldi		r16, 0b10000000;	0b10001111
		out		MCUCR, r16
		;ldi		r16, 0b00000001
		;out		GICR, r16

		;variable für ersten durchlauf ins register kopieren
		ldi		r16, 1
		mov		r2, r16

		sei					;interrupts frei

Haupt:	

		;ADC konfig, ADC0 

		ldi 	r16, 0b01100000 
		out 	admux, r16
		ldi		r16, 0b11000011
		out		adcsra, r16
	adcrun:	
		in		r10, adcsra
		sbrc	r10, 6
		rjmp 	adcrun

		;adc werte in reg. schreiben

		in		r17, ADCL
		in		r18, ADCH

   ;ACHTUNG, unteren WERT ebenfalls ändern
		cpi		r18, adc_wert    ;hier einstellwert für sreg
		in		r16, SREG ;SREG speichern
		andi	r16, 0b00000001
		mov		r1, r16
		eor		r1, r0
		mov		r0, r16
		sbrc	r2, 0
		rjmp	erstedurchgang
		breq	slep		
   ;ACHTUNG, oberen Wert ebenfalls ändern
		cpi		r18, adc_wert 	;hier einstellwert
		brlo 	ab1			;hier tor zu
		brsh	auf1		;hier tor auf
		rjmp 	slep
;unterprogramme

slep:							;schlafen legen, und alle 10 min wieder wecken
		ldi		r16, 0b00000101		;teiler 
		out		TCCR1B, r16
		ldi		r16, 0b00000100
		out		TIMSK, r16
		ldi		r30, schleife_sleep			;schleifendurchläufe für wartezeit
		clr		r31
	slep1:	
		;wdr									;watchdog reset
		ldi		r16, low(slep_tcnt_vorladen)		 		;63535 ins register laden = 2 sekunden
		ldi		r17, high(slep_tcnt_vorladen)					
		out		TCNT1H, r17
		out		TCNT1L, r16
		sleep
		nop
		tst		r30
		brne	slep1
		rjmp	haupt 
		
erstedurchgang:

		clr		r2
		rjmp	haupt

auf1:
		ldi		r16, 0b00000101
		out		PORTB, r16
		rcall	zeitaktiv_auf			;Timer1 für Sicherheitszeit aktivieren
		;warten bis schalter betätigt
	warten1:	
		sbrc	r31, 0				;wenn timer1 interrupt fahrt beendet
		rjmp 	slep				;dann springt wieder nach slep zurück
		in		r16, PIND
		sbrc	r16, 3
		rjmp	entprellen
		rjmp	warten1
		
ab1:	
		ldi		r16, 0b00000110
		out		PORTB, r16
		rcall	zeitaktiv_ab			;Timer1 für Sicherheitszeit aktivieren
		;warten bis schalter betätigt
	warten2:	
		sbrc	r31, 0				;wenn timer1 interrupt fahrt beendet
		rjmp 	slep				;dann springt wieder nach slep zurück
		in		r16, PIND
		sbrc	r16, 2
		rjmp	entprellen
		rjmp	warten2

;entprell routine
entprellen:
		push	r16
		ldi		r17, schleife_durch			;schleifendurchläufe
		in 		r16, PIND
		mov		r3, r16
	aus1:
		in		r16, PIND
		mov		r2, r16
		eor		r2, r3
		mov		r3, r16
		push	r16
		rcall	ms10
		pop		r16
		dec		r17
		tst		r17
		brne	aus1		
		sbrc	r16, 3
		rjmp	aus2
		sbrc    r16, 2
		rjmp	aus2
		rcall	ms10
		clr		r17
		pop		r16
		rjmp	slep
	aus2:
		clr		r16
		clr		r17
		clr		r19
		out		PORTB, r16
		out		TCCR0, r16		;timer deaktivieren
		out		TCNT0, r16		;timer0 zählregister nullen
		pop		r16
		rjmp 	slep

;timer0 fürs bewegen der Tür aktivieren
zeitaktiv_auf:
		;r29 zum herunterzählen beladen.
		ldi		r29, zeit_hochfahren
		ldi		r16, 0b00000101		;teiler 
		out		TCCR0, r16
		ldi		r16, 0b00000001		;interrupt starten
		out		TIMSK, r16
		ret
zeitaktiv_ab:
		;r29 zum herunterzählen beladen.
		ldi		r29, zeit_runterfahren
		ldi		r16, 0b00000101		;teiler 
		out		TCCR0, r16
		ldi		r16, 0b00000001		;interrupt starten
		out		TIMSK, r16
		ret
	

;***********Warteschleife*********

ms10:							;taster entprellen
		;wdr
		push	r17
		push	r18
		ldi 	r16, low(zeit)
		ldi 	r17, byte2(zeit)
		ldi 	r18, byte3(zeit)
	ms101:
		subi 	r16, low(1)			;1 Takt
    	sbci 	r17, byte2(1)		;1 Takt
    	sbci 	r18, byte3(1)		;1 Takt
		sbrs 	r18, 0				;1 takt
		breq 	ms102				;
		rjmp	ms101				;2 takte
	ms102:	
		pop		r18
		pop		r17
		ret
	

;*************************interrupt handler***************************
;sleep-timer, 16 bit
timer:
		dec		r30
		reti

;nach abgelaufener zeit motor aus, timer0, 8bit	
timer0:
		dec		r29
		tst		r29
		breq	timer0_stop
		reti
	timer0_stop:
		push	r16
		clr		r16
		out		PORTB, r16
		out		TCCR0, r16
		out		TCNT0, r16
		sbr		r31,1
		pop		r16
		reti