I am trying to make a simple button-controlled LED, but I cannot seem to get any input from the button that would change the state of the LED. In other words, the program keeps branching to lighton, keeping the LED always on, regardless of the button state. I am using an Elegoo Uno R3.

Schematic: enter image description here

Code:

.text
.global setup
.global loop

setup:
  ser r16
  sts DDRB, r16
  ldi r16, 0b00000000
  sts DDRD, r16
  ldi r16, 0b00100000
  sts PORTB, r16
  clr r16
  sts PORTD, r16

loop:
  lds r20, PORTD
  cpi r20, 0x00 ; PORTD always equal to 0x00 ?
  breq lighton
  clr r16
  sts PORTB, r16
  rjmp loop
lighton:
  ldi r16, 0b00100000
  sts PORTB, r16
  rjmp loop

Edit: I also implemented the method in https://stackoverflow.com/questions/39361410/creating-a-toggle-switch-in-avr-assembly to create a short delay with r18 instead of del, but it didn't help; see revised loop method below:

loop:
  cpi r18, 0
  brne dec_jmp
  lds r20, PORTD
  cpi r20, 0x00 ; PORTD always equal to 0x00 ?
  breq lighton
  clr r16
  sts PORTB, r16
  ldi r18, 250
  rjmp loop
lighton:
  ldi r16, 0b00100000
  sts PORTB, r16
  ldi r18, 250
  rjmp loop

dec_jmp:
  dec r18
  rjmp loop

With delay:

lighton:
  ldi r16, 0b00100000
  sts PORTB, r16
  call delay150
  ldi r16, 0b00000000
  sts PORTB, r16
  call delay150
  rjmp loop
  • Duplicate: stackoverflow.com/questions/39361410/… – Jot Dec 5 at 19:38
  • See edit in post – Bgeo25 Dec 5 at 21:38
  • You have two potential problems in he setup: 1. You test not only PortB-bit2 (=Arduino pin 2), but all the pins of PortB. As these are floating your test (cpi r20 0x00) will never come true and the branch to lighton will never happen. 2. Your button will suffer from bouncing (google on this). Because of the 1st problem the LED should stay OFF. But it stays ON, so there is something else wrong. Break he program in small(er) parts and test each part on it's own. Did you try to switch the LED on and of by software alone (with a delay in between and not looking at the state of the switch)? – PimV Dec 5 at 22:30
  • PORTB-bit2 corresponds to Pin13, which is the output pin that I am using. From what I understand, the branch to lighton is always happening and that's the problem. For example, I removed the line that sets PORTB in the setup method, and the LED remains on. So, Pin13 is constantly being set at lighton. Also, I did try the LED by itself with a delay and it works normally. – Bgeo25 Dec 5 at 23:07
  • are you sure that the button is wired correctly? is the voltage on pin3 changing when you press the button? – jsotola Dec 6 at 6:23

Fixed it with the below code for the loop:

loop:
  sbic PIND, 2
  call nopressb
  ; button pressed
  ldi r16, 0b00100000
  out PORTB, r16
  rjmp loop
nopressb:
  ldi r16, 0b00000000
  out PORTB, r16
  rjmp loop
  • Why do you use a call to jump to nopressb? call is ment to call a subroutine and stores the return address on the stack. Because you never return from a subroutine the stack will overflow. – PimV Dec 7 at 12:26

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.