hexpheus
hexpheus

Reputation: 761

AVR LED on-off program in assembly using buttons

I'm writing assembly code for ATMEL ATmega16 using AtmelStudio 7. I just want to turn on an LED while I press a button and I want it to be off when I press it again. Exactly like a room light. For some reason this code only turns the light on and never goes off with pressing the button (button is simulated in proteus). Can anyone help me with this simple code?

start:
    /* set the PIND2 data direction to 0 for input */
    /* This one simulates the key */
    ldi R16, (0 << PD2) ; Make PD2 as input
    out DDRB,R16    ; Configure the PIND2 as input

    /* set the PORTB7 data direction to 1 for output */
    /* this one causes the LED to be ON/OFF */
    ldi R17, (1 << PB7) ; Make PB7 as output 
    out DDRB,R17    ; Configure the PORTB7 as output

OFF_MODE:
    /* Put the PORTB7 to 0 */ 
    ldi R18,(0 << PB7)
    out PORTB,R18
    call delay
    /* Skip if PIN 2 in PORT D is set */
    sbis PIND,2
    jmp OFF_MODE    ; Branch to the OFF_MODE if the key isn't pressed yet

ON_MODE:
    /* Put the PORTB to 1 */
    ldi R18,(1 << PB7)
    out PORTB,R18
    call delay
    /* Skip if PIN 2 in PORT D is set */
    sbis PIND,2
    jmp ON_MODE ; Branch to the ON_MODE if the key isn't unpressed yet
rjmp start
delay:
    ldi r16, 0xFF
delay_loop_1:
    dec r16
    cpi r16, 0x00
    jmp delay_loop_1
ret

Upvotes: 1

Views: 4807

Answers (1)

nopasara
nopasara

Reputation: 536

You have an infinite loop in your delay function. Mind using:

delay:
    ldi r16, 0xFF
delay_loop_1:
    dec r16
    brne delay_loop_1
    ret

Upvotes: 1

Related Questions