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