buy hot The Fixer cool video Year One download Kasabian album nice Terminator Salvation hit cool track Jordin Sparks USA Whatever Works video download Check My Brain melodies nice video Finding Nemo nice Pop - Various Artists hit cheap DIVX Year One

digital-diy.com

Swordfish Code Snippet - TMR0 Print E-mail
( 0 Votes )
  
Saturday, 04 April 2009 10:19

TMR0 is an 8 byte timer/counter that can be pre-scaled to change vary its incrementing cycle. It is quite different in regards to setting up compared to the 16F's, but here's an example.


Pre-scaling is important as we may want the Timer Register to increment faster/slower in different applications. The speed in which it does cycle is dependent on both the external crystal speed and the pre-scaling options, or the Prescaler and external clock if an external source is used.


Now to make a timer that can be used to count mS very accurately. An easy way to find out how much time each clock cycle will take is to use a pic timer calculator such as this. Make sure that the Internal Check Box is selected, now be sure that 20Mhz is the clock speed, and the pre-scaler is set to 1:32, you will see that the TMR0 period is now 1.638mS, so every time the TMR0 clock reaches 255, and rolls over to 0, 1.638mS has elapsed. To make things easier, I will work with a scale of 1000 for my mS counter. Now when mS = 10000, 10mS has elapsed, so there is no need to use Floats.


The sub routine "TMR0_Initialize" goes through the required steps to set up TMR0, follow the code at your own pace;

 

Device = 18F452
Clock = 20
 
Dim
    mS As Word,
    TMR0ON As T0CON.7,
    T08BIT As T0CON.6,
    T0CS As T0CON.5,
    T0SE As T0CON.4,
    PSA As T0CON.3,
    TMR0IF As INTCON.2,
    TMR0 As TMR0L,
    TMR0IE As INTCON.5,
    TMR0_Event As Boolean
 
Interrupt TMR0_Interrupt()
    Save(0)                  // Backup system variables
    If TMR0IF = 1 Then       // Check if a TMR0 Interrupt occurred
        TMR0IF = 0           // Clear the interrupt
        Inc(mS, 1638)        // Increment the mS counter (scale of 1000)
        If mS >= 10000 Then  // Working with a scale of 1000, so this
            mS = mS - 10000  //  checks if 10mS has elapsed
            TMR0_Event = True
        EndIf
    EndIf                  
    Restore                  // Backup system variables
End Interrupt
 
Sub TMR0_Initialize()
TMR0ON = 0               // Disable TMR0
T08BIT = 1               // Ensure TMR0 is working in 8 Bit mode
T0CS = 0                 // Ensure TMR increments from internal clock
T0SE = 0                 // Only used if external source is selected
PSA = 0                  // Ensure the Clock source uses the Prescaler
T0CON.0 = 0              // Set the Prescaler bits
T0CON.1 = 0              //
T0CON.2 = 1              //
TMR0 = 0                 // Clear the TMR0 register
TMR0IE = 1               // Enable TMR0 Interrupts
Enable(TMR0_Interrupt)   // Enable the TMR0 Interrupt Handler
TMR0ON = 1               // Enable TMR0 to increment
End Sub
 
// Start Of Main Program...
mS = 0                       // Reset the mS counter
TMR0_Event = False           // Clear the TMR0 Event Flag
TMR0_Initialize              // Setup and enable TMR0
Low(PORTB.0)                 // Make PORTB.0 and output and set it low
 
While True
    While TMR0_Event = False // Wait for 10mS to elapse
    Wend                     //
    TMR0_Event = False       // Reset the Event Flag
    Toggle(PORTB.0)          // Toggle PORTB.0
Wend                         // Loop forever

 

The result, a very accurate interrupt;

 

TMR0

Note the PIC's power supply/oscillator are not shown

Comments (3)
  • King Snake  - interrupt

    Thanks for another helpful article. One question though. Why is there an if statement in your interrupt?

    TMR0IF must be 1 if the interrupt was triggered, correct? Making the if statement that exists in TMR0_Interrupt redundant?

    Thanks

  • Graham

    Hi King Snake :)

    > Why is there an if statement in your interrupt?

    There could be any number of other interrupts being handled by the same interrupt vector. I put it in there for good practice should the code be used in such applications by others :)

    You are correct though, if TMR0 was the sole interrupt, then you would not *need* the if statement.

    Cheers, Graham

  • King Snake

    Graham,
    Thanks for the help! I used this to create a interrupt driven servo routine, so the servo is always driven to a position. I posted it in the forum. It would be great if I could convert it into a module, but I'm not there yet. Maybe Later.
    Thanks!
    -King Snake

Write comment
Your Contact Details:
Comment:
[b] [i] [u] [url] [quote] [code] [img]   
Security
Please input the anti-spam code that you can read in the image.
Last Updated ( Tuesday, 14 April 2009 10:37 )
 

Whos Online

  • andyo
  • Jon Chandler
  • MrDEB

Forum Activity