The following code can be used or modified to do what you want. Everything is done in the background.
The good thing about it, is that it can be used on any port - not just port B.
And it will watch a large number of tachs - not just 8 (of course, you have to expand the ASM section).
It does NOT need a debounce - as long as the sample interval is longer than the expected bounce time.
The sample interval is set by the TMR0 interrupt rate. The interrupt rate must be high enough to 'catch' every
HIGH and LOW of the input. So if the HIGH time of the input is 10 mSec and the LOW time of the input is 30 mSec,
then the interrupt must be faster than 10 mSec.
As written, the code will run for 1000 interrupt times, then quit. if you don't want it to stop, and only count trasitions, simply eliminate
the TACHCLOCK part.
(as written)
To start,
Clear the TachCounters
Clear TPE
In your main loop, check for TPE to be set. If it is,
Read the TachCounters
Clear the TachCounters
Clear TPE
Code:
INCLUDE "DT_INTS-18.bas"
ASM
INT_LIST macro
INT_Handler TMR0_INT, ReadTachs, ASM, yes
endm
INT_CREATE
ENDASM
Goto OverInt
'---[TMR0 interrupt handler]---------------------------------------------------
Asm
ReadTachs
movff PreloadH,TMR0H ; Preload depends on clk speed
movff PreloadL,TMR0L
btfsc TPE,0
bra DoneForNow
infsnz TachClock
incf TachClock + 1
movlw 0x03 - 1 ; Real value is 1000 = 0x3E8, but must have one less
cpfsgt TachClock + 1 ; to compare with greater than
bra TachRoutine
movlw 0xE8 - 1 ; Likewise, subtract one here, too.
cpfsgt TachClock
bra TachRoutine
bsf TPE,0
clrf TachClock
clrf TachClock + 1
bra DoneForNow
TachRoutine
movf PORTF,0,0
movwf Temp,0 ; Save VAR so can't change between compare and save
xorwf OldPortF,0,0
movwf changedF,0
movff Temp,OldPortF
Tach1
btfss changedF,0
bra Tach2
infsnz Tach1Counter
incf Tach1Counter+1
Tach2
btfss changedF,1
bra Tach3
infsnz Tach2Counter
incf Tach2Counter+1
Tach3
btfss changedF,2
bra Tach4
infsnz Tach3Counter
incf Tach3Counter+1
Tach4
btfss changedF,3
bra DoneForNow
infsnz Tach4Counter
incf Tach4Counter+1
DoneForNow
bcf INTCON,2 ; Clear the TIMER0 interrupt flag
INT_RETURN
ENDASM
OverInt:
TachCounter1=0:TachCounter2=0:TachCounter3=0:TachCounter4=0
asm
movff PreloadH,TMR0H ; Preload depends on clk speed
movff PreloadL,TMR0L
bcf INTCON,2
endasm
TPE = 0
INT_ENABLE TMR0_INT
(your code here)
Bookmarks