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

Proteus仿真PIC18F4580遇栈溢出,LED控制功能异常求助

PIC18F4580 LED控制汇编代码与Proteus仿真问题

问题概述

首次使用MPLAB和Proteus开发PIC18F4580的LED控制程序,遇到两类问题:

  1. 初始代码仿真时触发栈溢出报错:[PIC18 STACK] PC=0x000E. Stack overflow is forcing device reset. [U1]
  2. 更新代码后,LED1始终常亮,按下按键后熄灭,但未实现80次高低脉冲效果,LED2也无法点亮

初始代码(触发栈溢出)

;硬件连接要求:
;(a) 按键PB接RD4,按下时RD4=0(低电平),释放时RD4=1(高电平)
;(b) LED1接RC1,RC1=0(低电平)时亮,RC1=1(高电平)时灭
;(c) LED2接RC2,RC2=1(高电平)时亮,RC2=0(低电平)时灭
;功能需求:持续监测按键,当按键按下(门打开)时,给LED1发送80次高低脉冲,之后熄灭LED1、点亮LED2;否则保持LED1亮、LED2灭

   PORTD EQU 0xF83
   PORTC EQU 0xF82
   TRISC EQU 0xF94
   TRISD EQU 0xF95
   Counter EQU 0x20
 ;LED1 > RC1 亮:0 灭:1
 ;LED2 > RC2 亮:1 灭:0
 
   BSF TRISD, 4
   BCF TRISC, 1
   BCF TRISC, 2
   
   LoopPB1:
    MOVLW D'80'
    MOVWF Counter
    Call PB1
    DECFSZ Counter
    Call LoopPB1
    BSF PORTC, 1
    BSF PORTC, 2
    return
   
   PB1:
    BCF PORTC, 1 ;置低
    BCF PORTC, 1
    return
   
   BTFSS PORTD, 4
   BCF PORTC,1
   BRA PB1
   RETURN
   
    END

更新后代码(逻辑异常)

ORG 0
    
;硬件连接与功能需求同初始代码

   PORTD EQU 0xF83
   PORTC EQU 0xF82
   TRISC EQU 0xF94
   TRISD EQU 0xF95
   Counter EQU 0x20
 ;LED1 > RC1 亮:0 灭:1
 ;LED2 > RC2 亮:1 灭:0
 
   BSF TRISD, 4
   BCF TRISC, 1
   BCF TRISC, 2
   
   MOVLW D'80'
   MOVWF Counter
   
   LoopPB1:
    MOVLW D'80'
    MOVWF Counter
    Loopn:
    BSF PORTC, 1 ;置高
    BCF PORTC, 1
    DECFSZ Counter, F
    BRA Loopn
    BSF PORTC, 2
    BSF PORTC, 1
    BRA Check
    
   Check:
   BTFSS PORTD, 4
   BRA Check
   BRA LoopPB1
    
    END

问题分析与解决建议

1. 初始代码栈溢出问题

  • 原因:LoopPB1中递归调用自身,每次调用都会占用栈空间,80次递归远超PIC18F4580的栈深度(PIC18系列栈深度通常为31级),直接导致栈溢出触发芯片复位。
  • 修复:将递归结构改为循环结构,避免反复占用栈空间。

2. 更新后代码逻辑异常问题

  • LED1无脉冲效果:脉冲序列中BSF PORTC,1后立刻BCF PORTC,1,MCU执行速度极快,肉眼无法分辨电平变化,看起来LED1一直常亮。必须添加延时子程序,让高低电平状态保持足够时长。
  • 按键触发逻辑颠倒:Check段中BTFSS PORTD,4的逻辑错误——该指令是当位为1时跳过下一条,当前逻辑变成按键未按下时死等,按下时才进入脉冲循环,与需求完全相反。
  • LED2无法保持点亮:脉冲结束后设置BSF PORTC,2,但立刻跳回Check,若按键未释放会卡在等待;若释放则重新进入循环重置LED2为低电平,导致LED2无法持续点亮。

修正后的参考代码

ORG 0

PORTD EQU 0xF83
PORTC EQU 0xF82
TRISC EQU 0xF94
TRISD EQU 0xF95
Counter EQU 0x20
;LED1: RC1=0亮,RC1=1灭
;LED2: RC2=1亮,RC2=0灭

;端口初始化
BSF TRISD, 4   ;RD4设为输入(按键)
BCF TRISC, 1   ;RC1设为输出(LED1)
BCF TRISC, 2   ;RC2设为输出(LED2)

MAIN_LOOP:
    BTFSS PORTD, 4   ;检测按键:未按下(RD4=1)则跳过下一条
    BRA DO_PULSES    ;按键按下(RD4=0)则执行脉冲序列
    
    ;按键未按下时:LED1亮,LED2灭
    BCF PORTC, 1
    BCF PORTC, 2
    BRA MAIN_LOOP

DO_PULSES:
    MOVLW D'80'
    MOVWF Counter

PULSE_LOOP:
    ;LED1灭(高电平)
    BSF PORTC, 1
    CALL DELAY       ;延时
    ;LED1亮(低电平)
    BCF PORTC, 1
    CALL DELAY       ;延时
    
    DECFSZ Counter, F
    BRA PULSE_LOOP

    ;脉冲完成后:LED1灭,LED2亮
    BSF PORTC, 1
    BSF PORTC, 2
    
    ;等待按键释放
WAIT_RELEASE:
    BTFSC PORTD, 4   ;按键仍按下(RD4=0)则跳过下一条,继续等待
    BRA MAIN_LOOP    ;按键释放(RD4=1)则返回主循环
    BRA WAIT_RELEASE

;延时子程序(可根据需求调整延时长度)
DELAY:
    MOVLW 0xFF
    MOVWF 0x21
DELAY_LOOP1:
    MOVLW 0xFF
    MOVWF 0x22
DELAY_LOOP2:
    DECFSZ 0x22, F
    BRA DELAY_LOOP2
    DECFSZ 0x21, F
    BRA DELAY_LOOP1
    RETURN

END

原理图注意事项

  • 按键RD4需配置上拉电阻(或启用MCU内部上拉),确保未按下时RD4为高电平,按下时为低电平。
  • LED1需串联限流电阻,连接方式为RC1→电阻→LED→GND(符合RC1=0时LED亮的逻辑);LED2连接方式为VCC→电阻→LED→RC2(符合RC2=1时LED亮的逻辑)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 21:31:11