What do you mean poll the pin in there? The ISR?
Yes, in the timer ISR.
i.e. disable change interrupts, and only use the timer ISR.
Save the previous state of PORTB in a global variable (ANDed with a mask to remove the bits you are not interested in)
How do you count the interrupts? I don't follow what your explaining.
Each time through the interrupt, you can increment (or decrement) a variable. That is "counting interrupts".
Assume you have two variables (each is one byte)
and you have defined a mask of which PORTB bits you are using
SWMASK equ B'00001111' ;switch mask
DBCOUNT equ 10 ;debounce period (#interrupts)
then you could do something like this to detect when no key has changed for ten interrupt cycles:
(note, I'm assuming all variables are in bank 0)
ANDLW SWMASK ;discard unused pins
MOVWF new_portb ;save for later
XORWF old_portb,w ;check if this is the same as the old value
skipnz ;skip if non-zero
;here if buttons have changed
XORWF old_portb,f ;update old_portb to match new value
GOTO swdone ;done processing
no_change: ;here if keys still the same
GOTO swdone ;count was already zero, so nothing to do
;here if we are in the middle of debouncing
DECFSZ debounce_count,f;dec count, skip if zero
GOTO swdone ;count > 0, so nothing to do yet
;here if count has hit zero
;....... add code here to do something because a button has just changed
swdone: ;all code exits to this point
I just type the above off the top of my head, but I hope you get the idea.
The only "trick" I've used is the two XORWF instructions to avoid using a third variable for temporary storage of the new PORTB value