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.
Suitable Prescaler values are shown here...
INT Freq |
OSC |
|
INT Freq |
OSC |
4 |
8 |
16 |
10 |
20 |
>=2 hz |
8 |
- |
- |
>=5 hz |
8 |
- |
>=4 hz |
4 |
8 |
- |
>=10 hz |
4 |
8 |
>=8 hz |
2 |
4 |
8 |
>=20 hz |
2 |
4 |
>=16 hz |
1 |
2 |
4 |
>=40 hz |
1 |
2 |
>=32 hz |
1 |
1 |
2 |
>=80 hz |
1 |
1 |
>=64 hz |
1 |
1 |
1 |
|
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.
|
Prescaler |
T1CON |
8 |
$30 |
4 |
$20 |
2 |
$10 |
1 |
$00 |
|
A few more examples.
10hz @ 4 mhz |
100hz @ 20 mhz |
1000hz @ 16 mhz |
@Freq
= 10
@Prescaler = 2
T1CON = $10 |
@Freq
= 100
@Prescaler = 1
T1CON = $00 |
@Freq
= 1000
@Prescaler = 1
T1CON = $00 |
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
Code Size = 232 words
Last Edited: 09/04/2006