0
votes

Just started learning PIC microcontrollers. For some reason, PORTB remains 0x00 and interrupt never occurs.

;*** 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

Circuit:
enter image description here

3
What effect do you expect writing the port register to have after configuring RB0 as an input? What actual signal are you applying on the pin? - doynax
@doynax I will want to connect a push button or switch to RB0 which I'll expect the interrupt to be triggered when the switch or button is 1. I'm doing this programmatically for debugging purposes. - Acha Bill
@doynax, I've edited the question - Acha Bill
@jafar, please add more details in the question about your setup, something like "I am generating the .HEX in MPLAB IDE, loading it in Proteus, running the simulation, pushing the button there and nothing happens". Otherwise people trying to answer might end up running in circles. - Luis Chavier

3 Answers

0
votes

It seems you want to programatically trigger an external interrupt on pin RB0/INT. To do this, you need to set the RB0 pin as output.

If you look at figure 4-4 in page 17 of the PIC16F84A datasheet, you can see the block diagram for pins RB3:RB0. The RB0/INT signal is connected directly to the hardware pin via a Schmitt Trigger Buffer. That means that whatever signal is present on that pin is what is going to drive the interrupt.

When you set the TRISB0 bit to 1, the 3-state buffer output will be in high impedance, meaning that the only thing that can drive the RB0/INT signal is an external electrical signal connected to the pin.

If you just set the TRISB0 bit to 0, the logic level you write to RB0 should be able to trigger the interrupt.

0
votes

You need to connect the RB0/INT pin to ground via a pull-down resistor in your circuit, otherwise the pin voltage is undefined when the button is released. You should do this:

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

With this circuit, you have:

  • Button pressed: RB0 = 1
  • Button released: RB0 = 0

Alternatively, you could wire the button like this:

RBO/INT --- Button --- GND

To use the circuit above, you need to enable the PORTB internal pull-up resistors by clearing the RBPU bit in the OPTION register. These are like internal resistors inside the chip connecting the pins to VDD, but they are disabled by default. After enabling them, you circuit essentially becomes similar to this:

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

You can also add the resistor to your circuit instead of using the internal ones. Keep in mind that for these last two circuits the polarity will be reversed, i.e.:

  • Button pressed: RB0 = 0
  • Button released: RB0 = 1
0
votes

I didn't carefully read all the answers, but it seems that the advisers forgot a simple thing: -- in the MPLAB IDE, the simulation of the change of input should be done outside the program itself, by Stimulus (Debugger/Stimulus; taking into account that the Debbuger/Select Tool should be selected prior that, e.g. to MPLAB SIM).

Regarding the pushbutton, it can go exactly as shown on the electronic diagram if and only if the internal pull-up is engaged (available only on PORTB, and done by setting the bit 7 in the OPTION REGISTER (in bank 1).

Saving the minimal context (the value of the W and STATUS registers) may not be needed always, and sometimes should not be done --- e.g. in the case when the task of the interrupt service routine is to reset W to 0. But this should be carefully investigated for each case.