TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: naieto en 05 de Junio de 2006, 14:40:02
-
Hola gente, hay alguna forma de salir abruptamente de una interrupcion antes que esta finalice? ejemplo:
blablalba
#INT_EXT
funcion1()
{
for(contador_1=0;contador_1<=10;contador_1++)
{
for(contador_2=0;contador_2<=100;contador_2++)
{
for(contador_3=0;contador_3<=200;contador_3++)
{
if(input(PIN_B1))
{
TERMINAR CON LA INTERRUPCION
}
output_high(PIN_A0);
}
}
}
}
main()
{
blablabla;
while(1)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(L_TO_H);
output_low(PIN_A0);
}
}
Si aprieto un pulsador en rb0 entro en funcion1 y me prende un led hasta que termine la interrupcion (es decir hasta que terminen de contar los for anidados), pero si aprieto un pulsador en rb1 antes que termine dicha interrupcion quiero que esta finalice inmediatamente. Al principio crei que si desabilitaba la interrupcion inmediatamente salia, pero no es asi por las pruebas que hice.
gracias
-
Si bien no es una solución elegante... podrias hacerlo. Has probado con ¿exit? ¿return? ¿goto?
De todas formas, tener rutinas grandes en una rutina de interrupción no es para nada aconsejable y es una mala práctica de programación que debieras comenzar a evitar. Eso te acarrea mas problemas que soluciones y además no atenderías otra interrupción mientras procesas la actual.
Saludos
-
Puedes utilizar un antiestético goto que te mande al final de la función de interrupción.
P.D.: veo que se me ha adelantado Maunix con la misma solución :D
-
Bueno muchachos, contestaron mas rapido de lo que esperaba. Gracias, voy a probar lo que me sugirieron. Pregunte por las dudas que hubiera alguna funcion especifica de la interrupcion, pero veo que no solo no existe sino que no se usa hacer esto.
Salu2
Sebastian Nieto
-
si , es lo malo que tiene al recrearse en ellas mucho tiempo
#INT_EXT
/************************************************************/
Mi_interrupcion(){
/************************************************************/
if ((pulsador & 1)== 1){ // segunda pulsacion
contador_1 = 11; // lo cual forzara a salir de todos los "for"
contador_1 = 101;
contador_1 = 201;
}
Pulsador ++;
}
/************************************************************/
funcion1(){
/************************************************************/
for(contador_1=0;contador_1<=10;contador_1++)
{
for(contador_2=0;contador_2<=100;contador_2++)
{
for(contador_3=0;contador_3<=200;contador_3++)
{
output_high(PIN_A0);
}
}
}
}
/************************************************************/
main() {
/************************************************************/
blablabla;
byte pulsador;
Pulsador = 0;
while(1)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(L_TO_H);
output_low(PIN_A0);
if ((pulsador & 1)== 1){funcion1();} // o verificar la bandera que la produjo
}
}
yo usaria banderitas
Este ejemplo quizas no funcione , solo es una idea .
-
Me gusto la idea de hacer
contador_1=11
contador_2=101
contador_3=201
asi me evito usar un goto que recuerdo una vez haberme traido problemas al compilar, no se si a alguien le paso tambien de no poder compilar con goto o fue algun problema mio.
-
pues si que no es muy estetico el goto no ?
y ademas que se te dijo en el curso sobre los saltos dentro de las interrupciones?
jejeje :lol:
Como andas seba veo que por fin te animaste a postear bueno solo saludarte y darte la vienvenida y
-
Bueno, agradezco la ayuda, les cuento que al final puse un if(blablabla) {break;} dentro del lazo for para salir inmediatamente de este y por ende en mi ejemplo salir de la interrupcion. Todo esto venia porque queria hacer un programa que me prenda un led en ra0 si mantenia apretado un pulsador en rb0 un tiempo minimo, si no llegaba a ese tiempo minimo que no haga nada. Aca dejo el programita por si a alguien le interesa:
# INCLUDE <16F84.h>
# USE DELAY(clock=4000000)
# FUSES HS,NOWDT,NOPUT
# USE FAST_IO(A)
# USE FAST_IO(B)
int contador_1;
int contador_2;
int contador_3;
int1 estado_pulsador=0;
#INT_EXT
funcion1()
{
estado_pulsador=1;
for(contador_1=0;contador_1<=5;contador_1++)
{
for(contador_2=0;contador_2<=100;contador_2++)
{
for(contador_3=0;contador_3<=200;contador_3++)
{
if(!input(PIN_B0))
{
estado_pulsador=0;
break;
}
if(estado_pulsador==1)
{output_low(PIN_A0);
}
}
}
}
}
main()
{
set_tris_a(0);
set_tris_b(1);
output_low(PIN_A0);
while(1)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
ext_int_edge(L_TO_H);
if(estado_pulsador==1)
{
output_high(PIN_A0);
delay_ms(2000);
output_low(PIN_A0);
estado_pulsador=0;
}
}
}
Cualquier sugerencia para mejorarlo es aceptada por supuesto
salu2 Seba Nieto
-
Yo pondria:
#define TRUE 1
#define FALSE 0
inicializo la variable Salir = FALSE;
en cada for ponemos (por ejemplo): (contador_1<5) && (!Salir)
Si ponemos Salir=TRUE
Todos los bucles terminan
Un saludo.
-
Hola, bueno creo que tambien es posible que en donde quieras finalizar la interrupcion escribas en ASM la instruccion RETFIE, pero cuidado, recuerda que si haces esto deberias recuperar los registros W, STATUS y todo lo que pretendas mantener al ingresar al la interrupcion antes de retornar de ella, esto en C es automatico, bueno dejo la idea, obviamente requiere conocer algo de ASM.
saludos.
-
Hola, bueno creo que tambien es posible que en donde quieras finalizar la interrupcion escribas en ASM la instruccion RETFIE, pero cuidado, recuerda que si haces esto deberias recuperar los registros W, STATUS y todo lo que pretendas mantener al ingresar al la interrupcion antes de retornar de ella, esto en C es automatico, bueno dejo la idea, obviamente requiere conocer algo de ASM.
saludos.
Yo no haría eso. El C no solo guarda el contexto típico del pic sino que también suele guardar contextos propios del stack interno que utiliza para sus propias variables.
Hacer algo asi, volvería de la rutina de interrupción pero nos podría acarrear otros problemas como sobreescritura de variables por no haberse vaciado correctamente la pila, etc.
Saludos