I wrote this code for avr atmega328P in assembly language. It turns on and off an LED using a push button, but in proteus I am getting this error:
Invalid opcode 0xFFFF at PC=0x002A
This is my code:
.INCLUDE "M328Pdef.inc"
ldi r16,HIGH(RAMEND)
out SPH, R16
ldi r16,LOW(RAMEND)
out SPL, R16
start:
ldi r16,0xFF
out DDRB,r16
ldi r17,0x00
out DDRD,r17
ldi r21,0x00
ldi r23,0x01
Forever:
in r20,PIND
cp r20,r21
BREQ ledon
cp r20,r23
BREQ ledoff
rjmp Forever
ledon:
ldi r22,0x01
out PORTB,r22
ret
ledoff:
ldi r24,0x00
out PORTB,r24
ret
Does anyone have a solution for it?
CodePudding user response:
Problem is here:
BREQ ledon ; branch
cp r20,r23
BREQ ledoff ; branch
rjmp Forever
ledon:
ldi r22,0x01
out PORTB,r22
ret ; return from subroutine, but never used [R]CALL.
ledoff:
ldi r24,0x00
out PORTB,r24
ret ; return from subroutine, but never used [R]CALL.
You are branching to ledon
resp. ledoff
, which is just a conditional jump. But at the end of the respective blocks, you are using ret
as if you called the code by means of [r]call
.
The ret
will pop 2 bytes from the stack and use these as a word-address to return to. The code target will very likely have uninitialized flach, which holds 0xff's, and two 0xff's are 0xffff which is not a legal AVR opcode.
To fix, you could rjmp Forever
instead of ret
, but it depends on what you want to achieve with the code.