Strange results with PBP3 and instant interrupts


Closed Thread
Results 1 to 15 of 15

Hybrid View

  1. #1
    Join Date
    Mar 2011
    Posts
    13

    Default Strange results with PBP3 and instant interrupts

    I have a set of code that worked very well under 2.6a. I changed processors to an enhanced midrange PIC supported only by the new level of PBP, so I upgraded to 3.0.

    Code worked, once I stamped out the issues with different ports/pins/etc. on the new hardware. But I'm getting really strange results with the T1 interrupt.

    T1 interrupt was set for 1000hz, and sure enough, I can make it flip an output pin every 1mS, with some effort. However,
    - I can't make it NOT do things on 1mS boundaries by changing the required Hz in the instant interrupts setup
    - the interrupt routine drops timing; I do various things on the 1mS tick, and some of these involve running a counter variable and making it roll over to 0 at some count as in
    counter = counter +1
    IF counter = 5 THEN counter = 0
    This works, but those statements seem to make the interrupt routine sometimes miss a timer tick and run a long time before it starts back up again, which I think means it misses the next interrupt tick while still on the interrupt, so the timer runs a full count. That's the only good explanation I can come up with.

    It acts like the system clock is not fast enough to service the timer tick interval and still get off the interrupt level before the timer times out. However, I ran the same basic code on a midrange (not enhanced midrange) PIC with the same clock frequency and had no problems with the interrupt timing on that one. It's possible I've set up the clock speed incorrectly on the newer and more complex PIC, but I've thrashed the clock oscillator setup pretty thoroughly over the last two days.

    My best guess right now is that either (a) I'm really going to slap my forehead hard when someone tells me the answer or (b) there is some setup/migration issue with PBP3 and instant interrupts that I missed. Naturally, I think it's (b). 8-)

    So where's the secret "migrate instant interrupts to PBP3" file?

  2. #2
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Default Re: Strange results with PBP3 and instant interrupts

    Could you post a source file showing the problem ???

    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 " !!!
    *****************************************

  3. #3
    Join Date
    Mar 2011
    Posts
    13


    Did you find this post helpful? Yes | No

    Thumbs up Re: Strange results with PBP3 and instant interrupts

    Sure.
    Salient (I think) points:
    - config bits set for external 4MHZ crystal; oscilloscope shows this is actually running at 4MHz
    - DEFINE for 4MHz set
    - Just in case, the OSCCON register is set for doing what the config bits say, and to select the internal 4MHz oscillator if that fails
    - The PORTA.4 = Mpx.0 is used just to toggle an otherwise not used pin so I can see it flip every time the interrupt routine runs.
    This happens on 1mS intervals MOST of the time; all the time when it's the only thing in the interrupt routine, missing a tick every so often when I put more code into the interrupt routine. This is what made me suspect the system clock.
    - the output pins will sometimes go 80mS between changes instead of the expected 5mS or so. This is what makes me think I am missing an intterupt return time.
    - Changing the frequency in the instant interrupts code from 1000 to some thing else does NOT change the 1mS interrupt interval as seen on the porta.4 pin. This baffles me and makes me think there is an inconsistency with PBP3 and instant interrupts.


    '============ Rotating output pins =========
    ' Compiler : PICBASIC PRO Compiler 3.0
    ' Target PIC : 16F1518
    ' Oscillator : set to 4MHz external crystal
    ' timing ticks happen every 1mS
    ' ...
    DEFINE OSC 4 ; use external 4MHz crystal
    ' Includes for interrupts
    wsave VAR BYTE $20 SYSTEM
    wsave1 VAR BYTE $A0 SYSTEM
    '
    INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
    '...
    '===============config bits=================
    #CONFIG
    __config _CONFIG1, _FOSC_XT & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _WDTE_OFF & _FCMEN_OFF
    __config _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _BORV_19 & _LPBOR_OFF & _LVP_OFF
    #ENDCONFIG
    '================================
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    INT_Handler TMR1_INT, ReloadTMR1, ASM, no ; MUST be first
    INT_Handler TMR1_INT, _T1handler, PBP, yes
    endm
    INT_CREATE ; Creates the interrupt processor
    ENDASM
    ' ================================================== ==========
    ;--- Change these to match the desired interrupt frequency ----------
    @Freq = 1000 ; Frequency of Interrupts in Hz
    @Prescaler = 1 ; Timers Prescaler setting
    T1CON = $00 ; $30 = Prescaler 1:8, TMR1 OFF
    ; $00=1:1, $10=1:2, $20=1:4, $30=1:8 -- Must match @Prescaler value

    @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
    GOSUB StartTimer ; Start the Timer
    '======== pre- main loop code here =================
    ' Initialization
    OSCCON = $68 ' set oscillator control for 4MHZ, external
    '...
    '============ main loop starts here=================
    '
    Value = 120
    mainloop:
    Value = Value +1
    Pause 500
    GOTO mainloop
    '
    '================================================= ===========
    T1handler: ' what happens when T1 clicks over a time interval
    ' interval is set for 1mS / 1000Hz
    ' each fifth interrupt, move to a new output pin
    Mpx = Mpx + 1
    IF Mpx = 6 THEN Mpx = 0
    PORTA.4 = Mpx.0 ' *** Debug *** toggle an output pin to see interrupt handling timing
    IF Mpx = 1 THEN ' only do index processing every fourth count
    i = i + 1 ' update which pin is changed
    IF i > 2 THEN i = 0 ' force i to be 0..2 and roll over to 0
    n = Value PID i ' makes n be the i-th digit of Value
    PINS = ~ DCD 1
    LATA = LATA & PINS ' pull the enable pins
    ENDIF
    '
    @ INT_RETURN ' done with this interrupt pass
    '
    ;---[TMR1 reload - interrupt handler]-----------------------------------------
    ASM ; Calculate Timer Reload Constant
    ReloadInst = 8 ; # of Intructions used to reload timer
    if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
    MaxCount = 65536 + (ReloadInst / Prescaler)
    TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
    if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
    error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
    endif
    else
    error Invalid Prescaler
    endif
    ENDASM

    @Timer1 = TMR1L ; map timer registers to a word variable
    Timer1 VAR WORD EXT
    TimerReload CON EXT ; Get the External Constant
    TMR1ON VAR T1CON.0 ; Alias the Timers ON/OFF bit

    ;---Reload Timer1------
    ASM
    ReloadTMR1
    MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
    MOVLW LOW(TimerReload) ; 1 Add TimerReload to the
    ADDWF TMR1L,F ; 1 value in Timer1
    BTFSC STATUS,C ; 1/2
    INCF TMR1H,F ; 1
    MOVLW HIGH(TimerReload) ; 1
    ADDWF TMR1H,F ; 1
    MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
    INT_RETURN
    ENDASM

    ;---Start/Stop controls -----
    StartTimer:
    Timer1 = TimerReload ; Load Timer
    TMR1ON = 1 ; start timer
    RETURN

    StopTimer:
    TMR1ON = 0 ; stop timer
    RETURN

  4. #4
    Join Date
    Mar 2011
    Posts
    13


    Did you find this post helpful? Yes | No

    Default Re: Strange results with PBP3 and instant interrupts

    It gets stranger, if more useful. The real problem with blowing out of the interrupt timing was the
    'n = Value DIG i ' statement (which I notice I hosed up posting the source code.)

    I moved the "@ INT_RETURN " statement up a line at a time, and when I got above the "DIG" statement, timing was magically as expected. No amount of dinking with the statement and retrying the syntax, limits, whatever would stop this.

    When I split the "Value" variable into three digits of one byte each and used an IF array to make decimal counting work in the main loop, and changed to a select statement for the pre-carved-up digits in the interrupt loop, it started working just fine.

    Either there is a vaster subtlety than I can see, or the "DIG" math function is broken in some way that interacts with timer1 interrupts.

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: Strange results with PBP3 and instant interrupts

    Hi,
    The first thing that got my attention was the dual interrupt service routines coupled to the same interrupt source. I see that you're not resetting the flag in the ASM handler so it goes in, reload the timer, returns and immediately goes back to PBP handler - I think that's what it'll do or at least what's it meant to do. Is there any reason for not having the reload code, in ASM, as a block at the beginning of the T1_Handler ISR? Not saying the way you've done it doesn't work but it seams a bit wasteful and I don't think I've seen dual ISR's like that before.

    As for the DIG operator I can't say for sure but I'm having a hard time seeing HOW it could interfere with TMR1 or the interrupts. Apparently something strange is going on but I suspect the actual problem is something else than the DIG operator.

    I know, not much real help but anyway...

    /Henrik.

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


    Did you find this post helpful? Yes | No

    Default Re: Strange results with PBP3 and instant interrupts

    Hi,

    Henrik found it ...

    Why not reload timer simply using PBP ???

    would only make ONE interrupt stubb.

    Past that, I don't think using PBP "bits" into an ASM part is really safe ...

    Code:
    ;---Reload Timer1------
    ASM
    ReloadTMR1
    MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
    MOVLW LOW(TimerReload) ; 1 Add TimerReload to the 
    ADDWF TMR1L,F ; 1 value in Timer1
    BTFSC STATUS,C ; 1/2
    INCF TMR1H,F ; 1
    MOVLW HIGH(TimerReload) ; 1
    ADDWF TMR1H,F ; 1
    MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
    INT_RETURN
    ENDASM
    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