Proteus中7段LED定时器出现"Invalid opcode 0xFFFF at PC=0x0014"错误求助
错误原因及解决方法
问题诊断
Proteus提示的Invalid opcode 0xFFFF at PC=0x0014,本质是中断向量地址配置错误:
- ATmega8的Timer0溢出中断(对应TOIE0)的向量地址是
0x0014,但你的代码中将中断服务程序的跳转指令放在了0x0020地址处,导致0x0014位置无有效指令(默认填充0xFFFF)。当定时器溢出触发中断时,程序计数器PC跳转到0x0014,执行空指令从而报错。
修正后的代码
.include "m8def.inc" .org 0x0000 rjmp RESET .org 0x0014 ; 修正为Timer0溢出中断的正确向量地址 rjmp TIMER0_OVF_ISR RESET: ldi r16, low(RAMEND) out SPL, r16 ldi r16, high(RAMEND) out SPH, r16 ldi r16, 0x7F out DDRD, r16 ldi r16, 0x00 out PORTD, r16 ldi r16, 0 sts COUNT, r16 ldi r16, (1<<TOIE0) out TIMSK, r16 ldi r16, (1<<CS02)|(1<<CS00) out TCCR0, r16 sei MAIN: rjmp MAIN TIMER0_OVF_ISR: push r16 push r30 push r31 lds r16, COUNT inc r16 cpi r16, 10 brlo OK ldi r16, 0 OK: sts COUNT, r16 ldi r30, low(SEGMENT*2) ldi r31, high(SEGMENT*2) add r30, r16 adc r31, r1 ; r1默认初始化为0,此处无需修改 lpm out PORTD, r0 pop r31 pop r30 pop r16 reti .cseg .equ SEG_START = 0x0060 .org SEG_START SEGMENT: .db 0b00111111 ; 0 .db 0b00000110 ; 1 .db 0b01011011 ; 2 .db 0b01001111 ; 3 .db 0b01100110 ; 4 .db 0b01101101 ; 5 .db 0b01111101 ; 6 .db 0b00000111 ; 7 .db 0b01111111 ; 8 .db 0b01101111 ; 9 .dseg COUNT: .byte 1
额外验证点
- 段码表地址计算正确:
SEGMENT*2是因为AVR程序存储器为16位字地址,而.db存储字节,用Z指针访问时需乘以2,这部分逻辑无误。 - 中断服务程序的寄存器入栈/出栈顺序正确,不会破坏主程序的寄存器状态。
内容的提问来源于stack exchange,提问作者11a4-Hạo Khiêm Trần




