Why does TIMER slow down when using longer pause


Closed Thread
Results 1 to 6 of 6
  1. #1
    Join Date
    Jul 2007
    Posts
    53

    Default Why does TIMER slow down when using longer pause

    This is probably a beginner question but I've look everywhere and can't find any answer. I'm using PicBasic Pro with Microcode Studio and COLT Bootloader. This is PIC 18F4620, internal clock, 4X PLL.

    I have this very simple program and the count (TMR var) is slowing down with a longer pause. Can someone explain why? Is this because I'm using internal clock?

    Thanks!

    'PIC 18F4620
    DEFINE RESET_ORG 800h
    DEFINE OSC 32

    DEFINE LCD_LINES 4
    define LCD_DREG PORTD
    DEFINE LCD_RSREG PORTC
    DEFINE LCD_RSBIT 0
    DEFINE LCD_EREG PORTC
    DEFINE LCD_EBIT 1

    OSCCON = %11110000 '8 mhz, internal osc
    OSCTUNE = %11000000 '4x PLL enabled
    INTCON = %10100000 'Interrupt enabled

    T0CON.0 = 1 '1:256 prescaler
    T0CON.1 = 1
    T0CON.2 = 1
    T0CON.3 = 0 'prescaler enabled
    T0CON.4 = 1
    T0CON.5 = 0 'int clk
    T0CON.6 = 0 '16 bits timer
    T0CON.7 = 1 '0= disabled

    TMR var word 'Speed waves Min speed

    on interrupt goto SetTime

    TMR = 0

    start:
    LCDout $FE,1, "timer: " , #tmr
    pause 500
    goto start

    'pause = 50 ---> count up to 1450 approx (30 sec)
    'pause = 500 ---> count up to 150 approx (30 sec)

    disable
    SetTime:
    TMR = TMR + 1
    resume
    enable

    end

  2. #2
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    GrandPa , Although you are running an interrupt routine it will wait for the pause command to finish before servicing the interrupt. The interrupt flag is set right away but the call isn't made untill the command is finished. It's in the manual....

    Dave Purola,
    N8NTA

  3. #3
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by GrandPa View Post
    This is probably a beginner question but I've look everywhere and can't find any answer.
    It's not in there...kinda/sorta between the lines it is...kinda...
    If you're using the 'On Interrupt', PBP won't check 'Interrupts' until it's finished executing the current command.
    So, for example, if you've set up the progam to get a TMR interrupt every 100ms, and you've got a 500ms pause, you'll most likely miss 4-6 timer interrupts, because PBP is busy concentrating on the PAUSE (or ignoring the interrupts, whichever way you like it.
    It's not because you're using the internal clock, it's the way you've got it set up.
    If you use a short pause in a loop to create a longer pause, you'll get more repeatable results over a larger range of pauses.
    There are other ways of doing this, but this should get you started...
    Another thought...you might NOT want to use TMR as a variable...too close to TMR0, TMR1, etc.etc...

    DEFINE RESET_ORG 800h
    DEFINE OSC 32
    DEFINE LCD_LINES 4
    define LCD_DREG PORTD
    DEFINE LCD_RSREG PORTC
    DEFINE LCD_RSBIT 0
    DEFINE LCD_EREG PORTC
    DEFINE LCD_EBIT 1
    osccon=$f0 : osctune=$c0 : intcon=$a0 : t0con=$97 : tmr var word : temp var word
    on inter rupt goto SetTime
    TMR = 0
    enable
    start: LCDout $FE,1, "timer: " , #tmr
    for temp = 1 to 500
    pause 1
    next temp

    goto start
    disable
    SetTime:
    TMR = TMR + 1 : resume
    enable
    end


    EDIT: I see Dave beat me to the punch!

  4. #4
    Join Date
    Jul 2007
    Posts
    53


    Did you find this post helpful? Yes | No

    Question I'm Still puzzled !

    I would like first to thank Dave and Skimask for their answer. Actually I submitted a simplified version of the proble I got with timer.

    I first tried with this. As you can see I used TIMER1 as the clock source for TIMER3. Then I read TMR3H and TMR3L in a loop.

    Without any interrupt and I can't see why the Timer register is affected by how often it is read during a certain time. This is why I tried with no luck using interrupt. So the question is still the same. Why do I get different values when I use longer pause ???


    DEFINE RESET_ORG 800h
    DEFINE OSC 32

    DEFINE LCD_LINES 4
    DEFINE LCD_DREG PORTD
    DEFINE LCD_RSREG PORTC
    DEFINE LCD_RSBIT 0
    DEFINE LCD_EREG PORTC
    DEFINE LCD_EBIT 1

    OSCCON = %11110000 '8 mhz, internal osc
    OSCTUNE = %11000000 '4x PLL enabled

    T1CON.7 = 1 '16 bits read/write
    T1CON.6 = 0 'clock from internal osc
    T1CON.5 = 1 '1:8 prescale
    T1CON.4 = 1 '1:8 prescale
    T1CON.3 = 0 'osc shut off
    T1CON.2 = 1
    T1CON.1 = 0 'Internal clock
    T1CON.0 = 1 'enabled

    T3CON.7 = 1 '16 bits read/write
    T3CON.5 = 1 '1:8 prescale
    T3CON.4 = 1 '1:8 prescale
    T3CON.1 = 1 'clock from timer1
    T3CON.0 = 1 'enabled

    myTMR var word
    myTMR = 0
    TMR3H = 0
    TMR3L = 0

    start:
    gosub gettime
    LCDout $FE,1, "timer: " , #myTMR
    pause 500
    goto start

    'pause = 50 ---> count up to 660 approx (30 sec)
    'pause = 500 ---> count up to 60 approx (30 sec)

    getTime
    myTMR.BYTE1 = TMR3H
    myTMR.BYTE0 = TMR3L
    return

    end

  5. #5
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by GrandPa View Post
    I would like first to thank Dave and Skimask for their answer. Actually I submitted a simplified version of the proble I got with timer.

    I first tried with this. As you can see I used TIMER1 as the clock source for TIMER3. Then I read TMR3H and TMR3L in a loop.

    Without any interrupt and I can't see why the Timer register is affected by how often it is read during a certain time. This is why I tried with no luck using interrupt. So the question is still the same. Why do I get different values when I use longer pause ???
    I'd be willing to bet that TMR3 is rolling over so fast, that you're not seeing the actual value; you're actually seeing just the lower 16 bits of that value. If TMR3 had 32 bits, you might see the value increasing past 65535.
    The difference between using pause 50 and pause 500 might be just enough difference in the number of instructions to give you that difference that you're seeing.
    Try this and see how fast it actually rolls over:
    I added another counter that'll pick up the number of times that TMR3 rolled over and a counter that'll show you how fast the loop goes thru (which really doesn't have anything to do with how fast TMR3 counts other than the oscillator's speed).
    DEFINE RESET_ORG 800h
    DEFINE OSC 32
    DEFINE LCD_LINES 4
    DEFINE LCD_DREG PORTD
    DEFINE LCD_RSREG PORTC
    DEFINE LCD_RSBIT 0
    DEFINE LCD_EREG PORTC
    DEFINE LCD_EBIT 1
    OSCCON = %11110000 '8 mhz, internal osc
    OSCTUNE = %11000000 '4x PLL enabled
    T1CON.7 = 1 '16 bits read/write
    T1CON.6 = 0 'clock from internal osc
    T1CON.5 = 1 '1:8 prescale
    T1CON.4 = 1 '1:8 prescale
    T1CON.3 = 0 'osc shut off
    T1CON.2 = 1
    T1CON.1 = 0 'Internal clock
    T1CON.0 = 1 'enabled
    T3CON.7 = 1 '16 bits read/write
    T3CON.5 = 1 '1:8 prescale
    T3CON.4 = 1 '1:8 prescale
    T3CON.1 = 1 'clock from timer1
    T3CON.0 = 1 'enabled
    myTMR var word
    oldmyTMR var word
    myTMR = 0
    rollover var word
    timesthru var word
    TMR3H = 0
    TMR3L = 0
    lcdout $fe , 1
    start:
    myTMR.byte1 = tmr3h
    myTMR.byte0 = tmr3l
    if oldmyTMR > myTMR then rollover = rollover + 1 'TMR3 rolled over back to zero because the old value is greater than the new value
    LCDout $FE,$80, "timer:" , DEC myTMR , " "
    lcdout $fe , $c0, "rollover:",DEC rollover, " "
    lcdout $fe , $94, "times thru:", DEC timesthru, " "
    oldmyTMR = myTMR
    timesthru = timesthru + 1
    goto start
    Last edited by skimask; - 5th July 2007 at 23:17.

  6. #6
    Join Date
    Jul 2007
    Posts
    53


    Did you find this post helpful? Yes | No

    Smile Problem solved !

    Hi and thank you for all that tried to help.

    I made 2 BIG mistakes that make it failed.

    FIRST: I assumed that when using TIMER1 clock as the source for TIMER3 I will have the output of the timer (with prescaler). Seems to be wrong, I'm just using the same clock that's all.

    SECOND: ----- This was the real catch ------
    I'm using PORTC.0 and PORTC.1 for the LCD display. C0 is also TIMER3 clk input. C1 is TIMER1 osc input. I fist moved the LCD wires to somewhere else and I was amazed to find out that TIMER3 stopped. I know think that I was sending some clock signal with the LCD. One thing that help me find this was that I had about 1 count for every pass within the loop. hehehe

    I solved this issue by using HPWM out to T0CK1 input.


    Thanks again!

Similar Threads

  1. Delayed output 10 secs
    By lilimike in forum mel PIC BASIC Pro
    Replies: 37
    Last Post: - 14th October 2011, 06:28
  2. Old and beyond help ?
    By DavidFMarks in forum mel PIC BASIC Pro
    Replies: 46
    Last Post: - 11th December 2008, 15:23
  3. Replies: 11
    Last Post: - 12th July 2008, 02:36
  4. Fade out LEDs question
    By Sam in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 22nd June 2008, 10:50
  5. Help Quick Need to make code smaller
    By Programmednew in forum mel PIC BASIC Pro
    Replies: 41
    Last Post: - 25th January 2005, 03:46

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