2016-02-05 101 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'被配置爲輸入。 –