;newswich.asm ;4 LEDs on PORTB, 4 switches on PORTD ;PORTD0 SWITCH -----> PORTB0 LED ;PORTD1 SWITCH -----> PORTB1 LED ;PORTD2 SWITCH -----> PORTB2 LED ;PORTD3 SWITCH -----> PORTB3 LED ;Press a switch and corresponding the LED will lightup ;press another switch and the first LED will go off and ;the LED corresponding to the new switch will light up ;assembled using Atmel's avrasm assembler. ;the following .inc file should be placed in the same directory as ;this assembly program .include "1200def.inc" .cseg .org 0 rjmp RESET ;Reset Handle rjmp RESET rjmp RESET RESET: ldi r16, 0b11111111 ;load register r16 with all 1's out DDRB, r16 ;configure PORT B for all outputs ldi r16, 0b00000000 ;load register r16 with all 0's out DDRD, r16 ;configure PORTD for all inputs ldi r16, 255 ;all LEDs off out PORTB, r16 loopit: rcall get_switch ;call the subroutine to ;determine which switch is pressed. ;the subroutine returns the result ;in register r17 out PORTB, r17 ;output the value on PORTB rjmp loopit ;get more ;------------------------***********------------------------------- ;GET_SWITCH: Subroutine to determine which switch is pressed. ;switch on return value in r17 ; PD0 0b11111110 ; PD1 0b11111101 ; PD2 0b11111011 ; PD3 0b11110111 ;registers destroyed: r18, r19 ;subroutines called: delay20ms ;------------------------***********------------------------------- get_switch: in r18, PIND ;read PIND buffer andi r18, $0F ; cpi r18, $0F ;if no switch is pressed ;then loop back till pressed breq get_switch cpi r18, 0b00001110 ;check is SW0 is pressed brne not_0 ;if not check more its_0: rjmp next_step not_0: cpi r18, 0b00001101 ;check is SW1 is pressed brne not_1 ;if not check more its_1: rjmp next_step not_1: cpi r18, 0b00001011 ;check is SW2 is pressed brne not_2 ;if not check more its_2: rjmp next_step not_2: cpi r18, 0b00000111 ;check is SW3 is pressed brne get_switch ;if not some problem, so go back next_step: rcall delay20ms ;call a debounce delay routine waitfor_rel: ;now wait for the switch to be in r19, PIND ;be released andi r19, $0F ;when the switch is released, all cpi r19, $0F ;PIND0-3 bits will be '1' brne waitfor_rel rcall delay20ms ;OK, the switch is released ;debounce it mov r17, r18 ;put the switch code in r17 ori r17, $F0 ret ;and return ;------------------------***********------------------------------- ;DELAY20MS: A 20ms delay subroutine ;Crystal Frequency is 4MHz ;registers destroyed: r21, r20 ;------------------------***********------------------------------- delay20ms: ldi r21, 31 outer_loop: ldi r20, 255 inner_loop: nop nop nop nop nop nop nop dec r20 brne inner_loop dec r21 brne outer_loop ret