Hola, estoy realizando un frecuencímetro en una pantalla GLCD. Todo funciona perfectamente, la frecuencia medida es precisa y la escritura en el GLCD es correcta. El frecuencímetro es solo una de las funciones que tiene el proyecto. Por lo tanto es tan solo un Sub-Menu del mismo y para salir de la funcion del frecuencimetro debo presionar una tecla para volver al menú anterior. El problema que tenía era que se debía esperar 1 segundo para que se testeara el boton y se realizara la funcion para volver al menú anterior ya que 1 segundo es lo que toma el muestreo de la frecuencia y el metodo usado es preciso pero mantiene al procesador ocupado en eso.
Así que lo mas lógico para que el procesador no deba testear siempre los pulsadores los testeo en una interrupción por flanco sobre la patilla RB0. Hasta aquí todo bien, el problema es, como hago si en la interrupcion detecto que se presiono el pulsador, salir de la interrupcion y a su vez de la funcion del frecuencimetro donde me encontraba antes? Un return; solo me provoca una salida de la interrupción así que use goto_address(); para irme a la dirección de la memoria donde termina la funcion del frecuencimetro y sigue el programa normalmente. Este metodo funciona pero tiene el problema que por consiguiente al no salir como se debe de la interrupción produce un Overflow del stack al entrar y salir varias veces de la interrupción. Mi humilde pregunta y para no se mas extenso, como puedo hacer para evitar este overflow? Hay algun otro metodo que me permita salir de la interrupcion y a su vez de la funcion anterior?
Muchisimas gracias
PD: adjunto la parte del programa de la interrupcion y el frecuencimetro.
#INT_EXT //testeo de los pulsadores y su funcion
VOID RB0_ISR (VOID){
IF(!mux_read(6)){ //testeo si presiono el boton para volver
setup_timer_1(T1_DISABLED); //si presione el boton desactivo el timer
BUT_FREC = 0; //los botones ya no se usan para el frecuencimetro
clear_interrupt(INT_EXT); //habilito otra vez las interrupciones porque el compilador las desactiva aqui para evitar que
enable_interrupts(INT_EXT); //entre de nuevo y borro el flag
enable_interrupts(GLOBAL);
goto_address(DIR_FIN_FREC); //y me voy a la direccion de la memoria donde esta el siguiente paso a la funcion
} //frec(); de este modo salgo de la misma :D
}
La funcion mux_read(); es una funcion que cree yo que simplemente lo que hace es leer el pin a traves de un multiplexor, funciona correctamente, seria lo mismo a decir IF(!input(PIN_B0))
Este es el código del frecuencimetro
WHILE(1){ //bucle infinito
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1); //activo el TIMER 1
WHILE(cycles != 587825){ //con este bucle demoro 1 segundo
IF(t1_overflow){ t1_overflow = 0; ++OVER; } //testeo si desborda el TIMER 1
++cycles;
}
reinicio:
setup_timer_1(T1_DISABLED); //desactivo el TIMER 1
glcd_text57(0,20,FREQ,2,OFF); //borro la frecuencia anterior del GLCD
IF(t1_overflow){ t1_overflow = 0; ++OVER; } //testeo por ultima vez el desbordamiento del TIMER 1
FRECC = make32(OVER,get_timer1()); //uno el valor del TIMER y los OVERFLOW en un INT32 para tener la frecuencia
glcd_text57(0,20,FREQ,2,ON); //escribo la frecuencia en el GLCD y lo actualizo
glcd_update();
set_timer1(0); OVER = 0; cycles = 0; //inicializo variables
}