提问人:JophMax 提问时间:10/25/2023 更新时间:10/27/2023 访问量:54
为什么我的汇编程序子例程没有被执行?
Why My Assembler Subroutine doesn't get executed?
问:
我目前正在创建代码以开始一个序列,每当我按下按钮时点亮 10 个 LED。但是,当我应用我的 BTFSS 并开始在 Proteus 上进行模拟时,即使我按下按钮,一切都保持不变。
以下是该程序的代码:
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
BTFSS PORTA,0
GOTO INICIO
CALL RUTINA_1
GOTO INICIO
RUTINA_1
CALL ANTI_REBOTE
;10
CLRF TRISB
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
GOTO RUTINA_1
ANTI_REBOTE
BTFSC PORTA,0
GOTO ANTI_REBOTE
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
我在 MPLAB 中使用了 animate 选项以及将 RA0 端口设置为高电平的刺激,但仍然什么也没发生。
答:
1赞
Kozmotronik
10/26/2023
#1
PIC16F877A的模拟控制寄存器不是CMCON寄存器,而是ADCON1寄存器。根据 PIC16F877A 的数据表,第 4.1 节:
在上电复位时,这些引脚配置为模拟输入,读取为“0”。
比较器处于关闭(数字)状态
因此,无需配置 CMCON,因为它默认配置为关闭。
您需要配置的是 ADCON1 寄存器,因为 PORTA 具有模拟输入(ANx 引脚)。默认情况下,这些引脚配置为模拟引脚,因此始终读取为 0。这就是为什么当您按下 RA0 引脚上的输入按钮时没有任何反应。
这是因为这些端口与多种内部硬件(如ADC、比较器和数字缓冲器)进行多路复用。您需要选择正确的硬件来连接到输入引脚,因此它是您想要的数字缓冲器。
综上所述,将 RA0 引脚用作数字输入并将所有模拟引脚用作数字 IO 的正确设置如下:
include <p16f877a.inc>
list p=16f877a
A EQU 0x20
N EQU 0x21
M EQU 0x22
ORG 0 ; <-- Reset vector
; Setup code starts from the reset vector (program memory adress 0)
BCF STATUS,RP0
BCF STATUS,RP1 ; Bank0
CLRF PORTA ; Clear garbage on IO buffers
CLRF PORTB ; It is a good practice to reset all used output ports
CLRF PORTD ; since their values on reset is unknown.
BSF STATUS,RP0 ; Bank1
MOVLW D'6' ; Configure all ANx pins as digital IO
MOVWF ADCON1
MOVLW B'11111111' ; Set all pins of PORTA as input
MOVWF TRISA
CLRF TRISB ; Set all PORTB pins as output
CLRF TRISD ; Set all PORTD pins as output
INICIO
BTFSS PORTA,0
GOTO INICIO
CALL RUTINA_1 ; You better debounce the button press before proceeding
GOTO INICIO
评论