Description

An RGB LED is a LED which has three LED's integrated in one packaging. These LED's have the colors red, green, and blue. Such a LED costs about 1 Euro. With these three colours you can mix to any colour. When using 8-bit PWM a number of 256 * 256 * 256 combinations can be made, thus the LED can show 16.777 million colours, and 256 different brightnesses. When all the three LED's are at full brightness the color will be white.When they are all off the color will be 'black' in the dark ;). The RGB LED used here has four leads, one for each color an one for the common cathode(ground). The Red LED operates on a voltage of 2 V, Green needs 3.5 V, and the Blue LED needs also 3.5 V. Each LED draws 20mA current, so the maximum current consumption is 60mA.

Hardware

The circuit is very simple.The RGB LED is hooked up to the PWM outputs on PORTB1, PORTB2 and PORTB3 of the ATMega8. There is also a resistor between theb LED and the ATM8 to limit the current to 20mA. There is also a link to the datasheet of the RGB LED that is used in this project.

Software

The code for the fading LED is written in assembler with the AVR Studio 4. In this example the LEDs will fade in and out one by one. The PWM timers of the ATMega8 are used to let the LED's fade in and out. To use the PWM timers you first need to initialize the timers at the begin of the program code. The speed of the fading in and out can be changed with changing the clock speed of the ATM8.You can copy and paste the textfile into the AVR Studio 4.

Example program in assembler

;***** PWM demonstration with RGB LED ****
; Demonstrates how to set the PWM modes of the Timer/Counter1, 1a and 2 of the AT Mega8.
; A  RGB LED @ the PWM output at PORTB.1.2.3 fades on and off.
; Author	: www.avrprojects.net  
; Target	: ATMega8 
; Hardware	: RGB LED at PORTB1:2:3 G:B:R
;*****************************************
.include "M8def.inc"
.def Temp =r16 	; Temporary register
.def pw1 =r20	;
.def pw2 =r21	;
.def pw3 =r22	;

;***** Initialization ********************
INIT_SP:

			ldi   r16,high(RAMEND)   ;Intialize stackpointer 
      		out   SPH,r16 
      		ldi   r16,low(RAMEND) 
      		out   SPL,r16

			ldi temp,0
			out OCR1AL,temp
			out OCR1BL,temp
			out OCR2,temp
		
INIT_PORTB:
			ser	Temp
			out	DDRB,Temp			; Set PORTB to output
			clr temp
			out PORTB,temp			; Set PORTB to 0

INIT_TIMER_1AB:
			ldi	temp, 0b10100001	; Set Timer/Counter1AB, set PWM mode to clear OC1AB at upcounting, set OC1AB at downcounting 
			out	TCCR1A, temp		;
			ldi temp, 0b00000001	; Start Timer/Counter1AB 
			out TCCR1B, temp

INIT_TIMER_2:
			ldi temp, 0b01100001	; Start Timer/Counter2 , set PWM mode to clear OCR2 at upcounting
			out TCCR2, temp

;******* this is the main loop 
 
LOOP:		rcall	UP1				; call UP1 subroutine
			rcall	DN1
			rcall	UP2
			rcall	DN2
			rcall	UP3
			rcall	DN3
			rjmp 	LOOP

;******* subroutines

UP1:		inc pw1					; Increase the pulse width
			out OCR1AL,pw1			; Output to CompareRegister1A which will set the puls width
			rcall delay				; Delay of 0.01s
			cpi pw1,255				; Check if pulse width is max
			brne UP1
			ret

DN1:		dec pw1
			out OCR1AL,pw1
			rcall delay
			cpi pw1,0
			brne DN1
			ret

UP2:		inc pw2					; Increase the pulse width
			out OCR1BL,pw2			; Output to CompareRegister1B which will set the puls width
			rcall delay				; Delay of 0.01s
			cpi pw2,255				; Check if pulse width is max
			brne UP2
			ret

DN2:		dec pw2
			out OCR1BL,pw2
			rcall delay
			cpi pw2,0
			brne DN2
			ret

UP3:		inc	 pw3				; Increase the pulse width
			out OCR2,pw3			; Output to CompareRegister2 which will set the puls width
			rcall delay				; Delay of 0.01s
			cpi pw3,255				; Check if pulse width is max
			brne UP3
			ret
						
DN3:		dec pw3
			out OCR2,pw3
			rcall delay
			cpi pw3,0
			brne DN3
			ret




DELAY:								; delay of 0.01s @ 4Mhz
; ============================= 
;    delay loop generator 
          ldi  R17, $43
WGLOOP0:  ldi  R18, $C6
WGLOOP1:  dec  R18
          brne WGLOOP1
          dec  R17
          brne WGLOOP0
; ----------------------------- 
; delaying 1 cycle:
          nop
; =============================
			ret

Hex file of the assembler program
:020000020000FC
:1000000004E00EBF0FE50DBF00E00ABD08BD03BD53
:100010000FEF07BB002708BB01EA0FBD01E00EBDD3
:1000200001E605BD06D00BD010D015D01AD01FD0D8
:10003000F9CF43954ABD21D04F3FD9F708954A954E
:100040004ABD1BD04030D9F70895539558BD15D0FF
:100050005F3FD9F708955A9558BD0FD05030D9F762
:100060000895639563BD09D06F3FD9F708956A95E8
:1000700063BD03D06030D9F7089513E426EC2A95C8
:0A008000F1F71A95D9F70000089572
:00000001FF