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

为何PIC16F877A汇编子程序无法执行?按键触发LED无响应

问题分析与解决方案

核心问题点

  • 按键检测逻辑与硬件不匹配:如果你的按键是下拉式(按下时RA0为低电平),BTFSS PORTA,0会在RA0为高时跳过跳转,与实际触发逻辑完全相反;如果是上拉式按键,当前消抖函数的逻辑会直接卡住程序。
  • 消抖函数逻辑冲突:当前ANTI_REBOTE是等待RA0变为低才返回,但主程序是检测RA0为高才进入LED序列,两者逻辑矛盾,导致程序无法正常执行。
  • 冗余代码冗余:RUTINA_1中重复执行CLRF TRISB,端口方向配置在初始化阶段已经完成,无需重复设置。

修改后的代码

include <p16f877a.inc>
list p=16f877a

A EQU 0x20
N EQU 0x21
M EQU 0x22

BSF STATUS,5
MOVLW B'11111111'
MOVWF TRISA
CLRF TRISB
CLRF TRISD
BCF STATUS,5
MOVLW D'7'
MOVWF CMCON
CLRF PORTA
CLRF PORTB
CLRF PORTD

INICIO
BTFSC PORTA,0  ; 改为BTFSC:适配下拉按键,按下时RA0为低则跳过跳转
GOTO INICIO
CALL ANTI_REBOTE  ; 先消抖确认按键稳定
CALL RUTINA_1
GOTO INICIO

RUTINA_1
; 移除冗余的CLRF TRISB
;10路LED序列开始
MOVLW B'00000010'
MOVWF PORTD
MOVLW D'200'
MOVWF A
CALL RETARDO
;9
MOVLW B'00000001'
MOVWF PORTD
MOVLW D'200'
MOVWF A
CALL RETARDO
;8
CLRF PORTD
MOVLW B'10000000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;7
MOVLW B'01000000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;6
MOVLW B'00100000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;5
MOVLW B'00010000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;4
MOVLW B'00001000'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;3
MOVLW B'00000100'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;2
MOVLW B'00000010'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
;1
MOVLW B'00000001'
MOVWF PORTB
MOVLW D'200'
MOVWF A
CALL RETARDO
RETURN  ; 序列执行完返回主循环,而非无限循环

ANTI_REBOTE
; 消抖:等待按键电平稳定(RA0保持低电平一段时间)
MOVLW D'20'
MOVWF A
DELAY_DEBOUNCE
    MOVLW D'80'
    MOVWF M
DELAY_INNER
    NOP
    NOP
    DECFSZ M,1
    GOTO DELAY_INNER
    DECFSZ A,1
    GOTO DELAY_DEBOUNCE
; 等待按键松开,避免单次按下触发多次序列
WAIT_RELEASE
    BTFSC PORTA,0
    GOTO WAIT_RELEASE
RETURN

RETARDO
TRES
    MOVLW D'80'
    MOVWF M
DOS
    MOVLW D'25'
    MOVWF N
UNO
    NOP
    NOP
    DECFSZ N,1
    GOTO UNO
    DECFSZ M,1
    GOTO DOS
    DECFSZ A,1
    GOTO TRES
RETURN
END

关键修改说明

  1. 按键检测逻辑修正:将BTFSS PORTA,0改为BTFSC PORTA,0,适配下拉式按键(按下时RA0为低);如果是上拉式按键(按下时RA0为高),则保留BTFSS,同时修改消抖函数为等待RA0高电平稳定。
  2. 消抖函数重构:先等待按键电平稳定,再等待按键松开,避免程序因逻辑冲突卡住,同时防止单次按下触发多次LED序列。
  3. 移除冗余代码:删除RUTINA_1中的CLRF TRISB,端口方向只需初始化一次。
  4. 序列执行逻辑调整:将RUTINA_1末尾的GOTO RUTINA_1改为RETURN,执行完一次LED序列后回到主循环等待下一次按键触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:56:37