MPLAB,试图清除一点,但它仍然是1

问题描述:

我正在使用MPLAB为我的项目编程PIC16F84A。我有一个汇编代码,其中RB4-7位连接到按钮,因此用作输入。一个中断子程序被实现来处理任何新的中断(当一个按钮被按下时)。一切正常,当按下按钮时,图片会转到指定的子程序。但现在,当我在子程序中时,我必须清除该标志(INTCON - RBIF),但该标志未被清除,但清除INTCON寄存器中的任何其他位都可以正常工作。所以我该怎么做?MPLAB,试图清除一点,但它仍然是1

这里是我的代码:

 ORG  0X00 
     GOTO START 
     ORG  0x04 
     BTFSC INTCON,RBIF 
     GOTO RBX_INT 
START CLRF PORTA 
     MOVLW B'10001000' 
     MOVWF INTCON 
     BSF  STATUS,RP0 
     CLRF TRISA 
     MOVLW B'11110000' 
     MOVWF TRISB 
     MOVLW B'10000111' 
     MOVWF OPTION_REG 
     BCF  STATUS,RP0 
MAIN GOTO MAIN 

这是我的子程序:

RBX_INT BCF  INTCON,RBIF 
     MOVLW D'156' 
     CALL DELAY 
     RETFIE 
+1

如果这是一个“变更中断”,即使您不需要知道状态,您也需要**读取**端口。如果你不这样做,触发中断的逻辑将继续触发。 –

+0

@RogerRowland是的,这是问题所在。 – kamal

,应清除该位从中断返回的权利之前,否则新的中断可能已经发生,而在delay循环和RBIF将被再次清除。发生这种情况是因为按钮反弹(https://en.wikipedia.org/wiki/Switch#Contact_bounce)。

此外,数据表规定:

输入引脚(RB7的:RB4) 与锁定在最后 读PORTB的旧值进行比较。 RB7:RB4 的“不匹配”输出被OR运算在一起产生RB端口变化 标志位RBIF(INTCON < 0>)的中断。

这意味着您必须在清除RBIF之前阅读PORTB以更新锁存值。

RBX_INT 

    MOVFW PORTB  ;Read PORTB to update the latch. 
    MOVLW D'156' 
    CALL DELAY 
    BCF  INTCON,RBIF ;Clear interrupt flag as close as possible to RETFIE. 
    RETFIE 

此外,您应该了解有关中断服务例程的上下文保存/恢复。在这个例子中,它并不重要,因为主循环什么也不做,只是因为中断可能随时发生,所以应该注意保存它使用的所有寄存器和资源,并在退出中断之前恢复它们以防止损坏来自任何数据/状态主代码路径。

见部分

6.9 现场保护中断

在PIC16F84A数据表时。

+0

延迟已经在处理反弹效应。我已经做了你的建议,但没有奏效。 – kamal

+0

只要您清除RBIF,PORTB上的任何活动都会在硬件中重新设置。延迟仅在清除RBIF之前执行时才有所帮助。 – Unimportant

+1

是的你说的是正确的,但那不是我的问题。该标志未被设置为零。我正在使用刺激来触发中断,并且我正在查看每一步的位数,但仍然没有清除RBIF。 – kamal