Hola! Bueno, una vez ya me pasó... En primer lugar, al atender la interrupción por cambio en RB, hay que resetear el bit RBIF (INTCON.0) por soft; caso contrario, al salir de la rutina el micro volverá a entrar y asi for ever...
En segundo lugar, la interrupción es por cambio. Es decir que si nuestra rutina es muy rápida (por lo general es así), es muy probable que presionemos el pulsador, se atienda la rutina y cuando soltemos el pulsador (así sea un click) ya hayan pasado muchos ciclos desde que se salió de la rutina de interrupción deseada y volvamos a entrar a la interrupción(hubo un cambio en RB). No son rebotes del pulsador ni nada de eso...
Algo que funciona: deja los pulsadores ahí donde están, pero no uses la interrupción por cambio en RB. Casi siempre se necesita, en cualquier proyecto, una base de tiempos. Yo uso el timer0 para las rutinas de demora de milisegundos, segundos, etc. Entonces, cada vez que tengas una interrupción del timer0 (cada 5, 10 ó 20 ms, por ejemplo) copias el estado de RB a un registro, filtras para que queden los pulsadores, si hay uno pulsado, activas un flag (por ejemplo, el bit 7 de tu registro de teclas) y listo!
En el programa principal chequeas el flag de tecla y sabes que hacer si hay tecla, sin que estar chequeandolo en el codigo principal...
Bueno, confuso, no?
pero prueba, que funciona y da buen resultado!
Saludos y suerte!
Ah! como dice Jonathan, con unos 5 o 10 ms se tienen resultados más que buenos...