我用匯編語言為 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
有人有解決方案嗎?
uj5u.com熱心網友回復:
問題在這里:
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.
你正在分支到ledonresp。ledoff,這只是一個條件跳轉。但是在各個塊的末尾,您使用ret的方式就好像您通過呼叫代碼一樣[r]call。
ret將從堆疊中彈出 2 個位元組并將它們用作要回傳的字地址。代碼目標很可能有未初始化的閃存,其中包含 0xff,兩個 0xff 是 0xffff,這不是合法的 AVR 操作碼。ret0x002a 是發出非法跳轉的最后一個位元組地址。
要修復,您可以rjmp Forever代替ret,但這取決于您希望通過代碼實作的目標。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/533860.html
