You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Proteus仿真报错:Invalid opcode 0xFFFF at PC=0x8C02 求助

Proteus仿真错误排查:Invalid opcode 0xFFFF at PC=0x8C02

运行Proteus仿真时出现错误提示:Invalid opcode 0xFFFF at PC=0x8C02,附上我的AVR汇编代码和电路图,请求排查问题:

我的AVR汇编代码

START:
    LDI R18, 0XFF
    OUT DDRB, R18 //LET PORT B AS OUTPUT
    LDI R16, 0B01110101
    OUT TCCR0A, R16
    LDI R17, 0B01110101
    OUT TCCR0B, R17
    LDI R24, 0XFF
    OUT DDRD, R24 // LET PORT AS INPUT
    OUT OCR0A, R18


MAIN:

    IN R18, PINB //LOAD PORT B TO R18
    CPI R18, 0B00000000 //CHECK IF R18 == 0
    BREQ SPEED1 // JUMP TO SPEED1 IF R18 == 0
    OUT OCR0A, R16
    OUT OCR0B, R17

    IN R18, PINB //LOAD PORTB TO R18
    CPI R18, 0B00000001 //CHECK IF R18 == 1
    BREQ SPEED2 // JUMP TO SPEED2 IF R18 == 1
    OUT OCR0A, R16
    OUT OCR0B, R17

    IN R18, PINB //LOAD PORTB TO R18
    CPI R18, 0B00000010 //CHECK IF R18 == 2
    BREQ SPEED3 // JUMP TO SPEED3 IF R18 == 2
    OUT OCR0A, R16
    OUT OCR0B, R17

    IN R18, PINB //LOAD PORTB TO R18
    CPI R18, 0B00000011 //CHECK IF R18 == 1
    BREQ SPEED4 // JUMP TO SPEED4 IF R18 == 3
    OUT OCR0A, R16
    OUT OCR0B, R17

    RJMP MAIN

SPEED1:
    LDI R16, 0B00000001
    OUT PORTD, R16
    LDI R17, 255
    RET

SPEED2:
    LDI R16, 0B00000001
    OUT PORTD, R16
    LDI R17, 180
    RET

SPEED3:
    LDI R16, 0B00000001
    OUT PORTD, R16
    LDI R17, 100
    RET

SPEED4:
    LDI R16, 0B00000001
    OUT PORTD, R16
    LDI R17, 0
    RET

我的Proteus电路图

Proteus电路图


问题排查与修正

1. 核心错误:RET指令误用

这是触发Invalid opcode错误的直接原因:

  • 你通过BREQ跳转指令进入SPEED1-SPEED4代码块,但这些代码块末尾用的是RET指令。
  • RET是子程序返回指令,必须配合CALL使用(CALL会把当前PC值压入堆栈,RET再弹出恢复PC)。而BREQ只是直接跳转,没有压栈操作,执行RET时会从堆栈读出无效值(0xFFFF),导致PC指向无效内存,触发错误。

修正方法:把所有RET替换成RJMP MAIN,直接跳回主循环。

2. 其他逻辑/注释错误

  • DDRD注释矛盾:代码中OUT DDRD, R24设置R24为0xFF(输出模式),但注释写的是LET PORT AS INPUT,如果PORTD是输入,应设置DDRD为0x00;如果是输出,修正注释即可。
  • SPEED4判断注释错误:CPI R18, 0B00000011是判断R18是否等于3,但注释写的是CHECK IF R18 == 1,需修正注释为CHECK IF R18 == 3。
  • MAIN循环冗余代码:每次判断后都重复执行OUT OCR0A, R16和OUT OCR0B, R17,这些代码仅在不触发跳转时执行,可优化结构(比如把输出放在所有判断之后)。
  • Timer0配置合理性:TCCR0A和TCCR0B都设置为0B01110101,对应快速PWM模式(WGM0[2:0]=111),CS0[2:0]=101对应1024分频,需确认是否符合你的PWM输出需求。

修正后的示例代码

START:
    LDI R18, 0XFF
    OUT DDRB, R18 // PORT B 设置为输出
    LDI R16, 0B01110101
    OUT TCCR0A, R16
    LDI R17, 0B01110101
    OUT TCCR0B, R17
    LDI R24, 0XFF
    OUT DDRD, R24 // PORT D 设置为输出(修正注释)
    OUT OCR0A, R18


MAIN:
    IN R18, PINB // 读取PORT B状态到R18
    
    CPI R18, 0B00000000 // 判断是否等于0
    BREQ SPEED1 
    
    CPI R18, 0B00000001 // 判断是否等于1
    BREQ SPEED2 
    
    CPI R18, 0B00000010 // 判断是否等于2
    BREQ SPEED3 
    
    CPI R18, 0B00000011 // 判断是否等于3(修正注释)
    BREQ SPEED4 
    
    // 所有判断不触发时,更新OCR0值
    OUT OCR0A, R16
    OUT OCR0B, R17

    RJMP MAIN

SPEED1:
    LDI R16, 0B00000001
    OUT PORTD, R16
    LDI R17, 255
    RJMP MAIN // 替换RET,跳回主循环

SPEED2:
    LDI R16, 0B00000001
    OUT PORTD, R16
    LDI R17, 180
    RJMP MAIN

SPEED3:
    LDI R16, 0B00000001
    OUT PORTD, R16
    LDI R17, 100
    RJMP MAIN

SPEED4:
    LDI R16, 0B00000001
    OUT PORTD, R16
    LDI R17, 0
    RJMP MAIN

内容的提问来源于stack exchange,提问作者acemal9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 09:20:22