TMR0 preset problem, PBP3.0


Closed Thread
Results 1 to 3 of 3
  1. #1
    Join Date
    Jun 2007
    Posts
    15

    Default TMR0 preset problem, PBP3.0

    Trying to get an instant interrupt TMR0 counter to work on 16F873 with PBP3.0.
    Similar code worked with PBP2.x, but now I'm banging my head on the wall.

    Maybe just something simple I have overlooked?

    What this should be doing, is presetting the tmr0 counter to 255, so it overflows with every tick,

    incrementing a counter Cnt in the interrupt handler.

    What is happening, is that the toggled pin in the interrupt handler is toggling every couple of

    hundred us, instead of every (0.75 us + interrupt execution time).

    What am I missing?

    '************************************************* ***************
    '* Name : ustimer.BAS *
    '* Author : [select VIEW...EDITOR OPTIONS] *
    '* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
    '* : All Rights Reserved *
    '* Date : 12/9/2011 *
    '* Version : 1.0 *
    '* Notes : for 16F873 *
    '* : *
    '************************************************* ***************
    DEFINE OSC 12 'defines clock frequency = 12MHz
    OPTION_REG = 000001 'timer0 prescaler divide by 4
    'with Fosc = 12 MHz, gives timer tick of 0.75 us

    ADCON1 = 000111 ' 16F87x, 16F87xA, disables a-d converter
    INTCON = 100000 'allows tmr0 interrupts

    TRISA = 001111
    high porta.4
    high porta.5

    INCLUDE "DT_INTS-14.bas" ' Base Interrupt System - THIS FILE MUST BE IN THE COMPILER DIRECTORY!
    INCLUDE "ReEnterPBP.bas" 'HELPER FILE FOR REINTERING PBP IN INTERRUPT- THIS FILE MUST BE IN THE COMPILER DIRECTORY!
    '
    '
    ASM ;This assembler code is needed for the instant interrupt routines
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    INT_Handler TMR0_INT, _PULSETIMER, PBP, yes
    endm
    INT_CREATE ; Creates the interrupt processor
    ENDASM

    Cnt var word 'count variable

    wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
    wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1

    @ INT_ENABLE TMR0_INT

    roundabout:
    ' ****************** some code goes here *****************************
    ' the code uses the Cnt variable and resets it when the job is done
    '
    '********************* to here ****************************************
    goto roundabout

    'This is the tmr0 interrupt handler
    PULSETIMER:
    TMR0 = $FF 'presets the counter to 255, so it overflows (gives a tock)
    'at every tick.
    INTCON.2=0 'resets the timer0 overflow flag
    TOGGLE PORTA.4 'toggle pin on every interrupt, to check timing with scope!
    cnt = cnt + 1 'count every interrupt, so counter increments every 0.75 us
    'or in reality 0.75 us + interrrupt handler execution time.
    @ INT_RETURN

    END

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: TMR0 preset problem, PBP3.0

    Hi,
    I can't believe that code used to work with PBP2.6....

    You have the prescaler set to 1:4 so TMR0 "ticks" at Fosc/4/4 or 12Mhz/4/4=750kHz, one "timer tick" is 1/750kHz=1.3333us so IN THEORY it should interrupt every 1.3333us but it's simply not possible to service the interrupt that fast since the jump to and jump from the ISR alone takes 2+2 instruction cycles let alone the context saving and the actual ISR code.

    What's happening in your case is that the timer interrupts, the prgram execution jumps to the ISR, which takes a BUNCH of cycles to do the context saving etc. Then it preloads the timer and continues executing the ISR. During the execution of the ISR the timer overflows again. The ISR continues to execute and before it exits it resets the interrupt flag and jumps back to the main program, now the timer continues to count untill it overflows and a new interrupt is tripped.

    I'm not sure exactly how DT-Ints works when it comes to resetting the interrupt flag. If it does it in the @INT_RETURN macro the above is true (I think) but if it does it when entering the ISR then the scenario would be a little different but it doesn't change the underlaying problem.

    /Henrik.

  3. #3
    Join Date
    Jun 2007
    Posts
    15


    Did you find this post helpful? Yes | No

    Default Re: TMR0 preset problem, PBP3.0

    Thanks, Henrik.
    I had used similar code in the past with PBP2.x, but not identical, the crucial difference was that the prescaler of my earlier code was divide by 256. So didn't run out of ISR processing time before the interrupt was flagged again.
    Realised that the ISR needed a few clock cycles, but did not realise that it needed so many that I would run out of time before the ISR was finished. I thought the ISR handling time would just extend the period of the timer by up to a microsecond or so. Now a little wiser!

    As for my 0.75 us instead of 750 kHz (equivalent to 1.33 us), I should know better than to attempt simple mental arithmetic instead of pen and paper or a calculator!
    Pinsamt, as they say in your neck of the woods.

    Will go to 20 MHz crystal and a higher prescaler setting, to see how low a timer period is possible before the problem rearises.

    Norbert

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