Question

I'm currently learning PIC assembly and I have come to the topic of timers. I understood that timer increments a value in its register according to a prescaler until overflow occurs in which case it will send an 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). Example code would be appreciated.

(I'm using Timer1 in PIC16F877A)

Était-ce utile?

La solution

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)

Autres conseils

you have to set prescaler value of timer0 like T0PS<2:0> = 001 you can also use TOCON last 3 bits for assigning like TOCON = 00000111 prescaler is responsible to increase cycle count if your timer make interrupt in 10ms and if you assign prescaler to 2 your interrupt occur in 20 ms however you have to consider that TOPS<2:0>=0 means your prescaler is 2. In addition you have to PSA=0 to use Prescaler for timer0.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top