Swordfish Code Snippet - TMR1

From the 18F452 datasheet:

The Timer1 module is a 16-bit timer/counter consisting of two 8-bit registers (TMR1H and TMR1L) which are readable and writable. The TMR1 register pair (TMR1H:TMR1L) increments from 0000h to FFFFh and rolls over to 0000h. The TMR1 interrupt, if enabled, is generated on overflow which is latched in interrupt flag bit, TMR1IF (PIR1). This interrupt can be enabled/disabled by setting/clearing TMR1 interrupt enable bit, TMR1IE (PIE1).

Timer1 can operate in one of two modes:
    a) As a Timer
    b) As a Counter

The operating mode is determined by the clock select bit, TMR1CS (T1CON). In Timer mode, Timer1 increments every instruction cycle. In Counter mode, it increments on every rising edge of the external clock input.

TMR1 has a 2 bit pre-scaler, and a 16bit register that can be configured to increment on an external clock, or internal FOSC (OSC/4).

There's a little more to setup than TMR0, although TMR1 is a great tool for many applications. Here's an example of how to set up your program for use with TMR1 for a 10mS interrupt (a timer calculator was used to configure the settings in this program:

 Device = 18F452
Clock = 20
 mS As Word,
 TMR1IE As PIE1.0, // TMR1 Interrupt Enable
 TMR1IF As PIR1.0, // TMR1 Interrupt Flag
 TMR1ON As T1CON.0, // TMR1 Count Enable
 Timer1 As TMR1L.AsWord // A quick way of creating a Word Alias
 TMR1StartVal = 15536, // User defined TMR1 starting value
 TMR1ReloadVal = TMR1StartVal + 5
Interrupt TMR1_Interrupt()
 Save(0) // Back up system variables
 If TMR1IF = 1 Then
 TMR1ON = 0 // Disable TMR1
 Timer1 = TMR1ReloadVal // Reload a new start value (includes non-counted cycles while disabled)
 TMR1ON = 1 // Enable TMR1
 TMR1IF = 0 // Clear the TMR1 Interrupt
 Inc(mS, 10) // Increment mS by 10
 Restore // Restore system variables
End Interrupt 
Sub TMR1_Initialize()
 TMR1ON = 0 // Disable TMR1
 T1CON.1 = 0 // 1 = External clock from pin RC0/T1OSO/T1CKI (on the rising edge)
 // 0 = Internal clock (FOSC/4)
 'TRISC.0 = 1 // If External clock, then set clock as an input    'T1CON.2 = 1 // 1 = Do not synchronize external clock input   // 0 = Synchronize external clock input
 // When T1CON.1 = 0;
 // this bit is ignored.
 T1CON.4 = 0 // 11 = 1:8 prescale value
 T1CON.5 = 0 // 10 = 1:4 prescale value
 // 01 = 1:2 prescale value...
 // 00 = 1:1 prescale value
 Timer1 = TMR1StartVal // Fill the Timer register with a starting value
 TMR1IE = 1 // Enable TMR1 Interrupts
 TMR1ON = 1 // Enable TMR1 to Increment
 Enable(TMR1_Interrupt) // Enable TMR1 Interrupt Handle
End Sub 
// Start Of Main Program...
mS = 0 // Clear the mS counter
TMR1_Initialize // Setup and enable TMR1
Low(PORTB.0) // Make PORTB.0 an output, and set it low
While True
 While mS <> 100 // Wait for mS = 100
 Wend //
 mS = 0 // Reset the mS counter
 High(PORTB.0) // Toggle PORTB.0
 Low(PORTB.0) //


And the result, a perfect 100mS (10Hz) interrupt:


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

Forum Activity

Member Access