Más o menos para darte una idea, necesitas un temporizador de los que tienes disponibles y que este siempre funcionando. Funcionará como temporizador del sistema. Digamos que lo configuras para que cada 1000 conteos de ciclos genere 1 ms. También necesitas una variable para capturar el valor del temporizador.
Tu lazo while 1 será así:
while (1)
{
case 1:
menu = reposo; // al final de cada case, vuelvo a reposo
break;
case 2:
menu = reposo; // al final de cada case, vuelvo a reposo
break;
case 3:
menu = reposo; // al final de cada case, vuelvo a reposo
break;
....
case reposo: break;
case antirebote:
if ((obtenerValorTemporizador() - retardo) > _10ms) //cuando transcurran 10 ms, relaiza el proceso que necesitas
{
menu++; /*****************************/
if (menu >2) menu = 0; /*** En este case hago la modificación de menu ***/
lim_pant = 1; /*************************************************/
}
break;
}
Por defecto menu será igual a reposo.
Cuando suceda la interrupción, puedes hacer algo así:
if (INTCON.INTF)
{
if (reposo == menu)
{
menu = antirebote;
retardo = obtenerValorTemporizador(); //capturo un valor del temporizador.
}
INTCON.INTF = 0;
}
Cuando ocurra una interrupción, si menu está en reposo se cambia menu a antirebote y en la variable retardo se captura el valor que tenga ese instante el temporizador (Cualquiera que tenga)
No importa cuantas veces suceda la interrupción, como menu ya no es igual a reposo, ya no ejecutará lo que hay dentro del if:
Ahora si analizas el case antirebote, verás un if que compara el valor del temporizador menos el capturado. Como dije arriba suponiendo que 1000 ciclos de conteo son 1 ms, entonces _10ms es 10000 ciclos.
Este case, denominado antirebote, se ejecuta hasta que pasen los 10ms (o el tiempo que logres determinar que es el correcto para eliminar el rebote), cambias el valor de menu y se ejecuta cualquiera de los otros cases. Y ojo.. Cuando finalizas cualquiera de los otros cases, vuelves a poner la variable menu a reposo para otra pulsación