; ***********************************************************************************************; * RGB-Fader + Festfarben + Strobo	+ Disco-Blinker												*; *																								*; * für ATMega 8515																				*; *																								*; * Version 2.0 - 10.03.2008																	*; *																								*; * LEDs über Mosfet-Schalter an Port A															*; *																								*; * PortA0 = Rot, PortA1 = Grün, PortA2 = Blau													*; ***********************************************************************************************.include "m8515def.inc"; ------------------------------------------------------------------------------------------------; Register etc. definieren; ------------------------------------------------------------------------------------------------.def temp0 		= R16						; Register definieren.def temp1 		= R17.def temp2 		= R18.def Speed 		= R19.def R  		= R20.def G  		= R21.def B  		= R22.def PWM_Count 	= R23.equ XTAL 		= 16000000					; nur zur Info; ------------------------------------------------------------------------------------------------; Stackpointer, Vektoren, Ports setzen; ------------------------------------------------------------------------------------------------.org 0x0000		rjmp    Start                  		; Reset Handler.org OVF0addr		rjmp    ISR_PWM       				; Timer Overflow Handler für PWM.org 0x0012									; Hauptprogramm kommt nach InterruptvektortabelleStart:		ldi 	temp0, LOW(RAMEND)			; LOW-Byte der obersten RAM-Adresse		out 	SPL, temp0		ldi 	temp0, HIGH(RAMEND) 		; HIGH-Byte der obersten RAM-Adresse		out 	SPH, temp0		ldi     temp0, 0b00000001			; CS00 setzen: Teiler 1		out     TCCR0, temp0		ldi     temp0, (1<<TOIE0)      		; TOIE0: Interrupt bei Timer Overflow		out     TIMSK, temp0		sei									; Interrupts aktivieren		ldi 	temp0, 0			out		DDRC, temp0					; PortC auf Eingang (DIP-Schalter)		ldi		temp0, 0b00000001		out 	DDRE, temp0					; PortE0 auf Ausgang (Status-LED), 1 und 2 auf Eingang		sbi		PORTE, 1					; Pull-Up-Widerstände		sbi		PORTE, 2		ldi 	temp0, 0xff		out 	DDRA, temp0					; PortA auf Ausgang setzen (PWM-Ausgang)		out		PORTC, temp0				; Pull-Up-Widerstände an PORTC aktivieren		sbi 	DDRD, 7						; PortD7 auf Ausgang ("On"-LED); ------------------------------------------------------------------------------------------------; "Grundzustand" - Farben über DIP-Schalter einstellbar, Strobo; ------------------------------------------------------------------------------------------------Schalter_Loop:    							; DIP-Schalter abfragen		sbis	PINC, 6						; Schalter 7 ist aus, weiter		rcall	RGB_Fade					; Schalter an --> RGB-Fader		sbis	PINC, 5						; Schalter 6 ist aus, weiter		rcall	Disco						; Schalter an --> Disco-Blinker		cbi		PORTE, 0					; Status-LED an		sbic	PINC, 3						; Schalter 4 abfragen (Grün Hälfte/Rosa-Korrektur)		rjmp	Farben						; Korrektur nicht gewünscht, "normal weiter"		in 		temp1, PINC					; Dip-Schalter abfragen		andi	temp1, 0b00000111			; Sonderfall "Weiss"		brne	Farben						; nicht alle Schalter an (nicht Weiss), also weiter zu Farben		ldi		R, 200						; weniger Rot wegen Rosa-Stich von Rebels		ldi		G, 255		ldi		B, 255		rjmp	Strobo						; Farbeinstellung überspringen, weiter zu StroboFarben:		ldi		temp1, 255					; Rot an		sbic	PINC, 0						; Schalter 1 abfragen (Rot)		ldi		temp1, 0					; Schalter ist aus, Rot aus		mov		R, temp1					; ins Register		ldi		temp1, 0					; Grün aus		sbic	PINC, 1						; Schalter 2 abfragen (Grün)		rjmp	Gruen						; Schalter ist aus, weiter		ldi		temp1, 255					; Schalter ist an, Grün an		sbis	PINC, 3						; Schalter 4 abfragen (Grün Hälfte/Rosa-Korrektur)		ldi		temp1, 90					; Schalter ist an, Grün HälfteGruen:		mov		G, temp1					; ins Register		ldi		temp1, 255					; Blau aus		sbic	PINC, 2						; Schalter 3 abfragen (Blau)		ldi		temp1, 0					; Schalter ist aus, Blau aus		mov		B, temp1					; ins RegisterStrobo:		sbic	PINC, 4						; Schalter 5 abfragen (Strobo)		rjmp	Schalter_Loop				; Schalter aus, kein Strobo		ldi		Speed, 255					; Strobo-Grundgeschwindigkeit		sbic	PINC, 7						; Schalter 8 abfragen (Rot/blau Strobo)		rjmp	Strobo_normal				; Schalter aus, normales Strobo		ldi		R, 255						; Rot		ldi		G, 0		ldi		B, 0		cbi		PORTE, 0					; Status-LED an		ldi		temp1, 2					; für 2 Zyklen RotStrobo_rot:				rcall	warten				dec		temp1		brne	Strobo_rot		ldi		R, 0						; dann aus		ldi		G, 0		ldi		B, 0		sbi		PORTE, 0					; Status-LED aus		ldi		temp1, 10					; und 10 Zyklen ausStrobo_rot_aus:		rcall	warten				dec		temp1		brne	Strobo_rot_aus		ldi		R, 0						; dann Blau		ldi		G, 0		ldi		B, 255		cbi		PORTE, 0					; Status-LED an		ldi		temp1, 2					; für 2 Zyklen BlauStrobo_blau:		rcall	warten				dec		temp1		brne	Strobo_blau		ldi		R, 0						; dann aus		ldi		G, 0		ldi		B, 0		sbi		PORTE, 0					; Status-LED aus		ldi		temp1, 10					; und 10 Zyklen ausStrobo_blau_aus:		rcall	warten				dec		temp1		brne	Strobo_blau_aus		rjmp	Schalter_Loop				Strobo_normal:		ldi		temp1, 2					; für 2 Zyklen anStrobo_an:				rcall	warten				dec		temp1		brne	Strobo_an		ldi		R, 0						; dann aus		ldi		G, 0		ldi		B, 0		sbi		PORTE, 0					; Status-LED aus		ldi		temp1, 10					; und 10 Zyklen ausStrobo_aus:		rcall	warten				dec		temp1		brne	Strobo_aus		rjmp	Schalter_Loop; ------------------------------------------------------------------------------------------------; Fade-Routine; ------------------------------------------------------------------------------------------------RGB_Fade:				push	temp0		ldi		Speed, 1					; Max.-GeschwindigkeitRGB_Loop:		ldi		R, 255						; erst mal Rot		ldi		G, 0		ldi		B, 0							cbi		PORTE, 0					; Status-LED anrot_gelb:									; dann Grün dazu --> Gelb		sbic	PINC, 6						; Schalter 7 ist an, weiter mit Fader		rjmp	RGB_Ende					; Schalter aus --> RGB-Fader beenden		ldi		Speed, 128					; Grundgeschwindikeit Warteschleife		sbic	PINC, 7						; Schalter 8 ("Dimmerkurve") an?		rjmp	DK_1						; nein, weiter		ldi		Speed, 255					; ja, Geschw. an Helligkeit anpassen		sub		Speed, G		cpi		Speed, 50					; Geschwindigkeit noch >= 50?		brsh	DK_1						; ja, weiter		ldi		Speed, 50					; nein, auf 50 setzenDK_1:		rcall	warten		sbi		PORTE,0						; Status-LED aus		inc		G		cpi		G, 255		brlo	rot_gelb		cbi		PORTE, 0					; Status-LED angelb_gruen:									; Rot weg --> Grün		sbic	PINC, 6						; Schalter 7 ist an, weiter mit Fader		rjmp	RGB_Ende					; Schalter aus --> RGB-Fader beenden		ldi		Speed, 128					; Grundgeschwindikeit Warteschleife		sbic	PINC, 7						; Schalter 8 ("Dimmerkurve") an?		rjmp	DK_2						; nein, weiter		ldi		Speed, 255					; ja, Geschw. an Helligkeit anpassen		sub		Speed, R		cpi		Speed, 50					; Geschwindigkeit noch >= 50?		brsh	DK_2						; ja, weiter		ldi		Speed, 50					; nein, auf 50 setzenDK_2:		rcall	warten		sbi		PORTE,0						; Status-LED aus				dec		R		brne	gelb_gruen		cbi		PORTE, 0					; Status-LED angruen_cyan:									; Blau dazu --> Cyan		sbic	PINC, 6						; Schalter 7 ist an, weiter mit Fader		rjmp	RGB_Ende					; Schalter aus --> RGB-Fader beenden		ldi		Speed, 128					; Grundgeschwindikeit Warteschleife		sbic	PINC, 7						; Schalter 8 ("Dimmerkurve") an?		rjmp	DK_3						; nein, weiter		ldi		Speed, 255					; ja, Geschw. an Helligkeit anpassen		sub		Speed, B		cpi		Speed, 50					; Geschwindigkeit noch >= 50?		brsh	DK_3						; ja, weiter		ldi		Speed, 50					; nein, auf 50 setzenDK_3:		rcall	warten		sbi		PORTE,0						; Status-LED aus		inc		B		cpi		B, 255		brlo	gruen_cyan		cbi		PORTE, 0					; Status-LED ancyan_blau:									; Grün weg --> Blau		sbic	PINC, 6						; Schalter 7 ist an, weiter mit Fader		rjmp	RGB_Ende					; Schalter aus --> RGB-Fader beenden		ldi		Speed, 128					; Grundgeschwindikeit Warteschleife		sbic	PINC, 7						; Schalter 8 ("Dimmerkurve") an?		rjmp	DK_4						; nein, weiter		ldi		Speed, 255					; ja, Geschw. an Helligkeit anpassen		sub		Speed, G		cpi		Speed, 50					; Geschwindigkeit noch >= 50?		brsh	DK_4						; ja, weiter		ldi		Speed, 50					; nein, auf 50 setzenDK_4:		rcall	warten		sbi		PORTE,0						; Status-LED aus		dec		G		brne	cyan_blau		cbi		PORTE, 0					; Status-LED anblau_magenta:								; Rot dazu --> Magenta		sbic	PINC, 6						; Schalter 7 ist an, weiter mit Fader		rjmp	RGB_Ende					; Schalter aus --> RGB-Fader beenden		ldi		Speed, 128					; Grundgeschwindikeit Warteschleife		sbic	PINC, 7						; Schalter 8 ("Dimmerkurve") an?		rjmp	DK_5						; nein, weiter		ldi		Speed, 255					; ja, Geschw. an Helligkeit anpassen		sub		Speed, R		cpi		Speed, 50					; Geschwindigkeit noch >= 50?		brsh	DK_5						; ja, weiter		ldi		Speed, 50					; nein, auf 50 setzenDK_5:		rcall	warten		sbi		PORTE,0						; Status-LED aus		inc		R		cpi		R, 255		brlo	blau_magenta		cbi		PORTE, 0					; Status-LED anmagenta_rot:								; Blau weg --> Rot		sbic	PINC, 6						; Schalter 7 ist an, weiter mit Fader		rjmp	RGB_Ende					; Schalter aus --> RGB-Fader beenden		ldi		Speed, 128					; Grundgeschwindikeit Warteschleife		sbic	PINC, 7						; Schalter 8 ("Dimmerkurve") an?		rjmp	DK_6						; nein, weiter		ldi		Speed, 255					; ja, Geschw. an Helligkeit anpassen		sub		Speed, B		cpi		Speed, 50					; Geschwindigkeit noch >= 50?		brsh	DK_6						; ja, weiter		ldi		Speed, 50					; nein, auf 50 setzenDK_6:		rcall	warten		sbi		PORTE,0						; Status-LED aus		dec		B		brne	magenta_rot				rjmp 	RGB_Loop					; Fade-Zyklus von vornRGB_Ende:		pop		temp0		ret; ------------------------------------------------------------------------------------------------; "Disco-Blink"-Routine; ------------------------------------------------------------------------------------------------Disco:		in		temp1, PINC					; DIP-Schalter abfragen		andi	temp1, 0b00000011			; nur die ersten zwei interessieren		mov		temp2, temp1				; merken, für Vgl, ob Schalter geändert		cpi		temp1, 0b00000011			; Programm 1		brne	Disco_P2		ldi     ZL, LOW(Disco_Farben_1*2)	; Z-Pointer laden Programm 1        ldi     ZH, HIGH(Disco_Farben_1*2)		rjmp	Disco_LoopDisco_P2:		cpi		temp1, 0b00000001			; Programm 2		brne	Disco_P3		ldi     ZL, LOW(Disco_Farben_2*2)	; Z-Pointer laden Programm 2        ldi     ZH, HIGH(Disco_Farben_2*2)		rjmp	Disco_LoopDisco_P3:		cpi		temp1, 0b00000010			; Programm 3		brne	Disco_P4		ldi     ZL, LOW(Disco_Farben_3*2)	; Z-Pointer laden Programm 3        ldi     ZH, HIGH(Disco_Farben_3*2)		rjmp	Disco_LoopDisco_P4:		ldi     ZL, LOW(Disco_Farben_4*2)	; Z-Pointer laden Programm 4        ldi     ZH, HIGH(Disco_Farben_4*2)Disco_Loop:				lpm		Speed, Z+					; Speed/"Ende-Flag" abfragen		tst		Speed						; Ende der Tabelle erreicht?		breq	Disco						; Ja, von vorne beginnen						in		temp1, PINC					; DIP-Schalter abfragen		andi	temp1, 0b00000011			; nur die ersten zwei interessieren		cp		temp2, temp1				; Wurde DIP-Schalter geändert?		brne	Disco						; Ja, Neustart mit neuem Programm		cbi		PORTE, 0					; Status-LED an		lpm		R, Z+						; Farben aus Tabelle holen		lpm		G, Z+		lpm		B, Z+		ldi		temp0, 64					; Grundgeschwindigkeite Disco-BlinkerDisco_warten:		sbic	PINC, 5						; Schalter 6 ist an, weiter mit Disco		ret									; Schalter aus --> Disco beenden		rcall	warten		sbi		PORTE,0						; Status-LED aus		dec		temp0		brne	Disco_warten		rjmp	Disco_Loop					; Nächste Farbe; ------------------------------------------------------------------------------------------------; Farbtabellen für Disco-Blinker-Farben; 1.Byte = Speed/Ende(255), Byte 2-4 = R, G, B; ------------------------------------------------------------------------------------------------Disco_Farben_1:.db 	128,255,0,0		; Rot.db 	128,0,255,0		; Grün.db 	128,0,0,255		; Blau.db 	128,255,0,0		; Rot.db 	128,0,255,0		; Grün.db 	128,0,0,255		; Blau.db 	64,255,0,0		; Rot.db 	64,0,255,0		; Grün.db 	64,0,0,255		; Blau.db 	64,255,0,0		; Rot.db 	64,0,255,0		; Grün.db 	64,0,0,255		; Blau.db 	128,0,255,255	; Cyan.db 	128,255,0,255	; Magenta.db 	128,255,255,0	; Gelb.db 	128,0,255,255	; Cyan.db 	128,255,0,255	; Magenta.db 	128,255,255,0	; Gelb.db 	64,0,255,255	; Cyan.db 	64,255,0,255	; Magenta.db 	64,255,255,0	; Gelb.db 	64,0,255,255	; Cyan.db 	64,255,0,255	; Magenta.db 	64,255,255,0	; Gelb.db 	0,0				; Ende TabelleDisco_Farben_2:.db 	128,255,0,0		; Rot.db 	128,0,0,255		; Blau.db 	128,210,255,255	; Weiß.db 	128,255,0,0		; Rot.db 	128,0,0,255		; Blau.db 	128,210,255,255	; Weiß.db 	64,255,0,0		; Rot.db 	64,0,0,255		; Blau.db 	64,210,255,255	; Weiß.db 	64,255,0,0		; Rot.db 	64,0,0,255		; Blau.db 	64,210,255,255	; Weiß.db 	128,255,0,0		; Rot.db 	128,0,0,255		; Blau.db 	128,210,255,255	; Weiß.db 	128,255,0,0		; Rot.db 	128,0,0,255		; Blau.db 	128,210,255,255	; Weiß.db 	64,255,0,0		; Rot.db 	64,0,0,255		; Blau.db 	64,210,255,255	; Weiß.db 	64,255,0,0		; Rot.db 	64,0,0,255		; Blau.db 	64,210,255,255	; Weiß.db 	128,255,0,0		; Rot.db 	128,210,255,255	; Weiß.db 	128,0,0,255		; Blau.db 	128,210,255,255	; Weiß.db 	128,255,0,0		; Rot.db 	128,210,255,255	; Weiß.db 	128,0,0,255		; Blau.db 	128,210,255,255	; Weiß.db 	0,0				; Ende TabelleDisco_Farben_3:.db 	255,255,90,0	; Orange.db 	255,0,0,255		; Blau.db 	255,255,90,0	; Orange.db 	255,0,255,255	; Cyan.db 	255,255,90,0	; Orange.db 	255,0,255,0		; Grün.db 	255,255,90,0	; Orange.db 	255,255,0,255	; Magenta.db 	255,0,0,255		; Blau.db 	255,255,0,255	; Magenta.db 	255,0,255,255	; Cyan.db 	255,255,0,255	; Magenta.db 	255,255,255,0	; Gelb.db 	255,0,255,0		; Grün.db 	0,0				; Ende TabelleDisco_Farben_4:.db 	64,255,0,0		; Rot.db 	64,0,0,0		; Aus.db 	64,0,255,255	; Cyan.db 	64,0,0,0		; Aus.db 	64,255,90,0		; Orange.db 	64,0,0,0		; Aus.db 	64,0,255,0		; Grün.db 	64,0,0,0		; Aus.db 	64,255,0,255	; Magenta.db 	64,0,0,0		; Aus.db 	64,255,255,0	; Gelb.db 	64,0,0,0		; Aus.db 	64,0,0,255		; Blau.db 	64,0,0,0		; Aus.db 	64,255,255,0	; Gelb.db 	64,0,0,0		; Aus.db 	0,0				; Ende Tabelle; ------------------------------------------------------------------------------------------------; ISR für Software-PWM; ------------------------------------------------------------------------------------------------ISR_PWM:    								; PWM-Ausgabe         push 	temp0        push 	temp1						; Statusregister + Temp0 sichern        in   	temp1, SREG		        ldi     temp0, 0b00000111      		; Grundzustand 1 = LED an, 0 = LED aus (wegen FET)				inc     PWM_Count              		; den PWM Zähler von 0 bis          cp      PWM_Count, R        		; Ist der Grenzwert für Rot erreicht?        brlo    PWM_G						; nein, weiter zu grün        andi    temp0, 0b00000110			; ja, LED Rot ausPWM_G:         cp      PWM_Count, G        		; Ist der Grenzwert für Grün erreicht?        brlo    PWM_B						; nein, weiter zu Blau        andi    temp0, 0b00000101			; ja, LED Grün ausPWM_B:        cp      PWM_Count, B        		; Ist der Grenzwert für Blau erreicht?        brlo    PWM_Ausgabe					; nein, weiter zur Ausgabe        andi    temp0, 0b00000011			; ja, LED Blau aus  PWM_Ausgabe:                           		; Neue Bitbelegung ausgeben        out     PORTA, temp0         out 	SREG, temp1					; Statusregister + Temp0 wiederherstellen        pop 	temp1		pop 	temp0				reti; ------------------------------------------------------------------------------------------------; Warteschleife; ------------------------------------------------------------------------------------------------warten:    									; 3 verschachtelte Warteschleifen        push 	temp2						; Statusregister + Temp sichern        push 	temp1        push 	temp0		in   	temp0, SREG        push 	temp0		mov		temp0, Speed				; Geschwindigkeit aus Register "Speed"loop0:		ldi 	temp1, 255 					; 255 Wiederholungen		sbis	PINE, 2						; Dip 9 an? -> viertelte Dauer			ldi		temp1, 64loop1:		ldi 	temp2, 2 					; 2 Wiederholungen		sbis	PINE, 1						; Dip 10 an? -> halbe Dauer			ldi		temp2, 1loop2:                          		dec     temp2		brne    loop2		dec     temp1		brne    loop1		dec     temp0		brne    loop0        pop 	temp0		out 	SREG, temp0					; Statusregister + Temp wiederherstellen        pop 	temp0		pop 	temp1		pop 	temp2		ret; ------------------------------------------------------------------------------------------------; Und Schluss; ------------------------------------------------------------------------------------------------ende: rjmp ende