2016-02-05 72 views
0

刚开始学习PIC单片机。由于某种原因,PORTB仍然是0x00,并且永远不会发生中断。PIC16F84_A中断不起作用

;*** COUNTER WITH INTERRUPT *** 
;***** PIC16FA4_A ************* 

ORG  0H 

STATUS EQU 03H 
PORTA EQU 05H 
PORTB EQU 06H 
TRISA EQU 85H 
TRISB EQU 86H 
INTCON EQU 0BH 
COUNT EQU 0CH 
COUNT1 EQU 08H 
COUNT2 EQU 09H 

GOTO MAIN 

;** INTERRUP ROUTINE ** 

ORG  04H 
INCF COUNT,1 
CLRF PORTB ; CLEAR RBO 
MOVLW 0AH 
SUBWF COUNT 
BTFSS STATUS,0 ;TEST FOR CARRY FLAG 
GOTO GO_ON 
GOTO CLEAR 

GO_ON 
BCF  INTCON,1 
RETFIE 

CLEAR 
CLRF COUNT 
BCF  INTCON,1 
RETFIE 
;** END OF INERRUPT ROUTINE ** 

MAIN 
BSF  INTCON,7; GLOBAL INTERRUPT ENABLE 
BSF  INTCON,4; RB0 INTERRUPT ENABLE 
BCF  INTCON,1; CLEAR INTERRUPT FLAG JUST IN CASE IT IS ON 

BSF  STATUS,5 
MOVLW 00H  ;ALL RA PINS AS OUTPUT PINS 
MOVWF TRISA 
MOVLW 01H  ;RB0 PIN AS INPUT PIN 
MOVWF TRISB 
BCF  STATUS,5 

LOOP 
MOVFW COUNT 
MOVWF PORTA ;PUT COUNT IN PORTA 
CALL DELAY ;DELAY 
MOVLW 01H  
MOVWF PORTB ;SET RB0 
;EXPECT PROGRAM CONTROL TO GO TO 04H (ORG) BUT IT DOESN'T 
;ALSO, USING THE WATCH OPTION IN DEBUGGER, PORTB STAYS 0H 
;CAN ANYONE HELP? 

GOTO LOOP 

DELAY 
LOOP1 
DECFSZ COUNT1,1 
GOTO LOOP1 
LOOP2 
DECFSZ COUNT2 
GOTO LOOP2 
RETURN  

END 

电路:
enter image description here

+1

什么影响你期望写端口寄存器有将RB0配置为输入后?你在引脚上施加什么实际信号? – doynax

+0

@doynax我想连接一个'push button'或'switch'到RB0,我期望在开关或按钮为1时触发中断。我以编程方式进行调试。 –

+0

@doynax,我编辑了问题 –

回答

0

看来你希望通过编程触发引脚RB0/INT外部中断。为此,您需要将RB0引脚设置为输出。

如果您查看PIC16F84A datasheet的第17页的图4-4,您可以看到针脚RB3:RB0的框图。 RB0/INT信号通过施密特触发缓冲器直接连接到硬件引脚。这意味着无论该引脚上出现什么信号,都会导致中断。

当您将TRISB0位设置为1时,3态缓冲器输出将处于高阻抗状态,这意味着唯一可以驱动RB0/INT信号的是连接到引脚的外部电信号。

如果您只是将TRISB0位设置为0,则您写入RB0的逻辑电平应该能够触发中断。

+0

在尝试以编程方式触发外部中断时,我将'TrisB'配置为输出。但是,当我将'portB'设置为'01H'时,即使RB0为1,程序执行也不会进入'04H'。 –

+0

您是在模拟器上还是在实际的硬件上运行?模拟器可能还没有在开发时考虑到这种细节。 –

+0

我注意到的另一件事是,您不在中断例程内保存/恢复上下文。例如,如果执行被中断,就在“BSF STATUS,5”指令后面,你将启动ISR访问Bank 1而不是Bank 0.你至少应该在ISR开始时保存'STATUS'寄存器(例如将它移动到'W'寄存器),并在'RETFIE'之前恢复它。 –

0

您需要通过电路中的下拉电阻将RB0/INT引脚接地,否则释放按钮时引脚电压不确定。你应该这样做:

RBO/INT --- Button --- VDD 
     | 
     Resistor (e.g. 10k) 
     | 
     GND 

有了这个电路,你必须:

  • 按下按钮:RB0 = 1
  • 按钮发布:RB0 = 0

或者,您可以连线Like按钮这个:

RBO/INT --- Button --- GND 

要使用上面的电路,您需要通过清除OPTION寄存器中的RBPU位来启用内部上拉电阻PORTB。这些就像芯片内部将电阻连接到VDD的电阻,但默认情况下它们是禁用的。使他们之后,你电路实质上成为与此类似:

 VDD 
     | 
     Resistor 
     | 
RBO/INT --- Button --- GND 

您也可以将电阻器添加到您的电路,而不是使用内部的人的。请记住,这些最后两个电路的极性将颠倒过来,即:

  • 按下按钮:RB0 = 0
  • 按钮发布:RB0 = 1
+0

另一方面,中断程序中的CLRF PORTB不起作用,因为'RB0'被配置为输入。 –