calling subroutine triggers interrupt


Closed Thread
Results 1 to 8 of 8
  1. #1
    Join Date
    Dec 2009
    Location
    Canada
    Posts
    68

    Unhappy calling subroutine triggers interrupt

    Hello All,

    Please advise if this is a known issue: I programmed PIC16F688 for interrupt on A2/INT on dropping edge which works fine, but I got a problem - every time I call any subroutine, it triggers the interrupt, even if the subroutine is empty like this:

    SBRTN:
    RETURN

    every call to any subroutine (gosub ...) results execution of my interrupt handler subroutine.

    Is this something known and caused by a common mistake?

    Thank you,
    Alexey
    Last edited by Alexey; - 19th May 2011 at 03:14.

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: calling subroutine triggers interrupt

    don't post any code just in case we could find the mistake in
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    Join Date
    Dec 2009
    Location
    Canada
    Posts
    68


    Did you find this post helpful? Yes | No

    Default Re: calling subroutine triggers interrupt

    Hi Steve,

    I thought this may be a known thing - did not want to bother gurus with long garbage code some pieces of which do not make sense until the rest is written. The line GOSUB VOLTMTR IS A PROBLEM - causes interrupt and execution of code of interrupt handler BTN_CHECK before code of VOLTMTR is executed
    Code:
         @ DEVICE pic16F688, WDT_OFF, INTOSCIO, PWRT_ON, MCLR_ON, BOD_OFF 
         @ DEVICE CPD_OFF, PROTECT_OFF 'DATA AND CODE MEMORY PROTECTION
         INTCON = 0
         DISABLE
         define OSC 4   
    
         clear    
                         
    ;---------INPUTS AND OUTPUTS-------------    
          'PORTA.0 ICSPDAT,           CONF AS OUTPUT
          'PORTA.1 ICSPCLK,           CONF AS OUTPUT          
          'PORTA.2 ON/OFF BUTTON            INPUT, WEAK PULL UP 
          'PORTA.3 VPP, CONF AS MCLR,        CONF AS MCLR, WEAK PULL-UP      
          'PORTA.4 AN2 VOLTAGE METER      INPUT, NO WEAK PULL UP 
              
          'PORTA.5 EXT ACTIVATION         INPUT, WEAK PULL UP 
          
          'PORTC.0  DIAG OUT                  OUTPUT
          'PORTC.1  DIAGNOSTIC INPUT     INPUT
          'PORTC.2  YELLOW WIRE            OUTPUT
              
          'PORTC.3  NOT USED                 OUTPUT, ZERO
          'PORTC.4  RED LED                    OUTPUT
          'PORTC.5  GREEN LED                OUTPUT      
          
               
         ;---------VARIABLES----------------------          
                              
              BTN VAR PORTA.2
              YW VAR PORTC.2
              REDLED VAR PORTC.4     
              GREENLED VAR PORTC.5  
                   
     
            FCODE       VAR BYTE
            COUNTER     VAR byte
            COUNTER2     VAR BYTE
            COUNTER3    VAR BYTE
            N         VAR BYTE
                CALC     VAR BYTE  
                NF         VAR BYTE
                F        VAR BYTE[5]    'AF,F1,F2,F3,F4,F5  
                POWER     VAR BIT
                 VOLT      VAR BYTE       'VOLTAGE IN 0.1294 V UNITS 
                  LVCOUNT   VAR BYTE       'COUNTER FOR LOW TIME
                  VTR       VAR BYTE       'VOLTAGE TRESHOLD           
                
    '--------------------DEFINITIONS-----------
    'FOR SERIAL INPUT:    
                 dEFINE DEBUGIN_REG PORTC 'GPIO  ' Debugin pin port 
            DEFINE DEBUGIN_BIT 1     ' Debugin pin bit 
                 DEFINE DEBUGIN_MODE 0    ' Debugin mode: 0 = True, 1 = Inverted 
            DEFINE DEBUG_BAUD 1200   ' Debug baud rate  
    '-----------PORTS CONFIGURATION------------
         CMCON0 = 7          'TURN COMPARATORS OFF 
         VRCON = 0           'VOLTAGE REFERENCE OFF TO SAVE POWER OPTION_REG.7 = 0
         OPTION_REG = 0
         ANSEL = %1000       'PORTA4/AN3 IS ANALOG
         WPUA = %100100      'PULL UPS ON A.2 AND A.5  (BUTTON AND EXT SWITCH)
         PORTA = 0           'OUTPUTS ON PORTA LOW (ALL UNUSED)
         TRISA = %111100     'SET PORT A FOR OUTPUTS ON PINS 0,1 (UNUSED) ALL OTHER INPUTS      
         PORTC=0             'yellow wire low, LEDs OFF, DIAG WIRE UP
         TRISC = %000010     'SET PORT C FOR INPUT ON PIN 1 (DIAG IN) ALL OTHER OUTPUTS
              
    '-----DETECTING IF THE SYSTEM IS 12 OR 24 VOLTS----  
    
         ADCON0=%00001101       'LEFT JUSTIFIED(0),VDD ref(0),not used,AN3 USED(011),NO START NOW,STAY ON
         ADCON1=%00010000       'CONVERSION CLOCK SELECT FOSC/32
         ANSEL=%1000              'USE AN3
    
         GOSUB VOLTMTR        'THIS CALL TRIGGERS INTERRUPT EVEN WHEN SUBROUTINE VOLTMTR IS EMPTY
         'ADCIN 3,VOLT           'this option works OK
           
         IF VOLT < 124 THEN  'IF VOLTAGE < 16 V    
             GREENLED = 1
             VTR = 97       
             
         ELSE
                      VTR = 210       
             REDLED = 1
         ENDIF
    
         PAUSE 1000     'TO DEBUG
         PORTC = 0      'TO DEBUG
         PAUSE 1000
         FCODE = VOLT
    
         ENABLE
    '---------INTERRUPTS CONFIG-----------
         OPTION_REG.6 = 0    'INTERRUPTS ON FAILING EDGE (BUTTON PRESSED) 
         INTCON = %10000    'ENABLES RA2 (1,) OTHER INTERRUPTS ON PORTA ARE OFF (BIT 3)  
         IOCA = %100         'ENABLES INTERRUPT ON PORTA.2                                          
    
        ON INTERRUPT GOTO BTN_CHECK     '  CHECK ON/OFF BUTTON
           
    START:      if yw = 0 then NAP 7  'THIS REDUCES CURRENT FROM 6 TO 4 mA
            GOSUB PAUSE_60
               IF YW = 1 THEN GOSUB VOLTAGE   
    GOTO START     'WAIT HERE TILL INTERRUPTED
    
    ''''--------------SUBROUTINES--------------------------
    '----------READ VOLTAGE--------------- 
    VOLTAGE:
         GOSUB VOLTMTR
        
         IF VOLT < VTR THEN 
              LVCOUNT = LVCOUNT +1
              REDLED = 1          'TURN RED ON SO THE LIGHT BECOMES YELLOW
         ELSE
              IF LVCOUNT > 0 THEN LVCOUNT = LVCOUNT - 1  
              IF LVCOUNT = 0 THEN REDLED = 0  
         ENDIF               
         
         IF LVCOUNT = 5 THEN 
              PORTC=0  
              lvcount = 0 
         endif     
     RETURN 
     
    '-----------PAUSE 60 sec--------------  
         N2 VAR BYTE
    PAUSE_60:
         FOR N2 = 1 TO 60
              PAUSE 100'0
         NEXT N2     
     RETURN
     
    TEST:
         N = PORTA        'READ PORT A TO CLEAR MISMUTCH, NOTHING ELSE
        ' INTCON.0=0       'CLEAR INTERRUPT FLAG AFTER READING PORT  (RAIF FLAG) not needed
         INTCON.1 = 0     'CLEAR INTF FLAG FOR PORT RA2  
     RETURN
    
    '---------VOLTMETER ROUTINE----------    
    VOLTMTR:
         ADCON0=%00001101       'LEFT JUSTIFIED(0),VDD ref(0),not used,AN3 USED(011),NO START NOW,STAY ON
         ADCON1=%00010000       'CONVERSION CLOCK SELECT FOSC/32
         ANSEL=%1000            'USE AN3
         PAUSE 1
         ADCON0 = %1111       'LEFT JUSTIFIED,VDD ref,not used,not used,AN3 USED(011),STARTS IMMEDIATELY,STAY ON
    ADCONV:      
         pauseus 50              'allow time for ADC calculation 
         IF ADCON0.1 = 1 THEN GOTO ADCONV
         volt = ADRESH
    
     RETURN
    
    '---------------------------------------------------
    SHOW_RESULT:
           IF FCODE =0 THEN 
            GREENLED = 1 'IF AF=0 -> GREEN LED ON REDLED OFF 
            REDLED = 0     
            PAUSE 10000 'STAY ON 10 SEC
            GREENLED = 0    'GPIO = 0    'TURN LED OFF
        ELSE    
            CALC = FCODE/10   'CALCULATE BLINKS
            GOSUB BLINKING    'BLINK 10S   
               GREENLED = 1
            PAUSE 50
            GREENLED = 0        
            PAUSE 1500
            CALC=FCODE//10
            GOSUB BLINKING  'BLINK 1S
        ENDIF    
    RETURN
    '---------------------------------------------------    
    BLINKING:
        for COUNTER3 = 1 TO CALC
              REDLED = 1
              PAUSE 1000
              REDLED = 0
              PAUSE 350
            NEXT COUNTER3
            PAUSE 1500      'DIVIDER BETWEEN 10s, 1s AND CONTINUING
    RETURN        
    
         DISABLE 'INTERRUPT
    BTN_CHECK:  
         IF YW = 0 THEN                   
              GREENLED = 1
              yw = 1
         ELSE 
              PORTC=0   
         ENDIF
         PAUSE  1000     'ANTI VIBRATION
         N = PORTA        'READ PORT A TO CLEAR MISMUTCH, NOTHING ELSE
        ' INTCON.0=0       'CLEAR INTERRUPT FLAG AFTER READING PORT  (RAIF FLAG)
         INTCON.1 = 0     'CLEAR INTF FLAG FOR PORT RA2    
     RESUME
         ENABLE 'INTERRUPT
    Thanks again,

    Alexey
    Last edited by ScaleRobotics; - 19th May 2011 at 05:35. Reason: code tags

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: calling subroutine triggers interrupt

    weird, may need to sleep on that one, what if you clear the INT flag before that gosub?
    INTCON.1 = 0
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5
    Join Date
    Dec 2009
    Location
    Canada
    Posts
    68


    Did you find this post helpful? Yes | No

    Default Re: calling subroutine triggers interrupt

    Hi Mister_E,

    Unfortunately this does not help. I removed all irrelevant code from the program to make it more clear, sorry for not doing this before. The code I have now for test is below. When it starts, calling empty Test subroutine always triggers interrupt so the GREENLED is ON. If I disable the GOSUB TEST, then it starts with GREENLED OFF (interrupt handler did not run)

    This is the first time I play with interrupt - most likely do something wrong. The MCU is PIC16F688

    @ DEVICE pic16F688, WDT_OFF, INTOSCIO, PWRT_ON, MCLR_ON, BOD_OFF

    define OSC 4
    clear
    '---------INTERRUPTS CONFIG-----------
    INTCON = %10000 'ENABLES RA2 (1,) OTHER INTERRUPTS ON PORTA ARE OFF (BIT 3)
    IOCA = %100 'ENABLES INTERRUPT ON PORTA.2
    ;---------VARIABLES----------------------

    BTN VAR PORTA.2
    YW VAR PORTC.2
    REDLED VAR PORTC.4
    GREENLED VAR PORTC.5
    N VAR BYTE


    '-----------PORTS CONFIGURATION------------
    OPTION_REG = 0
    ANSEL = %1000 'PORTA4/AN3 IS ANALOG
    TRISA = %111100 'SET PORT A FOR OUTPUTS ON PINS 0,1 (UNUSED) ALL OTHER INPUTS
    TRISC = %000010 'SET PORT C FOR INPUT ON PIN 1 (DIAG IN) ALL OTHER OUTPUTS
    'THE FOLLOWING DID NOT HELP
    N=PORTA 'JUST TO READ PORTA
    INTCON.0=0 'CLEAR INTERRUPT FLAG AFTER READING PORT (RAIF FLAG)
    INTCON.1=0 'CLEAR INTF FLAG FOR PORT RA2
    PORTC=0 'GREENLED SHOULD STAY OFF

    GOSUB TEST 'THIS SUBROUTINE ALWAYS CAUSES INTERRUPT!!!
    'NOW GREENLED ON PORT C5 IS ON !!!



    'THE FOLLOWING DID NOT HELP
    N = PORTA 'READ PORT A TO CLEAR MISMUTCH, NOTHING ELSE
    INTCON.0=0 'CLEAR INTERRUPT FLAG AFTER READING PORT
    INTCON.1=0

    ON INTERRUPT GOTO BTN_CHECK ' CHECK ON/OFF BUTTON

    START:
    GOTO START 'WAIT HERE TILL INTERRUPTED


    TEST: 'NO CODE IN THIS SUBROUTINE

    RETURN

    DISABLE
    BTN_CHECK:
    IF GREENLED = 0 THEN
    GREENLED = 1
    ELSE
    PORTC=0
    ENDIF
    '' PAUSE 1000 'ANTI VIBRATION
    N = PORTA 'READ PORT A TO CLEAR MISMUTCH, NOTHING ELSE
    INTCON.0=0 'CLEAR INTERRUPT FLAG AFTER READING PORT (RAIF FLAG)
    INTCON.1 = 0 'CLEAR INTF FLAG FOR PORT RA2
    RESUME
    ENABLE

  6. #6
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: calling subroutine triggers interrupt

    I think Steve meant to clear the flag before the GOSUB TEST, not before the ON INTERRUPT GOTO.

    It GOSUB's from an area that is DISABLEd to one that is ENABLED.
    If the flag is set, it will jump to the ISR.
    It may jump, even if it's not set.

    The ISR should verify that the flag is set before doing anything.
    Last edited by Darrel Taylor; - 19th May 2011 at 14:43.
    DT

  7. #7
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default Re: calling subroutine triggers interrupt

    Without INTCON.7 set before ON INTERRUPT, it's going to jump to your interrupt vector all the time in any code section where interrupt code is inserted. If you just set INTCON.7 it should never jump there until the hardware interrupt clears INTCON.7 automatically.

    INTCON = %10000 doesn't set INTCON.7 - so the ON INTERRUPT code inserted always assumes an interrupt condition exists.
    Last edited by Bruce; - 19th May 2011 at 18:28.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  8. #8
    Join Date
    Dec 2009
    Location
    Canada
    Posts
    68


    Did you find this post helpful? Yes | No

    Smile Re: calling subroutine triggers interrupt

    Darrel, Bruce,

    Thank you!

    I tried to move "On interrupt goto" to the very top and also check flag in the interrupt handler, either one works just fine.

    Will play with INTCON.7 tomorrow morning.

    Thanks again, the problem seems to be solved

    Alexey

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts