help: countdown with timer0 interrupt


Closed Thread
Results 1 to 13 of 13
  1. #1
    xnihilo's Avatar
    xnihilo Guest

    Smile help: countdown with timer0 interrupt

    Hello.

    I need to start a 5 minutes countdown on a pic16f690.

    I have the very simple main program:

    Loop
    @ sleep
    Goto loop

    Then I have an int handler for triggerings on porta pins. In fact there are ir receivers on each porta pin and an ir beam triggers an int and specific actions are taken.

    I would need to use timer0 overflow interrupt. What I read from the datasheet is that timer0 is a 8 bits timer that can be used as either a counter or a timer, with prescaler.

    If I am using:

    Define Osc 8

    I assume it means clock speed is 8000000 clock cycles per 1000000 microseconds, thus 125ns clock cycles.
    Right?
    If tmr0 is updated at every clock cycle it takes 256*125ns to set the tmr0 overflow flag in intcon register. If I use a 1:256 prescaler, it will take 256*256*125ns (=8.192 ms) before tmr0 overflows.
    Is that correct?

    I would need 36621 iterations of a counter variable to get 5 minutes countdown (300000/8.192).
    Right?

    If I add in my int handler a routine that will increment a word variable at every tmr0 overflow, I can still get porta change interrupts.
    Right?

    I could have used a loop but during the loop (inside the int handler) no interrupt would occur.

    What do you think?

    Thanks a lot.

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by xnihilo View Post
    Define Osc 8

    I assume it means clock speed is 8000000 clock cycles per 1000000 microseconds, thus 125ns clock cycles.
    Right?
    If tmr0 is updated at every clock cycle it takes 256*125ns to set the tmr0 overflow flag in intcon register. If I use a 1:256 prescaler, it will take 256*256*125ns (=8.192 ms) before tmr0 overflows.
    Is that correct?
    Datasheet reference one more time...
    The PICs run at F(osc) / 4 , 4 clock cycles per instruction cycle. Therefore, at 4Mhz, the PIC executes 1 million single cycle instructions per second. At 8Mhz, 2 million single cycle instructions per second, 500ns per instruction cycle, which is what the timers are incremented from.

    Tmr0 overflows every 256 instruction cycles, 7812.5 timers per second.
    5 minutes = 300 seconds = 2,343,750 total overflows to get 5 minutes.
    If Tmr0 is capable of 16 bit (as it is in some PICs), then 9155.2734375 overflows to get 5 minutes.

  3. #3
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    While the PIC is sleeping Timer0 will be off since on-chip clocks are shut down. You could
    use Timer1, but you would need an extermal clock during sleep.

    If it will be awake during your 5 minute time period, you could use the compare module set
    to reset Timer1 on each match. Load CCPR1L and CCPR1H with 62,500, set a prescaler of
    1:16, and it will interrupt every 500mS + automatically reset Timer1 to 0.

    Then you can just increment a variable in your int handler until your delay period is reached.
    This is a lot easier than reloading a timer in an int handler - or fiddling with adjustments to
    reload values compensating for code overhead.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  4. #4
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    8MHz & Fosc/4 = 2MHz = 0.5Us per instruction cycle.
    Id 1:256 prescaler, it will count 256 instruction cycle before incrementing TMR0.
    With a TMR0 preset to 176 and a prescaler of 256 it will interrupt every 10ms.

    Skimask, you say:
    "Tmr0 overflows every 256 instruction cycles, 7812.5 timers per second".
    I don't get it.
    256*0.5ns = 128 ns per overflow if 1:1 prescaler.
    1000000000ns / 128 = 7812500 iterations per second
    Last edited by xnihilo; - 8th August 2008 at 20:05.

  5. #5
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by xnihilo View Post
    Skimask, you say:
    "Tmr0 overflows every 256 instruction cycles, 7812.5 timers per second".
    I don't get it.
    256*0.5ns = 128 ns per overflow if 1:1 prescaler.
    1000000000ns / 128 = 7812500 iterations per second
    At 8Mhz, there are 2,000,000 instructions cycles per second.
    Assuming a 1:1 prescaler, with an 8 bit counter, you'll get 7812.5 Tmr0 overflow interrupts per second.

    256 * .5US = 128 US per overflow!

    You're off by 1,000 !

  6. #6
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Smile

    Quote Originally Posted by Bruce View Post
    While the PIC is sleeping Timer0 will be off since on-chip clocks are shut down. You could
    use Timer1, but you would need an extermal clock during sleep.

    If it will be awake during your 5 minute time period, you could use the compare module set
    to reset Timer1 on each match. Load CCPR1L and CCPR1H with 62,500, set a prescaler of
    1:16, and it will interrupt every 500mS + automatically reset Timer1 to 0.

    Then you can just increment a variable in your int handler until your delay period is reached.
    This is a lot easier than reloading a timer in an int handler - or fiddling with adjustments to
    reload values compensating for code overhead.
    You pointed out something I just read this afternoon: timer0 is frozen, which is a problem as I use "@ SLEEP" !!
    Well, my idea is to use the folowing parameters:
    With a TMR0 preset to 176 and a prescaler of 256 it will interrupt every 10ms.
    When in my lasergame program player health points drop below 0, it sets a variable (BIT) called CRITICAL to 1 and enable TMR0 interrupts.
    The routine handling the TMR0 interrupt would increment a counter variable and then it would go back to my main loop and... uh... go to sleep, disabling the timer...
    But, if I write (preseting CRITICAL to 0):

    (program starts here)
    loop:
    if (countdown == 1) THEN
    PAUSEus 15 'shortest pause I can use with a 8MHz clock
    ELSE
    @ SLEEP
    ENDIF
    Goto loop


    Then when my countdown in the INT handler reaches the desired value, I disable the INT for TMR0 and set CRITICAL to 0 so the main loop will behave as it should: have a sleep when the INT handler has been processed.
    My question is: when sleeping, the interrupt will be handled then MCU will go back to "goto loop" or will it continue the "@ sleep"?????

  7. #7
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Smile

    Quote Originally Posted by skimask View Post
    At 8Mhz, there are 2,000,000 instructions cycles per second.
    Assuming a 1:1 prescaler, with an 8 bit counter, you'll get 7812.5 Tmr0 overflow interrupts per second.

    256 * .5US = 128 US per overflow!

    You're off by 1,000 !
    Jeeze! You are right. Sorry, I should have more @ SLEEP myself

  8. #8
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    It would return to goto loop. The sleep instruction has already been executed.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  9. #9
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Smile

    Quote Originally Posted by Bruce View Post
    It would return to goto loop. The sleep instruction has already been executed.
    FIne, then that's what I need, right.
    It would work...
    Thank you very much.

  10. #10
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    Well, it does not work as expected.

    First I have a problem with the other interrupts (I poster a message today about this) but with my settings I was expecting a TMR0 overflow evey 10ms but it happens every 1ms...

    TMR0 starts at 98, and I'm using a 8MHz intosc.
    0.5Us per instruction cycle (FOSC/4).

    Strange...

  11. #11
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by xnihilo View Post
    Well, it does not work as expected.

    First I have a problem with the other interrupts (I poster a message today about this) but with my settings I was expecting a TMR0 overflow evey 10ms but it happens every 1ms...

    TMR0 starts at 98, and I'm using a 8MHz intosc.
    0.5Us per instruction cycle (FOSC/4).

    Strange...
    8,000,000 Hz oscillator / 4 = 2,000,000 instructions/second = 2,000,000 increments of TMR0 using a prescale of 1:1 (prescaler assigned to WDT).
    TMR0 is an 8 bit timer, max count = 256. You're reloading it with 98, leaves you with 158 counts.
    2,000,000 / 158 = 12,658.228 Hz = 79us per interrupt.
    2,000,000 / 256 = 7812.5 Hz = 128us per interrupt.
    So, you're 10ms theory (since we don't have any better information) isn't going to work.
    But this might:
    http://www.mister-e.org/pages/picmulticalcpag.html

  12. #12
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    8Mh/4 = 2000000 op per s.
    1:128 prescale = 2000000/128 = 15625 per s.
    Preload with 98, 158 counts.
    15628 / 158 = 98.89 Hz
    1000ms/100 = 10ms

    What's wrong?

  13. #13
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by xnihilo View Post
    1:128 prescale = 2000000/128 = 15625 per s.
    What's wrong?
    You left out that vital bit of information (the 1:128 prescale).

    So, it's happening every 1ms instead of 10ms?
    Are you sure you're correctly clearing/re-enabling the correct interrupt after you are done processing the interrupt...or is the interrupt sequence 'jumping right back into itself' after you are done processing it?
    Last edited by skimask; - 19th August 2008 at 15:07.

Similar Threads

  1. Won't go back to SLEEP after 1st Interrupt
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 29th June 2009, 09:00
  2. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  3. Sleep Mode
    By Pesticida in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 13th March 2008, 10:31
  4. Ping Darrel Taylor - Timer0 Instant Interrupt
    By JEC in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 9th January 2007, 11:20
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

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