Understanding interrupt on port state change

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
I need help in understanding how a state change interrupt works. More specifically, what kind of event can create a state change.

My specific example is, a PIC micro powered with 5V to Vdd, and a switch to a port B pin that is normally open (at 0V). Will throwing the switch to supply that Port B pin with +5V be considered a "state change"?

If that does induce a state change, would it essentially make that bit go from 0 to 1 assuming the voltage remains constant until the switch is thrown again?

If yes, can I tell the the software to: (paraphrasing here)

run normal program
test port b pin skip if 0
if 1 (voltage applied) goto a subroutine
if 0 continue normal program


I understand the need to enable interrupts in the INTCON register and also clear any interrupt flags after the interrupt is complete.

Thanks
 

rjenkins

Joined Nov 6, 2005
1,013
Depending on the PIC, I believe you can configure the interrupt to fire on either low-to-high, high-to-low or both.

The program you describe does not appear to need this interrupt, you would just read the switch input pin each time and take the appropriate branch if the pin is high.
(Don't forget the pulldown resistor to ensure a low level when the switch is open).

I've used interrupt on change, but only as a means of waking up a battery powered device when a keypad button was pressed. Whilst the device was running normally, I polled the inputs during it's RTC interrupt routine.
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Hi Ke5nnt
Which PIC uC do you use, and what language do you program in
At the moment a PIC 16F628A, and Assembly.

rjenkins said:
Depending on the PIC, I believe you can configure the interrupt to fire on either low-to-high, high-to-low or both.

The program you describe does not appear to need this interrupt, you would just read the switch input pin each time and take the appropriate branch if the pin is high.
(Don't forget the pulldown resistor to ensure a low level when the switch is open).

I've used interrupt on change, but only as a means of waking up a battery powered device when a keypad button was pressed. Whilst the device was running normally, I polled the inputs during it's RTC interrupt routine.
Thanks, I'll try that. Appreciate the input (no pun intended).

Regards.
 

eng1ne

Joined Dec 4, 2009
97
I am not really expanding on what others have said, they are right.

To approach from a different perspective, an interrupt is analogous to a ringer on a telephone. It interrupts you to tell you you have a phone call.

Without a ringer, you would have to repeatedly pick up the phone to see if anyone is there - this is the approach that you have suggested in your psuedo code.

Neither way is better, it depends on your application. If you have such a dull life that you don't mind sitting next to the phone all day and checking every 5 minutes, then do it! Otherwise, buy a telephone with a ringer!
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
I am apparently doing something wrong still, as it does not seem to want to work. Here is part of my code (PIC16F628A):

Rich (BB code):
;************************************************************************
;PROGRAM INITIALIZATION
INIT    BSF        STATUS,5    ;BANK 1
        MOVLW    B'00000000'
        MOVWF    TRISB        ;ALL PORT B ARE OUTPUT
        MOVLW    B'00000011'
        MOVWF    TRISA        ;RA0 AND RA1 INPUT, OTHERS OUTPUT
        BCF        STATUS,5    ;BANK 0
        BTFSC    PORTA,0        ;NIGHT MODE DESIRED?
        GOTO    NMRY        ;FLASH RED/YELLOW
        BTFSC    PORTA,1        ;OTHER NIGHT MODE DESIRED?
        GOTO    NMRR        ;FLASH RED/RED
;*************************************************************************
;NORMAL SIGNAL OPERATION
NORM    MOVLW    B'00001001'
        MOVWF    PORTB        ;ALL TRAFFIC LANES RED
        CALL    T3SEC        ;FOR 3 SECONDS
NORM1    MOVLW    B'01001001'
        MOVWF    PORTB        ;MAIN LANE TURN ARROW GREEN, ALL OTHERS RED
        CALL    T10SEC        ;FOR 10 SECONDS
        MOVLW    B'00011001'
        MOVWF    PORTB        ;MAIN LANE YELLOW, ALL OTHERS RED
        CALL    T4SEC        ;FOR 4 SECONDS
        MOVLW    B'00001001'
        MOVWF    PORTB        ;ALL TRAFFIC LANES RED
        CALL    T3SEC        ;FOR 3 SECONDS
        BTFSC    PORTA,0        ;R/Y NIGHT MODE DESIRED?
        GOTO    NMRY        ;GO TO R/Y NIGHT MODE
        BTFSC    PORTA,1        ;R/R NIGHT MODE DESIRED?
        GOTO    NMRR        ;GO TO R/R NIGHT MODE
I have 10K pull down resistors on RA0 and RA1. Regardless of whether 5V is applied to either RA0 or RA1, the program remains in "NORM".
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Maybe I should have said the program just stays in normal operation and doesn't divert to either NMRY or NMRR. The program does not get hung up after the T3SEC subroutine, it continues flawlessly into "NORM1"...
 

eng1ne

Joined Dec 4, 2009
97
So presumably, you get the different combinations of outputs, i.e. main line yellow, all others red, which repeats itself?

Is the bottom line the end of your code? Where does it GOTO if R/R Night Mode is not desired?

Out of interest, have you employed any sort of switch debouncing on the inputs? Assuming they are mechanical switches.
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Switch debounce no, simply because it's nowhere near a precision or instantaneous action. The software is simply meant to read for a high state on either RA0 or RA1 at certain intervals --- and either remain in normal operation or go to 1 of 2 other operations depending on which pin is high (voltage applied) but not both.

In other words, if RA0 and 1 are both low (no voltage) the program (a traffic signal) will function in normal mode, i.e. main lanes cycle green yellow red, then cross street cycles.

If voltage is applied to RA0, the light will cycle until all lanes are red, and then read that pin RA0 is high, and go to a flashing light where yellow flashes on the main traffic lanes, and the cross street flashes red.

If Voltage is applied to RA1, the light will cycle until all lanes are red, then read that pin RA1 is high, and go to a flashing light where red flashes all directions.

When voltage is removed from the pin (whichever is high), the light will go to a brief transition mode then back to normal operation.

The program in its entirety follows:

Rich (BB code):
;************************************************************************
;TRAFFIC CONTROL SIGNAL                                                    *
;THIS SIGNAL IS INTENDED TO CONTROL TRAFFIC AT A 4-WAY INTERSECTION        *
;WITH THE "MAIN" ROAD HAVING A GREEN ARROW AND INDEPENDENT YELLOW        *
;CONTROL FOR STOPPING TURN TRAFFIC.  SECONDARY ROAD IS STANARD R-Y-G    *
;LIGHTS.  THIS PROGRAM ALSO HAS 2 "NIGHT MODE" OPERATIONS WHERE            *
;MAIN LANES FLASH YELLOW WHILE SECONDARY ROAD FLASHES RED, OR            *
;4-WAY FLASHING RED DEPENDING ON POSITION OF A PERIPHERAL SWITCH        *
;                                                                        *
;CREATED BY RYAN GOFF FOR THE PIC16F628A                                *
;************************************************************************
;CONFIGURATION
    LIST        P=PIC16F628A
    #INCLUDE    P16F628A.INC
    __CONFIG B'10000100000000'
    ERRORLEVEL    -302
;
    ORG        01
    GOTO    INIT
;
    ORG        04
    GOTO    INIT
;
    COUNT1    EQU    22
    COUNT2    EQU    23
;*************************************************************************
;SUBROUTINES
T500MS    MOVLW    0x32
        MOVWF    COUNT1
        MOVLW    0x04
        MOVWF    COUNT2
T500MS1    DECFSZ    COUNT1        ;500MS DELAY FOR NIGHT MODE FLASHING
        GOTO    $+2
        DECFSZ    COUNT2
        GOTO    T500MS1
        RETURN
;
T3SEC    MOVLW    0xBF
        MOVWF    COUNT1
        MOVLW    0x13
        MOVWF    COUNT2
T3SEC1    DECFSZ    COUNT1        ;3 SECOND DELAY FOR 4-WAY RED
        GOTO    $+2
        DECFSZ    COUNT2
        GOTO    T3SEC1
        RETURN
;
T4SEC    MOVLW    0xFF
        MOVWF    COUNT1
        MOVLW    0x19
        MOVWF    COUNT2
T4SEC1    DECFSZ    COUNT1        ;4 SECOND DELAY
        GOTO    $+2
        DECFSZ    COUNT2
        GOTO    T4SEC1
        RETURN
;
T10SEC    MOVLW    0xFF
        MOVWF    COUNT1
        MOVLW    0x40
        MOVWF    COUNT2
T10SEC1    DECFSZ    COUNT1        ;10 SECOND DELAY FOR GREEN TURN ARROW
        GOTO    $+2
        DECFSZ    COUNT2
        GOTO    T10SEC1
        RETURN
;
T20SEC    MOVLW    0xFF
        MOVWF    COUNT1
        MOVLW    0x80
        MOVWF    COUNT2
T20SEC1    DECFSZ    COUNT1        ;20 SECOND DELAY FOR GREEN LIGHT
        GOTO    $+2
        DECFSZ    COUNT2
        GOTO    T20SEC1
        RETURN
;************************************************************************
;PROGRAM INITIALIZATION
INIT    BSF        STATUS,5    ;BANK 1
        MOVLW    B'00000000'
        MOVWF    TRISB        ;ALL PORT B ARE OUTPUT
        MOVLW    B'00000011'
        MOVWF    TRISA        ;RA0 AND RA1 INPUT, OTHERS OUTPUT
        BCF        STATUS,5    ;BANK 0
        BTFSC    PORTA,0        ;NIGHT MODE DESIRED?
        GOTO    NMRY        ;FLASH RED/YELLOW
        BTFSC    PORTA,1        ;OTHER NIGHT MODE DESIRED?
        GOTO    NMRR        ;FLASH RED/RED
;*************************************************************************
;NORMAL SIGNAL OPERATION
NORM    MOVLW    B'00001001'
        MOVWF    PORTB        ;ALL TRAFFIC LANES RED
        CALL    T3SEC        ;FOR 3 SECONDS
NORM1    MOVLW    B'01001001'
        MOVWF    PORTB        ;MAIN LANE TURN ARROW GREEN, ALL OTHERS RED
        CALL    T10SEC        ;FOR 10 SECONDS
        MOVLW    B'00011001'
        MOVWF    PORTB        ;MAIN LANE YELLOW, ALL OTHERS RED
        CALL    T4SEC        ;FOR 4 SECONDS
        MOVLW    B'00001001'
        MOVWF    PORTB        ;ALL TRAFFIC LANES RED
        CALL    T3SEC        ;FOR 3 SECONDS
        BTFSC    PORTA,0        ;R/Y NIGHT MODE DESIRED?
        GOTO    NMRY        ;GO TO R/Y NIGHT MODE
        BTFSC    PORTA,1        ;R/R NIGHT MODE DESIRED?
        GOTO    NMRR        ;GO TO R/R NIGHT MODE
        MOVLW    B'10000001'
        MOVWF    PORTB        ;MAIN TRAFFIC LANES GREEN, TURN ARROWS OFF, SECONDARY RED
        CALL    T20SEC        ;FOR 20 SECONDS
        MOVLW    B'00010001'
        MOVWF    PORTB        ;MAIN TRAFFIC LANES YELLOW + SECONDARY RED
        CALL    T4SEC        ;FOR 4 SECONDS
        MOVLW    B'00001001'
        MOVWF    PORTB        ;ALL TRAFFIC LANES RED
        CALL    T3SEC        ;FOR 3 SECONDS
        BTFSC    PORTA,0        ;R/Y NIGHT MODE DESIRED?
        GOTO    NMRY        ;GO TO R/Y NIGHT MODE
        BTFSC    PORTA,1        ;R/R NIGHT MODE DESIRED?
        GOTO    NMRR        ;GO TO R/R NIGHT MODE
        MOVLW    B'00001100'
        MOVWF    PORTB        ;SECONDARY GREEN, MAIN LANES RED
        CALL    T20SEC        ;FOR 20 SECONDS
        MOVLW    B'00001010'
        MOVWF    PORTB        ;SECONDARY YELLOW, MAIN LANES RED
        CALL    T4SEC        ;FOR 4 SECONDS
        MOVLW    B'00001001'
        MOVWF    PORTB        ;ALL TRAFFIC LANES RED
        CALL    T3SEC        ;FOR 3 SECONDS
        BTFSC    PORTA,0        ;R/Y NIGHT MODE DESIRED?
        GOTO    NMRY        ;GO TO R/Y NIGHT MODE
        BTFSC    PORTA,1        ;R/R NIGHT MODE DESIRED?
        GOTO    NMRR        ;GO TO R/R NIGHT MODE
        GOTO    NORM1        ;OR REMAIN IN NORMAL CYCLE OPERATION
;**************************************************************************
;R/Y NIGHT MODE OPERATION.  PORTA 0
NMRY    MOVLW    B'00010000'
        MOVWF    PORTB        ;MAIN LANES ALL YELLOW, ALL OTHERS OFF
        CALL    T500MS        ;FOR 1/2 SECOND
        MOVLW    B'00000001'
        MOVWF    PORTB        ;SECONDARY RED, ALL OTHERS OFF
        CALL    T500MS        ;FOR 1/2 SECOND
        BTFSS    PORTA,0        ;STILL WANT R/Y NIGHT MODE?
        GOTO    TRANS        ;IF NO, TRANSITION TO NORMAL CYCLE MODE
        BTFSC    PORTA,1        ;SWITCH TO R/R NIGHT MODE?
        GOTO    NMRR        ;THEN GO TO R/R NIGHT MODE
        GOTO    NMRY        ;OR STAY IN THIS NIGHT MODE
;**************************************************************************
;R/R NIGHT MODE OPERATION.  PORTA 1
NMRR    MOVLW    B'00001000'
        MOVWF    PORTB        ;MAIN LANES RED, ALL OTHERS OFF
        CALL    T500MS        ;FOR 1/2 SECOND
        MOVLW    B'00000001'
        MOVWF    PORTB        ;SECONDARY RED, ALL OTHERS OFF
        CALL    T500MS        ;FOR 1/2 SECOND
        BTFSC    PORTA,0        ;R/Y NIGHT MODE DESIRED?
        GOTO    NMRY        ;THEN GO TO R/Y NIGHT MODE
        BTFSS    PORTA,1        ;R/R NIGHT MODE STILL DESIRED?
        GOTO    TRANS        ;NO, TRANSITION TO NORMAL CYCLE MODE
        GOTO    NMRR        ;YES, STAY IN R/R NIGHT MODE
;**************************************************************************
;TRANSITION FROM NIGHT MODE TO NORMAL
TRANS    MOVLW    B'10000001'
        MOVWF    PORTB        ;MAIN TRAFFIC LANES GREEN, SECONDARY RED
        CALL    T10SEC        ;FOR 10 SECONDS
        MOVLW    B'00010001'
        MOVWF    PORTB        ;MAIN TRAFFIC LANES YELLOW. SECONDARY RED
        CALL    T4SEC        ;FOR 4 SECONDS
        GOTO    NORM        ;GO TO NORMAL CYCLE OPERATION
;**************************************************************************
        END
 

t06afre

Joined May 11, 2009
5,934
Your code is very strange. It has some fundamental flaws as I can see.
When an interrupt is serviced:
• The GIE is cleared to disable any further interrupt.
• The return address is pushed onto the stack.
The PC is loaded with 0004h.
Then you are done in your ISR you do the retfie instruction. Stack is POPed and Top-of-Stack (TOS) is loaded in the PC. Interrupts are enabled by setting Global interrupt Enable bit, GIE
I can not see you have implemented such structure in your program
Rich (BB code):
    org 0
     goto      Main
     nop
     nop
     nop
ISR:
    ;Put your interrupt service routine her(ISR)
    ;
    ;
    ;
retfie   ;End it with this command the program will jump back to main program
 
 
Main:
;
;
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Did you disable the comparator? (CMCON = 7)

Did you set RA0 and RA1 as input? (TRISA register)

Edited: I don't see the setting in the code of your last post (#11).

Alberto
Added a line in the initial setup to disable comparators (CMCON bits 0:2 changed to 1, all others 0)

RA0 and RA1 should have already been specified as input based on the line of code:
MOVLW B'00000011'
MOVWF TRISA

In response to t06afre:
Several people on this thread have said I don't need to use "interrupts" for this function, and I tend to agree. The program is only intended to move around to different parts if during a bit test on RA0 or RA1 either pin is found to be high (a 1 rather than a 0).
 
Top