.include "tn13def.inc" .def TEMP = r16 .def STORE = r17 ; contains port value for the current LED .def STORE2 = r18 ; contains port value for the next LED .def OUTER = r19 ; fading counter .def INNER = r20 ; PWM counter .def TEMPx = r21 .equ DELAY = 150 ; I/O setup ; ========= ldi TEMP, 31 ; switch PB0..PB5 to output out DDRB, TEMP ldi STORE, 30 ; load start value (LED0 on) ldi STORE2, 29 ; load next value (LED1 on) LOOP: inc INNER ; increment the inner counter cpi INNER, DELAY ; have we reached the maximum value? brne GO_ON ; if yes, increment the outer one clr INNER ; reset inner counter inc OUTER ; increment outer counter cpi OUTER, DELAY breq NEXT_PHASE ; if it overflows, go to the next LED GO_ON: cp INNER, OUTER ; inner > outer? brsh THIS_LED ; if yes, the current LED needs to be on mov TEMPx, STORE2 com TEMPx out PORTB, TEMPx ; else the next one rjmp LOOP ; and start over THIS_LED: mov TEMPx, STORE com TEMPx out PORTB, TEMPx ; switch on current LED rjmp LOOP ; and start over NEXT_PHASE: clr OUTER ; reset counter mov STORE, STORE2 ; next LED lsl STORE2 ; shift current value ori STORE2, 1 ; the lsl makes the lsb 0, we need a 1 sbrs STORE2, 5 ; do we need to wrap around? ldi STORE2, 30 ; if yes, load the initial value andi STORE2, 31 ; mask bit 5 to 7 rjmp LOOP ; and start over