Interrupt won't execute.


Closed Thread
Results 1 to 24 of 24

Hybrid View

  1. #1
    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

  2. #2
    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.

  3. #3
    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

  4. #4
    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

  5. #5
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Red face ADCON code

    Thanks for the input Link, I'll have to have a look at that code, it looks smaller than mine.

    The way I've done it works currently though. When I cut and pasted code it seems some characters didn't come across for some reason. the individual lines should look more like:

    Code:
    IF TEMP > 22000 AND TEMP <= 35000 THEN POSITION = 175
    I don't know why, but the ADC values do come out between those values; they go all the way up to 65535 with full voltage. I tried to calculate how they'd come out before I coded it, but ended up just adjusting them after seeing the output. If anyone knows why that'd be interesting.

    Still need help with the interrupts though.

    I've since added every single registry setting I could find in, and i got it off the ground, but it's giving me very strange results. I'll post more details once the kids are in bed.

  6. #6
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,653


    Did you find this post helpful? Yes | No

    Unhappy

    Hi, BB

    your code doesn't compile at all ...

    from MCS ...

    FATAL ERROR: Too many errors. (21)
    ERROR Line 53: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 53: Syntax error. (AdCServo.pbp)
    ERROR Line 54: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 54: Syntax error. (AdCServo.pbp)
    ERROR Line 55: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 55: Syntax error. (AdCServo.pbp)
    ERROR Line 56: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 56: Syntax error. (AdCServo.pbp)
    ERROR Line 57: Bad expression or missing THEN. (AdCServo.pbp)
    ERROR Line 64: Bad expression. (AdCServo.pbp)
    ERROR Line 65: Bad expression. (AdCServo.pbp)
    ERROR Line 66: Bad expression. (AdCServo.pbp)
    ERROR Line 71: Bad expression. (AdCServo.pbp)
    ERROR Line 72: Bad expression. (AdCServo.pbp)
    ERROR Line 73: Bad expression. (AdCServo.pbp)
    ERROR Line 82: Bad expression. (AdCServo.pbp)
    ERROR Line 83: Bad expression. (AdCServo.pbp)
    ERROR Line 91: Bad expression. (AdCServo.pbp)
    ERROR Line 101: Bad expression. (AdCServo.pbp)
    add to that most of the operators and tokens are missing, your TMR1 calculations are false ( Where's the prescaler you've set to 8, gone ??? ), TMROFF calculations also false, your HSEROUT command syntax is not correct ...
    and the servo pulse values do not match 0 and 180° positions !

    Ok, I stop here ...

    You'd better rewrite your PROJECT on a white sheet from very start ...

    Would be much better ( and quicker ) than trying to correct what you've done ...

    AND I did forget last, but not least ... do not use " ON INTERRUPT " as timing is critical here ... only ASM interrupts will fit here ... IF you insist on using interrupts - that are not at all compulsory in such a project -


    Alain
    Last edited by Acetronics2; - 25th March 2010 at 09:51.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  7. #7
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Default Half working now.

    As mentioned above, I've added every single register entry that I could find that was related to timer1.

    The interrupt now executes, but I'm getting weird results.

    Firstly here's the code for the registry entrys I've added:

    Code:
    T1CON  = %00110001          'ENABLE X,X,PRESCALER = 8,X,X,X,TMR1ON 
    INTCON     = %11001000      'ENABLE GIE,PEIE,x,x,GPIE,x,x,x
    GIE         var INTCON.7
    PEIE        var INTCON.6
    TMR1IE      var PIE1.0
    TMR1ON      var T1CON.0
    TMR1IE = 1                  '
    PEIE = 1                    'WHO KNOWS
    GIE = 1                     'WHAT ALL OF 
    PIR1.0 = 0                  'THESE DO, BUT IT 
    TMR1H = 0                   'DIDN'T START 
    TMR1L = 0                   'WITHOUT THEM.
    I'm thinking I've added too many, but I don't really know how they work - even after reading the datasheet several times. If anyone has any comments to make about these I'd be most grateful, I really am trying to learn.

    Here's the interrupt routine again:

    Code:
    DISABLE' INTERRUPT
    INTCODE:
        IF SERVO1 = 0 THEN
            HSEROUT ["FIRST IF - POSITION: ",DEC POSITION,10]
            TMR1H = ((65535 - POSITION)/256)            'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - POSITION)-(TMR1H*256))    'EXTRACT LOW BYTE
            HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10]
            SERVO1 = 1
            HSEROUT ["SERVO1: ",DEC SERVO1,10,10]
        ENDIF
        
        IF SERVO1 = 1 THEN
            HSEROUT ["SECOND IF - TMROFF: ",DEC TMROFF,10]
            TMR1H = ((65535 - TMROFF)/256)              'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - TMROFF)-(TMR1H*256))      'EXTRACT LOW BYTE
            HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10,10,13]
            SERVO1 = 0
            HSEROUT ["SERVO1: ",DEC SERVO1,10,10]
        ENDIF
        INTCON.0 = 0
        PIR1.0 = 0
    RESUME
    ENABLE' INTERRUPT
    and here's the results on the serial port:

    FIRST IF - POSITION: 225
    HIGH: 12 LOW: 64
    SERVO1: 0

    This is where it gets weird. I'm trying to extract the high and low bits for timer1, ie. I want the timer to countdown for the amount of time stored in 'position'. So the timer has to equal 65535 - Position. I need to break this down into the high and low bits for tmr1H and tmr1L. So tmr1H = 65535 - position / 256 etc. (much thanks to Aratti for helping me with that).

    The strange thing is the value that the PIC has calculated for high and low.

    high should equal (65535 - 225(value for position is shown in serout))/256 = 255.11 (I know we'll lose the .11)

    Low should equal ((65535 - 225)-(255*256) = 30
    of course this last value won't be correct until the first one comes out right, but even with the first incorrect value from formula one in place it's still all wrong.

    I can't figure it out. Why so far out?
    It looks too simple to go wrong. I'm missing something.

    Can hair be glued back in?

    I can't find a smilie for crying desperately...

  8. #8
    Join Date
    Mar 2010
    Posts
    12


    Did you find this post helpful? Yes | No

    Default Re submitting code.

    Hey Ace, thanks for looking it over.

    As mentioned briefly above, when I cut and pasted my code, it seems a lot of the symbols didn't come across. I'll repost here:

    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?
    
    ADCON1 = %10000010          'SET PORTA ANALOGUE AND RIGHT JUSTIFY THE RESULT
    
    SERVO1      var PORTA.0     'OUTPUT PIN FOR SERVO1
    PUSHBUTT    VAR PORTA.2     'INPUT PIN FOR PUSHBUTTON
    TRISB.4 = 1                 'INPUT FOR SELECTOR SWITCH PIN 13
    TRISA.0 = 0                 'MAKES PIN 19 AN OUTPUT FOR SERVO1
    TRISA.2 = 1                 'MAKES PIN 17 AN INPUT FOR PUSHBUTTON
    
    PRESCALER = 8               'DEFINES THE TIMER1 PRESCALER AS 1:8
    FREQ = 50                   'CONSTANT FREQUENCY FOR THE SERVOS
    RUN = 0                     'TEMPORARY VARIABLE FOR SERVO RUNNING
    
    T1CON  = %00110001          'ENABLE X,X,PRESCALER = 8,X,X,X,TMR1ON 
    INTCON     = %11001000      'ENABLE GIE,PEIE,x,x,GPIE,x,x,x
    GIE         var INTCON.7
    PEIE        var INTCON.6
    TMR1IE      var PIE1.0
    TMR1ON      var T1CON.0
    TMR1IE = 1                  '
    PEIE = 1                    'WHO KNOWS
    GIE = 1                     'WHAT ALL OF 
    PIR1.0 = 0                  'THESE DO, BUT IT 
    TMR1H = 0                   'DIDN'T START 
    TMR1L = 0                   'WITHOUT THEM.
    
    GOSUB GETOSC 
    
    MAINLOOP:
            IF PUSHBUTT = 1 THEN 
                HSEROUT ["HIGH.",13,10]
            ELSE 
                HSEROUT ["LOW",13,10]
            ENDIF
            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
            HSEROUT ["FIRST IF - POSITION: ",DEC POSITION,10]
            TMR1H = ((65535 - POSITION)/256)            'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - POSITION)-(TMR1H*256))    'EXTRACT LOW BYTE
            HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10]
            SERVO1 = 1
            HSEROUT ["SERVO1: ",DEC SERVO1,10,10]
        ENDIF
        
        IF SERVO1 = 1 THEN
            HSEROUT ["SECOND IF - TMROFF: ",DEC TMROFF,10]
            TMR1H = ((65535 - TMROFF)/256)              'EXTRACT HIGH BYTE INTO TIMER1
            TMR1L = ((65535 - TMROFF)-(TMR1H*256))      'EXTRACT LOW BYTE
            HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10,10,13]
            SERVO1 = 0
            HSEROUT ["SERVO1: ",DEC SERVO1,10,10]
        ENDIF
        INTCON.0 = 0
        PIR1.0 = 0
    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
           MOVE?CB   OSC, _PICOSC
        else
           MOVE?CB   4, _PICOSC
        endif
    endasm
    RETURN
    
    END
    I hope it worked this time, dunno what went wrong the first time.

  9. #9
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,653


    Did you find this post helpful? Yes | No

    Exclamation

    Sorry to insist, but " ON INTERRUPT " can't make things work nicely ...

    latency can be much over the positionning pulse length ...

    so, no hope this way ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

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