Momentary switch to light On-board LED

This is my first attempt at interrupts using assembly. The objective is to illuminate on-board LED (Pin13) while button is being held down and out of the 30 or so tries, only once did I get a problem with bounce. I’m not to worried about that, but would like some input if the method I chose is the best. Accomplishing the job with the least amount of instructions is the objective.

 Button:   in	    r20, SREG
	  push	    r20
	  in	    r20, PORTB
	  ldi	    r19, (1 << PD5)
	  eor	    r20, r19
	  out	    PORTB, r20
	  pop	    r20
	  out	    SREG, r20

This is using Studio 7.0.1006 for a Mega328P. Code is tested on a Makerdunio Uno 3.0

main.txt (3.03 KB)

Welcome to the forum.

As you have said, assembly code, unfortunately most of the forum members are C++ programmers.
OP’s Code

	  jmp		InitDevice	; Reset Handler
	  jmp		Button		; IRQ0 Handler
	  jmp		EXT_INT1	; IRQ1 Handler
	  jmp		PCINT0_H	; PCINT0 Handler
	  jmp		PCINT1_H	; PCINT1 Handler
	  jmp		PCINT2_H	; PCINT2 Handler
	  jmp		WDT		; Watchdog Timer Handler
	  jmp		TIM2_COMPA	; Timer2 Compare A Handler
	  jmp		TIM2_COMPB	; Timer2 Compare B Handler
	  jmp		TIM2_OVF	; Timer2 Overflow Handler
	  jmp		TIM1_CAPT	; Timer1 Capture Handler
	  jmp		TIM1_COMPA	; Timer1 Compare A Handler
	  jmp		TIM1_COMPB	; Timer1 Compare B Handler
	  jmp		TIM1_OVF	; Timer1 Overflow Handler
	  jmp		TIM0_COMPA	; Timer0 Compare A Handler
	  jmp		TIM0_COMPB	; Timer0 Compare B Handler
	  jmp		TIM0_OVF	; Timer0 Overflow Handler
	  jmp		SPI_STC		; SPI Transfer Complete Handler
	  jmp		USART_RXC	; USART, RX Complete Handler
	  jmp		USART_UDRE	; USART, UDR Empty Handler
	  jmp		USART_TXC	; USART, TX Complete Handler
	  jmp		ADC_H		; ADC Conversion Complete Handler
	  jmp		EE_RDY		; EEPROM Ready Handler
	  jmp		ANA_COMP	; Analog Comparator Handler
	  jmp		TWI		; 2-wire Serial Interface Handler
	  jmp		SPM_RDY		; Store Program	Reset:

; ==============================================================================================

	  ldi	    r16, high (RAMEND)
	  out	    SPH, r16
	  ldi	    r16, low (RAMEND)
	  out	    SPL, r16

	  ; Now setup board for desired interrupt type and input pin
	  ldi	    r20, (1 << ISC00)
	  sts	    EICRA, r20		; interrupt 0 will trigger on any logical change
	  ldi	    r20, (1 << INT0)
	  out	    EIMSK, r20		; Enable interrupt 0
	  sbi	    DDRB, PB5		; Set digital pin 13 as output (LED)
	  sbi	    PORTD, PIND2

	  sei				; This is so interrupt will fall through to Main loop

; ==============================================================================================
  Main:	  nop
	  rjmp      Main

; ----------------------------------------------------------------------------------------------
  Button: in	    r20, SREG
	  push	    r20
	  in	    r20, PORTB
	  ldi	    r19, (1 << PD5)
	  eor	    r20, r19
	  out	    PORTB, r20
	  pop	    r20
	  out	    SREG, r20
EXT_INT1:		; IRQ1 Handler
PCINT0_H:		; PCINT0 Handler
PCINT1_H:		; PCINT1 Handler
PCINT2_H:		; PCINT2 Handler
WDT:			; Watchdog Timer Handler
TIM2_COMPA:		; Timer2 Compare A Handler
TIM2_COMPB:		; Timer2 Compare B Handler
TIM2_OVF:		; Timer2 Overflow Handler
TIM1_CAPT:		; Timer1 Capture Handler
TIM1_COMPA:		; Timer1 Compare A Handler
TIM1_COMPB:		; Timer1 Compare B Handler
TIM1_OVF:		; Timer1 Overflow Handler
TIM0_COMPA:		; Timer0 Compare A Handler
TIM0_COMPB:		; Timer0 Compare B Handler
TIM0_OVF:		; Timer0 Overflow Handler
SPI_STC:		; SPI Transfer Complete Handler
USART_RXC:		; USART, RX Complete Handler
USART_UDRE:		; USART, UDR Empty Handler
USART_TXC:		; USART, TX Complete Handler
ADC_H:			; ADC Conversion Complete Handler
EE_RDY:			; EEPROM Ready Handler
ANA_COMP:		; Analog Comparator Handler
TWI:			; 2-wire Serial Interface Handler
SPM_RDY:		; Store Program	Reset:

Some of us have used assembly code.
It was a long time ago since I used it, and using interrupts in assembly code does not come readily to mind.
Mine was with Z80.

Have you googled?

Tom… :slight_smile:


I have researched quite a few examples, but as informative as some are, they still didn't explain the why. As an example, I first tried to use a method that didn't really end up being any more efficient space wise, but logic dictated that toggling bit PD5 with SBI & CBI would work. Not so, so that tells me data must have to be latched using IN & OUT.

So far the most valuable resource has been the Atmel328 DataSheet.


NOTE: I changed to LED on PIN 7 instead of onboard LED.

This now has solved the problem of inverted logic due to bounce, because instead of toggling output pin, I'm following the logic of INT0 and inverting it so when button is pushed (LOW), I'm turning the LED on. I'm also getting a better handle on when IN/OUT & SBI/CBI can be used.

Btn:	  push	    r20
	  in	    r20, SREG
	  push	    r20			; Preserve stack pointer

	  sbis	    PIND, 2
	  rjmp	    LED_Off
	  sbi	    PORTD, PIND7
	  rjmp	    LED_Off + 1	  	      
LED_Off:  cbi	    PORTD, PIND7
	  pop	    r20			; Restore stack pointer
	  out	    SREG, r20
	  pop	    r20

This snippet might even be useful for testing dirty switches as if the pluses aren't to narrow one should see the LED flicker.