Interrupt won't execute.


Closed Thread
Results 1 to 24 of 24

Hybrid View

  1. #1
    Join Date
    Mar 2010
    Posts
    12

    Default Interrupt won't execute.

    Hey all, another newbie question.

    I'm trying to run a servo (later to be expanded to 2 servos) with timer1 interrupts. The program compiles nicely, but never gets to the interrupt routine. I've never used interrupts or the timer before, but I've read all that I can, and just can't figure it out.

    I'm running on the 16F690

    Here's my code:

    Code:
    define OSC 4
    ON INTERRUPT GOTO INTCODE
    
    
    DEFINE HSER_TXSTA 20h       'SET THE TRANSMIT REGISTER TO TRANSMITTER ENABLED
    DEFINE HSER_BAUD 2400       'SET BAUD RATE
                                'DEFINE ADCIN PARAMETERS
    Define ADC_BITS	10          'SET NUMBER OF BITS IN RESULT
    Define ADC_CLOCK 3          'SET CLOCK SOURCE (3=RC)
    Define ADC_SAMPLEUS 50	    'SET SAMPLEING TIME IN uS
    define LOADER_USED 1
    
    SELECTOR    VAR BYTE        'SELECTS PROGRAM TYPE
    TEMP        VAR WORD        'TEMPORY VARIABLE FOR ANY USE
    POSITION    VAR WORD        'POSITION OF SERVO1 1250 - 2500
    OFFWIDTH    VAR WORD        'HOW LONG THE PULSE NEEDS TO BE OFF FOR
    FREQ        VAR WORD        'FREQUENCY TO RUN THE SERVOS AT
    PICOSC      VAR BYTE BANK0  'TO STORE OSCILLATOR FREQUENCY IN
    PERIOD      VAR WORD        'TEMPORY VARIABLE TO DISPLAY THE PERIOD OF PULSE
    PRESCALER   VAR WORD        'STORES THE TIMER1 PRESCALER VALUE
    TMROFF      VAR WORD        'STORES THE TIME THAT THE SERVO1 PULSE WILL BE LOW
    RUN         VAR BIT         'IS THE PROGRAM RUNNING
    
    SERVO1      var PORTA.0     'OUTPUT PIN FOR SERVO1
    STARTSTOP   VAR PORTB.6     'INPUT PIN FOR PUSHBUTTON
    TRISB.4 = 1                 'INPUT FOR SELECTOR SWITCH PIN 13
    TRISA.0 = 0                 'MAKES PIN 19 AN OUTPUT FOR SERVO1
    TRISB.6 = 1                 'MAKES PIN 11 AN INPUT FOR PUSHBUTTON
    
    PRESCALER = 8               'DEFINES THE TIMER1 PRESCALER AS 18
    FREQ = 50                   'CONSTANT FREQUENCY FOR THE SERVOS
    RUN = 0                     'TEMPORARY VARIABLE FOR SERVO RUNNING
    
    T1CON  = %00110000          'SETS THE TIMER1 VALUES - PRESCALER = 8
    GIE         var INTCON.7
    PEIE        var INTCON.6
    TMR1IE      var PIE1.0
    TMR1ON      var T1CON.0
      
    ADCON1 = %10000010          'SET PORTA ANALOGUE AND RIGHT JUSTIFY THE RESULT
    
    GOSUB GETOSC 
    
    MAINLOOP
            GOSUB FINDPROGRAM
            GOSUB STARTPULSE
            'GOSUB STOPPULSE
    GOTO MAINLOOP
    
    FINDPROGRAM                'SELECTS BETWEEN SEVERAL TYPES OF MOTION
        ADCIN 10, TEMP          'READ CHANNEL 10 TO TEMP
        IF TEMP = 15000 THEN POSITION = 125                    'USES VOLTAGE DIVIDER TO
        IF TEMP  15000 AND TEMP = 22000 THEN POSITION = 150   'VARY THE VOLTAGE ON CH10.
        IF TEMP  22000 AND TEMP = 35000 THEN POSITION = 175   'THIS CONVERTS AND STORES
        IF TEMP  35000 AND TEMP = 47000 THEN POSITION = 200   'TO 'TEMP'.
        IF TEMP  47000 AND TEMP = 60000 THEN POSITION = 225   
        IF TEMP  60000 THEN POSITION = 250
        GOSUB SETPULSE   
    RETURN
    
    DISABLE INTERRUPT
    INTCODE
        IF SERVO1 = 0 THEN
            TMR1H = ((65535 - POSITION)256)            'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - POSITION)-(TMR1H256))    'EXTRACT LOW BYTE
            HSEROUT [HIGH , DEC TMR1H, LOW , DEC TMR1L,10,10,13]
            HIGH SERVO1
        ENDIF
        
        IF SERVO1 = 1 THEN
            TMR1H = ((65535 - TMROFF)256)              'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - TMROFF)-(TMR1H256))      'EXTRACT LOW BYTE
            HSEROUT [HIGH , DEC TMR1H, LOW , DEC TMR1L,10,10,13]
            LOW SERVO1
        ENDIF
    RESUME
    ENABLE INTERRUPT
    
    SETPULSE
        POSITION = POSITION MIN 250  'MIN POSITION LIMITED TO 0 DEGREES
        POSITION = POSITION MAX 125  'MAX POSITION LIMITED TO 180 DEGREES
        HSEROUT [POSITION = ,DEC POSITION,10,13]
        TMROFF = (((((10000  FREQ)  10)  PRESCALER)10) - POSITION)
        'HSEROUT [TMROFF = ,DEC TMROFF,10,10]
        'PERIOD = TMROFF + POSITION
        'HSEROUT [PERIOD = ,DEC PERIOD,10,10]
        
    RETURN
    
    STARTPULSE
        HSEROUT [PULSE STARTED,10,10]
        LOW SERVO1
        GIE = 1             'GLOBAL INTERRUPT ENABLE
        PEIE = 1            'PERIPHRIAL INTERRUPT ENABLE
        TMR1H = 255         'SETS TIMER1 TO 65535 
        TMR1L = 255         'NEXT TICK WILL INTERRUPT
        TMR1ON = 1
    RETURN
    
    STOPPULSE
        HSEROUT [PULSE STOPPED,10,10]
        LOW SERVO1
        PEIE =0
    RETURN
    
    GETOSC
    
    asm
        ifdef OSC
           MOVECB   OSC, _PICOSC
        else
           MOVECB   4, _PICOSC
        endif
    endasm
    RETURN
    
    END
    Thanks for any help, the learning curve seems steep at times.

  2. #2
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default

    Hey Bison,

    Yes, very steep learning curve... but the pay off is worth it.

    Not sure if this is your real problem or not... but on the program I have that works with a 12F683...

    Instead of using "DISABLE INTERRUPT" AND "ENABLE INTERRUPT"...

    I just use "DISABLE" and "ENABLE".

    Again, this is for the 12F683, but I also needed this...

    Code:
    INTCON     = %11001000     'now enable GIE,PEIE,x,x,GPIE,x,x,x
    I then use this bit of code when interrupted to see if the int. was caused by the timer1 overflow or because one of the inputs (button) went low...

    Code:
    disable
    
    MyInt:
      
      inttype = PIR1 & %00000001  'check if timer1 overflow occured
      if inttype = 1 then goto TimerInt
      
      goto buttonint  'interrupt was gpio.3
    I do not have the time to examine your code in detail right now but there are a couple of things to check.

    good luck
    Dwight

  3. #3
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Unhappy Thanks, but no go.

    Thanks Dwight, I tried that, but it didn't help. The interrupt isn't happening at all.

  4. #4
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Smile

    Just thinking out loud now...

    some possibilities:
    What is the source for the timer clock?
    What is the prescaler value?
    Did you properly enable the timer interrupt?
    (with the 12f683 it is the PIE1 reg)
    INTCON reg setup correctly?

    I can't remember exactly why right now... but at the end of my timer interrupt service routine I had these two lines, which clears bit 0 of these two registers. I think it clears the interupt flags so that when the "ENABLE" statement is hit(at then end of the interrupt handler code), it does not immediatly, falsely, re-interrupt.

    Code:
    intcon.0 = 0
       PIR1.0 = 0
    These are just my musings and I too am a newbie at this stuff
    If all else fails then write a small snippet of code that just tests one portion of your code to try and narrow the problem down.

    Do not forget to make the chip .pdf manual your best friend... you must, must, must read it! (a section at a time) go to the section on timers and on interupts and see what it tells you.

    That, in my opinion, is really the BIG difference between the versatility of the PIC micros and of something like the basic stamp. The PIC has much to offer and therefore much to configure correctly.

    Good luck
    Dwight

  5. #5
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Question Need more info.

    What is the source for the timer clock?
    Internal oscillator, I think I've selected this properly, but I'm not sure.

    What is the prescaler value?
    It should be 8 - I hope.

    Did you properly enable the timer interrupt?
    I tried to. I suspect this is where I need the help.

    INTCON reg setup correctly?
    Once again, I'm not sure. I tried to.

    Do not forget to make the chip .pdf manual your best friend... you must, must, must read it!
    I've read this, and other sections many times, but I really am starting from scratch here. I've nutted out quite a few things, but so much of the terminology is unfamiliar to me that it's not always clear.

  6. #6
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default

    Below is text copied from the 16f690 docs...

    Section 6.7 Timer1 Interrupt
    The Timer1 register pair (TMR1H:TMR1L) increments
    to FFFFh and rolls over to 0000h. When Timer1 rolls
    over, the Timer1 interrupt flag bit of the PIR1 register is
    set. To enable the interrupt on rollover, you must set
    these bits:
    • TMR1ON bit of the T1CON register
    • TMR1IE bit of the PIE1 register
    • PEIE bit of the INTCON register
    • GIE bit of the INTCON register
    The interrupt is cleared by clearing the TMR1IF bit in
    the Interrupt Service Routine.

    Note: The TMR1H:TTMR1L register pair and the
    TMR1IF bit should be cleared before
    enabling interrupts.

    I feel your pain!

    Dwight

  7. #7
    Join Date
    Nov 2007
    Location
    West Covina, CA
    Posts
    219


    Did you find this post helpful? Yes | No

    Default Something for later

    Can't help with the interupts for now but will offer a suggestion for your A/D part. I'm not sure how you got the numbers to compare and set the servo output values. Your variable "temp" will only get a value somewhere between 0 and 1023 due to the 10bit A/D.
    Code:
    FINDPROGRAM                'SELECTS BETWEEN SEVERAL TYPES OF MOTION
        ADCIN 10, TEMP          'READ CHANNEL 10 TO TEMP
        IF TEMP = 15000 THEN POSITION = 125                    'USES VOLTAGE DIVIDER TO
        IF TEMP  15000 AND TEMP = 22000 THEN POSITION = 150   'VARY THE VOLTAGE ON CH10.
        IF TEMP  22000 AND TEMP = 35000 THEN POSITION = 175   'THIS CONVERTS AND STORES
        IF TEMP  35000 AND TEMP = 47000 THEN POSITION = 200   'TO 'TEMP'.
        IF TEMP  47000 AND TEMP = 60000 THEN POSITION = 225   
        IF TEMP  60000 THEN POSITION = 250
        GOSUB SETPULSE   
    RETURN
    I would suggest using the SELECT CASE to compare your 6 A/D value possibilities. List the "Values" in ascending order and this will set your "POSITION" value as needed.
    Code:
    FINDPROGRAM                'SELECTS BETWEEN SEVERAL TYPES OF MOTION
        ADCIN 10, TEMP   ' Note: Value returned will be anywhere from 0 to 1023
        SELECT CASE TEMP
            CASE Value1: POSITION = 125         'TEMP = Value1, lowest value 
            CASE is <= Value2: POSITION = 150   'TEMP <= Value2
            CASE IS <= Value3: POSITION = 175   'TEMP <= Value3
            CASE IS <= Value4: POSITION = 200   'TEMP <= Value4
            CASE IS <= Value5: POSITION = 225   'TEMP <= Value5
            CASE Value6: POSITION = 250         'TEMP = Value6, highest value
        END SELECT        
        GOSUB SETPULSE   
    RETURN
    Louie

Members who have read this thread : 0

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