I understood that timer increments a value in its register according to a prescaler until overflow occcurs in which case it will send an interrupt.
This is partially correct. The value is incremented based on the selected clock input and the prescalar. The prescalar simply divides the clock input into different units of time. I will use an example from Microchip's Application Note AN580.
Assuming you have selected an external clock source (TMR1CS
set) and that clock source is 32.768kHz, the frequency that is input into your prescalar function block is 32.768kHz. Your prescalar is selectable between the following ratios: 1:1, 1:2, 1:4, and 1:8 by setting T1CKPS1
and T1CKPS0
to the desired value. The frequency of the clock that will increment the TIMER1 register can be any of the following:
Prescale....T1CKPS1....T1CKPS0....FREQUENCY(kHz)
1..................0..................0.................32.768
2..................0..................1.................16.384
4..................1..................0.................8.192
8..................1..................1.................4.096
The overflow time is the time it takes for TIMER1 to count to its max value. With a 16 bit counter, you have a maximum count of 2^16 = 65536 counts. The overflow time is simply the number of counts, divided by the frequency. This gives us the following overflow times based on the prescale values:
Prescale....FREQUENCY(kHz)....TIME(s)
1..................32.768........................2
2..................16.384........................4
4..................8.192..........................8
8..................4.0961........................16
Finally, TIMER1 has match registers TMR1H
and TMR1L
. This allows us to set a value below the maximum count which will produce the same overflow time effect. Again, you simply divide the number of counts by the frequency. For example, we can now produce the following times assuming that we selected Prescale 1:
TMR1H....TMR1L....TIME(s)
0x80..........0x00.........1
0xC0..........0x00.........0.5
0xE0..........0x00.........0.25
0xF0..........0x00.........0.125
The following code snippet is from Microchip's Application Note AN580 and it gives an example of setting up a 1 second interrupt on TIMER1. I would recommend that you read through the application note in its entirety and realize that this is an example of using an external oscillator. You also have the option of using your internal clock frequency as well - which will probably give you more granular timing.
START
CLRF STATUS ;Do initialization (Bank0)
BCF T1CON, TMR1ON ;Timer1 is NOT incrementing
:
: ;Do initialization stuff here
:
MOVLW 0x80 ;TIM1H:TMR1L = 0x8000 gives 1 second
MOVWF TMR1H ; overflow, at 32kHz.
CLRF TMR1L
;
CLRF INTCON
CLRF PIR1
BSF STATUS, RP0 ;Bank1
CLRF PIE1 ;Disable all peripheral interrupts
;
BSF PIE1, TMR1IE ;Enable TMR1 Interrups
;
; Initialize the Special Function Registers (SFR) interrupts
;
BCF STATUS, RP0 ;Bank0
CLRF PIR1
BSF INTCON, PEIE ;Enable Peripheral Interrupts
BSF INTCON, GIE ;Enable all Interrupts
;
MOVLW 0x0E
MOVWF T1CON ;Enable T1 Oscillator, Ext Clock, Async, prescaler = 1
BSF T1CON, TRM1ON ;Turn Timer1 ON
;
zzz SLEEP
GOTO zzz ;Sleep, wait for TMR1 interrupt
What I don't understand is how I should configure a prescaler so that timer would send an interrupt with time interval that I choose (say, 1s).
You can use this formula to determine your time: Time = Count / (Freq / Prescale)