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