; led-1.1.asm; Tri-color LED circuit test code (08/2005) ; Uses the at90s2343 ;--- GENERAL DEFINATIONS --- .equ clk_freq = 1 ; System clock frequency in MHz ;--- REGISTER DEFINITIONS --- .def state_cnt = r16 ; State counter (0...99) .def red_br = r17 ; Red LED brightness level (0=off 99=99.97%) .def green_br = r18 ; Green LED brightness level .def blue_br = r19 ; Blue LED brightness level .def tmp = r20 ; macro.asm scratchpad register .def flags = r21 ; Direction control flags .equ red_dir = 0x00 ; Red brightness inc=1/dec=0 flag .equ green_dir = 0x01 ; Green version of above .equ blue_dir = 0x02 ; Blue version of above ;--- PORT D DEFINITIONS --- ; (None) ;--- PORT B DEFINITIONS --- .equ blue_LED = 0 ; The blue LED output pin 0=on, 1=off .equ green_LED = 1 .equ red_LED = 2 .equ ser_in = 3 ; Serial data input pin 1=mark, 0=space .equ test = 4 ; test output ; pb76543210 .equ portB_defs = 0b00010111 ; (unused pins left as inputs) ;--- INTERRUPT VECTORS --- .org 0 RESET_V: rjmp main ; RESET vector EXT_INT0_V: rjmp INTR0 ; Int 0 vector TIM0_OVF_V: rjmp TIMR0_OVF ; Timer 0 overflow vector ;--- INCLUDES --- .include "../include/2343def.inc" .include "../include/macro.asm" ;--- LOCAL MACROS .macro all_on cbi PORTB, red_LED cbi PORTB, green_LED cbi PORTB, blue_LED .endmacro .macro red_off sbi PORTB, red_LED .endmacro .macro green_off sbi PORTB, green_LED .endmacro .macro blue_off sbi PORTB, blue_LED .endmacro ;--- THE PROGRAM --- main: SP_load RAMEND ; initialize stack pointer DDRB_write portB_defs ; set up port B red_off ; turn off all LEDs green_off blue_off TIMR0_div_1 ; set up and start timer0 TIMR0_INT_ENABLE ldi red_br, 0 ; set brightness values for test ldi green_br, 33 ldi blue_br, 66 sei ; enable interrupts loop: sbi PORTB, test nop ; wait for ints cbi PORTB, test nop red: cpi red_br, 99 ; Are we at max brightness? brne red_min_br ; No. check for min brightness clt ; Yes. set red_dir bld flags, red_dir ; to "down" rjmp red_action ; And go inc or dec red_min_br: tst red_br ; Are we at min brightness? (red_br=0) brne red_action ; No. go inc or dec set ; Yes. set red_dir bld flags, red_dir ; to "up" red_action: bst flags, red_dir ; Get a copy of the red_dir flag brtc red_dec ; if red_dir = 0, dec red_br instead inc red_br ; No, it is 1. so inc it rjmp green ; Next color red_dec: dec red_br ; red_dir = 0, so dec it green: cpi green_br, 99 ; Are we at max brightness? brne green_min_br ; No. check for min brightness clt ; Yes. set green_dir bld flags, green_dir ; to "down" rjmp green_action ; And go inc or dec green_min_br: tst green_br ; Are we at min brightness? (green_br=0) brne green_action ; No. go inc or dec set ; Yes. set green_dir bld flags, green_dir ; to "up" green_action: bst flags, green_dir ; Get a copy of the green_dir flag brtc green_dec ; if green_dir = 0, dec green_br instead inc green_br ; No, it is 1. so inc it rjmp blue ; Next color green_dec: dec green_br ; green_dir = 0, so dec it blue: cpi blue_br, 99 ; Are we at max brightness? brne blue_min_br ; No. check for min brightness clt ; Yes. set blue_dir bld flags, blue_dir ; to "down" rjmp blue_action ; And go inc or dec blue_min_br: tst blue_br ; Are we at min brightness? (blue_br=0) brne blue_action ; No. go inc or dec set ; Yes. set blue_dir bld flags, blue_dir ; to "up" blue_action: bst flags, blue_dir ; Get a copy of the blue_dir flag brtc blue_dec ; if blue_dir = 0, dec blue_br instead inc blue_br ; No, it is 1. so inc it rjmp dlay ; We're done with colors, do the delay blue_dec: dec blue_br ; blue_dir = 0, so dec it dlay: dec r8 brne dlay dec r9 brne dlay ; dec r10 ; brne dlay rjmp loop ;--- SUBROUTINES --- ; (None) ;--- INTERRUPT SERVICE ROUTINES --- INTR0: reti ; (not used) TIMR0_OVF: ; Timer overflow sends us here every 100us ; numbers in () are worst case number of clock cycles ; 10 + (3*5) + 6 = 31 cycles max. ldi tmp, 156 ; Reset TIMR0 out TCNT0, tmp ; to overflow in 100uS cpi state_cnt, 100 ; (1) state_counter overflow? brne red_test ; (2) no. continue clr state_cnt ; (1) yes, reset state_counter to 0 all_on ; (6) and turn all LEDs on red_test: cp state_cnt, red_br ; (1) red_br > state_counter? brcs green_test ; (2) yes. leave LED on, next test red_off ; (2) no. turn off LED green_test: cp state_cnt, green_br ; (same for green) brcs blue_test green_off blue_test: cp state_cnt, blue_br ; (same for blue) brcs colors_done blue_off colors_done: inc state_cnt ; (1) next state reti ; (5) ; EOF: led-1.1.asm