title: Assembly executing ButtonClick state only once
body: <p>I'm working on a simple button-led project using <code>Atmega2560</code> microcontroller. I have a problem with the buttons. When I click the button, main loop stops working and button function keeps running infinite times as long as I'm pressing the button. Main-loop should not stop when I press the button. And the button function must only be run once. How can i do that ?</p>
  
  <pre><code>.def LEDS = R16
  .def LED_DATA = R21
  
  .org 0
      rjmp MAIN
  
  MAIN:
      ldi LEDS, 0xFF  ; 0xFF = 1111 1111
  
      ldi LED_DATA, 0x01
  
      out DDRC, LEDS  ; PORTC
      sbi PORTB, 0
      sbi PORTB, 1
  
  LOOP_MAIN:
      sbis PINB, 0        ; If PORTB-0's pin = 1, skip next
      rjmp BUTTON_CLICK_H
  
      sbis PINB, 1
      rjmp BUTTON_CLICK_Y 
  
      call DELAY
      out PORTC, LED_DATA
  
      lsl LED_DATA
      brcc SHIFT_0_IN     ;if carry not set, the MSB was not set, so skip setting the LSB
      ori LED_DATA, 1
  
      SHIFT_0_IN:         ; keep LSB as 0 -&gt; do nothing, just continue
      rjmp LOOP_MAIN
  
      END:
      rjmp LOOP_MAIN
  
  
  BUTTON_CLICK_H:
      lsl LED_DATA
      cpi LED_DARA, 0x40
      breq SPEED_RESET
      rjmp SPEED_END
      SPEED_RESET:
      ldi LED_SPEED, 0x04
      SPEED_END:
      rjmp LOOP_MAIN
  </code></pre>
  
  <p><strong>EDIT:  (11/26/2017)</strong></p>
  
  <p>I wrote a simple button controller. The purpose of this controller is, to check whether the button is pressed or not or kept pressing. button code should only work once. But it does not work when I press the button. Where am I making mistakes?</p>
  
  <pre><code>.def BTN_STATE_FIRST = R23
  .def BTN_STATE_CHANGED = R24
  .def BTN_STATE_PINB = R25
  .def BTN_STATE_TEMP = R26
  
  LOOP_MAIN:
      out PORTC, LED_DATA         
      call LOOP_BUTTON        
      call DELAY  
  
      ; ...Codes
  
      rjmp LOOP_MAIN
  
  LOOP_BUTTON:
  
      ; (Is the button pressed, not pressed or kept pressed?) Controller
  
      in BTN_STATE_PINB, PINB     ; Read PINB data and put it current state in BTN_STATE_PINB
      mov BTN_STATE_TEMP, BTN_STATE_PINB  ; Move it to BTN_STATE_TEMP
      eor BTN_STATE_PINB, BTN_STATE_FIRST ; XOR BTN_STATE_PINB and BTN_STATE_FIRST. And write result to the BTN_STATE_PINB
      mov BTN_STATE_FIRST, BTN_STATE_TEMP ; Move it the BTN_STATE_FIRST
      breq BUTTON_PRESSED
      brne BUTTON_NOTPRESSED
  
      BUTTON_PRESSED:
      cpi BTN_STATE_PINB, 0x01    ; 1st button 0x01, 2nd button 0x02, 3rd button 0x04
      breq BUTTON_CHANGED
      rjmp BUTTON_NOTPRESSED
  
      BUTTON_CHANGED:
      cpi BTN_STATE_CHANGED, 0x01 ; When pressed and held, have been processed before ? 0x01 true, 0x00 false
      breq BUTTON_UP              ; If yes, branch to BUTTON_UP
      brne BUTTON_DOWN            ; Otherwise, branch to BUTTON_DOWN
  
      BUTTON_UP:
      dec BTN_STATE_CHANGED       ; Decrement the BTN_STATE_CHANGED to 0x00
  
      ldi LED_DATA, 0x40
  
      rjmp BUTTON_END
  
      BUTTON_DOWN:
      inc BTN_STATE_CHANGED       ; Increment the BTN_STATE_CHANGED to 0x01
  
      ldi LED_DATA, 0x80
  
  
      BUTTON_END:
      BUTTON_NOTPRESSED:
  
      ret
  </code></pre>