You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

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

火山引擎 最新活动