LED fader...in Assembly
I'm back with more assembly. This time it's a LED fader using PWM. To do this I vary the duty cycle of the PWM signal by incrementing the length until it reaches 255 and then decrementing until it reaches 0. This happens in an interrupt which is generated when the counter reaches TOP or 255 in the case of my settings. So I'm kinda getting 2 in 1 with this timer, PWM and an interrupt every cycle. There is one side effect of updating the PWM cycle this way and that is that the fade starts off slow and then goes fast instead of remaining the consistent. That could be solved by using another timer which is set to interrupt at the corresponding fade rate that you want.
Any way here is the code.
Any way here is the code.
/*Andrew Olson 2011 ATtiny2313 */ #include <avr/io.h> #define IO_DDRB _SFR_IO_ADDR(DDRB) #define IO_TCCR0A _SFR_IO_ADDR(TCCR0A) #define IO_TCCR0B _SFR_IO_ADDR(TCCR0B) #define IO_TIMSK _SFR_IO_ADDR(TIMSK) #define IO_OCR0A _SFR_IO_ADDR(OCR0A) .global TIMER0_OVF_vect TIMER0_OVF_vect: sbrs r1,0 ; skip if bit 0 set rjmp 2f dec r16 ; decrement brne 3f ; branch if not zero dec r1 ; we reached 0, so dec r1 rjmp 3f 2: inc r16 ; increment brvc 3f ; branch if overflow clear inc r1 ; we reached 255, so inc r1 3: out IO_OCR0A, r16 ; update cycle reti .global main main: rcall init 1: rjmp 1b init: ldi r16, (1<<COM0A1)|(1<<WGM01)|(1<<WGM00) ; non inverting fast PWM mode out IO_TCCR0A, r16 ldi r16, (1<<CS01)|(1<<CS00) ; /64 out IO_TCCR0B, r16 ldi r16, (1<<TOIE0) ; enable timer overflow out IO_TIMSK, r16 ldi r16,0x04 ; OC0A(PB2) as output out IO_DDRB, r16 ldi r16, 0x00 out IO_OCR0A, r16 clr r1 sei retI had a little trouble getting to work since I forgot to set up the data direction register and I had a small bug in the fading routine. Sorry, no video this time. But I can tell you that it's pretty cool. The fading of the light is like someone breathing when they are sleeping, slow and rhythmic. Pretty relaxing to watch.
