The Timer Template

This is a "Template" that can be a "Starting point" for programs that need to have interrupts generated at a specific frequency. It's range is between 2 hz and 30khz, although upper and lower limits are dependant on the OSC frequency.

With this you can create a "Time Base" that can be used to control the time between any number of actions. Possibilities include, Counting Time, Interrupt timed PAUSE's, PWM or Servo control, Multiple timed events, Frequency measurement, and on and on. There are so many possibilities, there's no way to cover them all, so it's up to you to figure out how to make it work with your application. All I can do is give you a starting point.

The template allows easy selection of the interrupt frequency by changing the Freq, Prescaler and T1CON values. The frequency will remain constant and cannot be changed during Run-Time. Although it can be stopped and started at will. Everything required to maintain the interrupt frequency is already in the program. All you need to do is "Fill-in" the Main program, and the T1handler. T1handler: will be called on each interrupt, and the Main: program can be doing other things at the same time.

For instance:
With an OSC of 16, and an interrupt frequency of 10hz, you would need a prescaler of 8 as indicated by the RED number in the table.

If you choose a prescaler that is too small for the requested frequency, the compiler will let you know. But you should try to use the smallest prescaler you can to get the best accuracy.

Once you know the required prescaler, you must change both the @Prescaler and T1CON values to match.



Note: @Prescaler and T1CON settings MUST match!






 Template 1: Generic Timer Interrupts at a Specified Frequency.
; Initialize your hardware first

DEFINE OSC 20

INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System
INCLUDE "ReEnterPBP.bas"     ; Include if using PBP interrupts

ASM
INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
        INT_Handler   TMR1_INT,   ReloadTMR1,   ASM,  no    ; MUST be first
        INT_Handler   TMR1_INT,   _T1handler,   PBP,  yes
    endm
    INT_CREATE               ; Creates the interrupt processor
ENDASM

;--- Change these to match the desired interrupt frequency -------------------
;--- See http://DarrelTaylor.com/DT_INTS-14/TimerTemplate.html for more Info.
@Freq       = 10                  ; Frequency of Interrupts in Hz
@Prescaler  = 8                   ; Timers Prescaler setting
T1CON = $30                       ; $30 = Prescaler 1:8, TMR1 OFF
; $00=1:1, $10=1:2, $20=1:4, $30=1:8 --  Must match @Prescaler value

@ INT_ENABLE  TMR1_INT            ; enable Timer 1 interrupts
GOSUB StartTimer                  ; Start the Timer

;____Your Main Program goes here______________________________________________
Main:
  ;   ---- Your Main Program goes here ----
GOTO Main

;____This routine is Called on each TMR1 Interrupt____________________________
T1handler:
  ;   ---- Your interrupt routine goes here ----

@ INT_RETURN

;---[TMR1 reload - interrupt handler]-----------------------------------------
ASM                               ; Calculate Timer Reload Constant
ReloadInst  = 8                   ; # of Intructions used to reload timer
  if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
MaxCount    = 65536 + (ReloadInst / Prescaler)
TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
    if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
        error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
    endif
  else
      error Invalid Prescaler
  endif
ENDASM

@Timer1 = TMR1L                   ; map timer registers to a word variable
Timer1       VAR WORD EXT
TimerReload  CON EXT              ; Get the External Constant
TMR1ON       VAR T1CON.0          ; Alias the Timers ON/OFF bit

;---Reload Timer1------
ASM
ReloadTMR1
    MOVE?CT  0, T1CON, TMR1ON     ;  1     stop timer
    MOVLW    LOW(TimerReload)     ;  1     Add TimerReload to the 
    ADDWF    TMR1L,F              ;  1     value in Timer1
    BTFSC    STATUS,C             ;  1/2
    INCF     TMR1H,F              ;  1
    MOVLW    HIGH(TimerReload)    ;  1
    ADDWF    TMR1H,F              ;  1
    MOVE?CT  1, T1CON, TMR1ON     ;  1     start timer
  INT_RETURN
ENDASM

;---Start/Stop controls -----
StartTimer:
    Timer1  = TimerReload         ; Load Timer
    TMR1ON = 1                    ; start timer
RETURN

StopTimer:
    TMR1ON = 0                    ; stop timer
RETURN
Page last modified on March 02, 2018, at 04:23 AM