Muh*_*mar 2 microcontroller assembly avr atmega32
我用汇编语言为 avr atmega328P 编写了这段代码。它使用按钮打开和关闭 LED,但在 proteus 中我收到此错误:
PC=0x002A 处的无效操作码 0xFFFF
这是我的代码:
.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
Run Code Online (Sandbox Code Playgroud)
有人有解决办法吗?
ema*_*uts 10
问题就在这里:
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.
Run Code Online (Sandbox Code Playgroud)
您正在分支到ledonresp。ledoff,这只是一个条件跳转。但在各个块的末尾,您使用的ret方式就好像通过[r]call.
将从ret堆栈中弹出 2 个字节并将它们用作要返回的字地址。代码目标很可能具有未初始化的闪存,其中包含 0xff,并且两个 0xff 是 0xffff,这不是合法的 AVR 操作码。ret0x002a 是最后一个发出非法跳转的字节地址。
要修复,您可以rjmp Forever代替ret,但这取决于您想要通过代码实现的目标。