Suspender-Salir-Romper funcion por interrupcion

Me encuentro con el problema de que durante el curso de una funcion esta es interrunpida por INT_EXT, las dos tratan los mismos valores pero solo deben prevalecer los resultados que opero INT_EXT. Una vec que se salta a la int_ext no se debe volver al punto donde salto dentro de la funcion. De hecho esta ya es perjudicial que altere los mismos valores que trato le interrupcion.

Se me ocurre preguntarle a la funcion por un "int1 rompe=1 continuamente" para que esta se rompa pero esto es muy pesado y no tiene porque coincidir el punto de reentrada con este "if" (puede ser tarde)

Luego esta el "go to" que dicen que es lo ultimo que hay que hacer

Hay alguna forma de saltarse la funcion actual despues de una interrupcion???
 
Como haber, hay, pero me parece un metodo de programacion muy problematico. La manera de hacerlo es tocar los valores en el stack, que es donde se almacena la direccion de retorno de la interrupcion. Pero andar tocando el stack es para problemas, ademas que el mantenimiento de ese codigo es casi imposible.

Suena a un problema logico que deberia ser facil de resolver, cuando la funcion principal termina de procesar los datos, va y se fija que valores ha creado la rutina de interrupcion (si los hubiera) y si los hay, les da precedencia.

Lo mejor en estos casos es colgar el codigo en cuestion.
 
cuando la funcion principal termina de procesar los datos, va y se fija que valores ha creado la rutina de interrupcion
Me da la idea de preguntarle solo siempre al final de la funcion si fue interrumpida mediante una int1-global por INT_EXT. Si es a si se sobreescribiran todos los valores guardados que trato esta, antes de operarlos en lo fundamental. Me da que esto siempre funcionaria, pero sigue la perdida de tiempo en ejecuciones que ya no sirven para nada, a parte del codigo adicional de guardar.
¿ Que significado tiene...
colgar el codigo en cuestion.
?
 
Signifique que copies aqui la parte de codigo relevante.

Estaria bueno que expliques un poco mas, por que la rutina principal procesa datos y la interrupcion tambien, asi como lo estas explicando se entiende muy poco, por no decir nada.
 
Última edición:
Lo que expresa quien hizo la consulta muestra un falla de diseño muy importante, que tal vez reqiiera semaforos u otras tecnicas de lockeo multitarea
 
Bien al final lo deje asi
Estoy emulando las ametralladoras pesadas de Aliens 2

Código:
microsensor pic<18f452.h>

#INT_EXT
void EXT_isr() {//función de interrupción
int1 S=0;  
CONVER(0);//pasa a slave
do{
if(spi_data_is_in()){//spi_data_is_in
output_high(PIN_C1); //RS TRUE
XX=spi_read(); S=1;
}///spi_data_is_in
}while(S!=1);  
output_low(PIN_C1);//RS FIN
CONVER(1);//pasa a master
//Quite todos los procesos que abia dentro ahora se realizan fuera
sx=1;///Tener en cuenta la tarea de por medio que implica INT_EXT en alea()
clear_interrupt(INT_EXT);
}//////*/

void alea(){
unsigned int16 ini,otra;///FFFF=65535

unsigned int8 cx;
int1 mdi=0;
sal=0; sx=0;
///////

resejuego();  lcd_putc("\f");//



otra=elcons*25;//constancia de apariciones aliens = elcons X 0.25 sg
//lcd_gotoxy(1,1); printf(lcd_putc,"otra=%lu ",otra); delay_ms(2500);///
lee=0; nu=0;
///otra=900;///
peti=5; //lcd_gotoxy(1,1); peti=1;

do{
//do{ }while(!MASTER);//Si lee No puede scrivir 
for(ini=2;otra>ini;ini+=25) {///CONSTANCIA
if (nu>0){ // nu>1;//si ya existen objetivos hazlos avanzar 
for(cx=0;nu>cx;cx++){
v8=psz[cx];
v16=dis[v8];
if(v16<velini){ //velini=velozcidad inicial
dis[v8]=1;//1 distancia minima ESTAN ENCIMA
}else{//se le hace avanzar
  v16-=vel[v8];// }//if(lesionar=true) { herido vaja su veloccidad[individual] } ELSE { toda vel[x]=velini siempre }
dis[v8]=v16;
}
}//for(cx)

//if(lee!=0) { if(modifica(lee)){ bur(); lee=0; } } //trampas de juego
//peti=5;///////
if(sx){ see(XX); }//sx=TRUE micro-sensor fue interrumpido para atender INT_EXT impazto ALIEN=XX
//re2(); bur(); pri(x,x) y sus subfunciones son las afectadas
if(nu>2){ bur(0); }//burbuja();//busca los mas cercanos si son + de 2
re2();// refresca posicion-distancia }
pri(0,nu);  //muestra LCD nu-objetivos,eliminacion,carga
}//!nu>0
else { lcd_gotoxy(1,1); lcd_putc("              Despejado"); }
mdi=0; //Elfor faborece la interrupcion 25x10 mejor que 250
for(cx=1;25>cx;cx++){ 
if(lee!=0) { if(!mdi){ mdi=1; modifica(lee); lee=0;  }//trampas de juego
if(sx){ see(XX); OP(0); } //sx=TRUE micro-sensor fue interrumpido para atender INT_EXT impazto ALIEN=XX
}//for(cx)
delay_ms(10);  } ///repite operaciones LCD RW cda 0.250 segundos
}///constancia de suceso elcons*250mlsg
if (nu<maxi){ carga(); }//NEW ALIEN no carges + de maxi aliens

}while(sal!=1);//fuera de juego
mensa(10); mensa(11);
peti=0;
}
void OP(int1 bj){
if(nu>2){ 
   if(bj){ bur(0); }//...secuencia tadas las posiciones(+ d 1 paso para ser todo correpto)
   else { bur(1); }//1...directo intercambia a psz[0] el prioritario+cercano
}
re2();//pasa posiciones[distancias] a Torret1 (vista la peli es Vigilante 1)
pri(0,nu);//muestra en LCD posicion[distancia] de cada objetivo
}

void see(unsigned int8 AX){//Se interrumpio sensor-RW para leer impazto en XX
//CONVER(1);
if(!lesi){ if(retro<1){ res[AX]=0; } else { res[AX]--; } }//if(lesion=false || retroceso=0) No se comunico al herirloNIretroceder SI pasa x aki resistencia[x]=0_eliminarlo
else {//lesion-objetivo=true se estan comunicando todos los inpactos que recive el objetivo[x]...
res[AX]--; if(vel[AX]>1){ 
vel[AX]=(vel[AX]*9)/10; } //lesi=herir x cada impacto recivido se le quita un 10% d velozcidad...
//lcd_gotoxy(30,2);  printf(lcd_putc," <%u>%u"v8,res[v8]);////comprovacion de velozcidad decrementada...
}

lcd_gotoxy(29-cf8(v8),2);  printf(lcd_putc,"<%u>%u"AX,res[AX]);////comprovacion de resistencia-decrementada...
if(res[AX]<1){ elimina(AX); } else { dis[AX]+=retro; }//dis[psz[v8]]+atras; }
sx=0;
}

void elimina(unsigned int8 ali){
lcd_gotoxy(1,1);         
if(psz[0]==ali){//se trata del objetivo principal
printf(lcd_putc,"\fDESTROY<%u> ",ali);//destroy_psz[0]
uno=1; if(nu>1){ pasa(1); } else { nu=0; }//posicion-distancia[1]...[0] [2]...[1] [3]...[2] asta que lu diga nu
//lx+=15; delay_ms(250); 
} else {//lo + raro no era el objetivo-prioritario
printf(lcd_putc,"\fSECUNDARIO<%u>FUERA ",ali);//destroy_psz[1]a[nu]
for(c2=1;nu>c2;c2++){ 
if(psz[c2]==ali){ pasa(c2+1); break; } }
uno=0;//lx+=20; 
}
ms=7;
///elimina implica
//if(nu>2){ bur(); }
//re2();
//pri(0,nu);
//delay_ms(50); 
}
void carga(){
int1 val=1;
unsigned int8 a8;
if(nu>0){
unsigned int8 cx,ce;
//unsigned int16 a16;

for(cx=0;10>cx;cx++){//...10 intentos
a8 = rand() % 201; //carga posicion 0-200
val=1;//si pasa a 0 error coincide con una posicion-existente
//////recorre posiciones de psz[0] a psz[nu] existentes
for(ce=0;nu>ce;ce++){ if(psz[ce]==a8){ val=0; break; } } //va8 No es una posicion valida OCUPADA vuelve a rand();
if(val){ break; } }//rompe bucle for(cx) busqueda de posicion-valida val=1
} else { a8 = rand() % 201; }//carga posicion 0-200
if(val){
psz[nu]=a8;
dis[a8]=760+velini; //carga distancia inicial 760 - ...1
vel[a8]=velini;
res[a8]=coraza;
nu++; //nu debe coincidir con nº aliens activos
      if(nu<8){ lcd_gotoxy(34-cf8(a8),2); printf(lcd_putc,"NEW<%u>n%u",a8,nu); }
      else{ lcd_gotoxy(37,2); printf(lcd_putc,"n%u ",nu); }
} else { lcd_gotoxy(33-cf8(a8),2); printf(lcd_putc,"ERRO<%u>n%u",a8,nu+1); }//...10 intentos 
} 

void bur(int1 buj){///burbuja()
//lcd_putc("\f");
//unsigned int8 c0,ca;
unsigned int8 d,a;
unsigned int8 p0,p1;//posiciones
unsigned int16 d0,d1;//distancias  
//i=nu-1;
if(!buj){
for(d=0;nu>=d;d++){//si nu=5---> 0 1 2 3 4 pasadas
a=d+1; 
p0=psz[d];
p1=psz[a];//POSICION
d0=dis[p0];
d1=dis[p1];//DISTANCIA
if(d0>d1){//si d0 esta a + distancia k d1 ...d1 tiene prioridad + cercano
psz[d]=p1;//
psz[a]=p0;
dis[p1]=d1;//prior
dis[p0]=d0;
}
}//for(d)
}
else {
for(d=2;nu>=d;d++){
p1=psz[d];//POSICION
//d0=dis[p0];
d1=dis[p1];//DISTANCIA
d0=dis[psz[0]];//se pregunta si la distancia[0] es la menor k distancia[d](d actual)
if(d1>d0){//si [0]=90 y [3]=25.....
p0=psz[0];//Si la distancia es mayor tambien sera necesario trasladar su posicion
//p1=psz[d];
//p0=psz[c0];
psz[0]=p1; dis[p1]=d1; 
psz[d]=p0; dis[p0]=d0;
}//.....................[0]=25 y [3]=90 
}//for(d)
}
}

void pri(int8 d,int8 a){
//ms<5 Atiende primero a un mensaje de odçbjetivo derrivado actual 
if(ms>5){ ms--; if(!uno){ lx=22; } else { lx=13; } } else { lx=1; }//si no fue el objetivo prioritario el mensaje es + largo lx+++++; 
c2=1;
 for(d=0;a>d;d++){
 v8=psz[d];
v16=dis[v8];
 lcd_gotoxy(lx,c2);          
//if(va16>15) {
       //      if(res[va8]>0){//sige vivo
    
      if(!lesi){ //lesionar
printf(lcd_putc,"%u[%lu] ",v8,v16); }  
      else { 
      c3=vel[v8]; 
      if(d<1 || c3<velini){
      printf(lcd_putc,"%u[%lu]%u ",v8,v16,c3); if(c3>9) { lx+=2; } else { lx++;}  }//observar velozcidad en caso de lesionar=true 
      else { printf(lcd_putc,"%u[%lu] ",v8,v16); } }
lx+=5;
if(v16>99){ lx+=2; } else { if(v16>9) { lx++; } }
         //    } else { printf(lcd_putc,"DESTROY[%u]",va8); lx=12;                 

if(v8>99){ lx+=2; } else { if(v8>9) { lx++; } }
if(lx>35) {  lcd_putc("                     "); //
if(c2>1) {  lcd_putc("                     "); break; }//El lcd no puede mostra + informacion

lx=1; c2=2; }

}//for(d)
lcd_putc("                  ");

  
       if(c2<2 || lx<8){ lcd_gotoxy(1,2); lcd_putc("POSICION [ DISTANCIA ]     "); } else {  lcd_putc("                     "); }
 }

void CONVER(int1 Soy){
if (Soy){
set_tris_c(0X11); //delay_ms(2);// 0001 0001 /// "C5_S C4_E C3_S  01 0"
setup_spi(spi_master | spi_l_to_h | spi_clk_div_16); delay_ms(2);//| SPI_XMIT_L_TO_H); //);// | SPI_XMIT_L_TO_H);  
output_high(PIN_c7); MASTER=1; //delay_ms(2);//LO PRIMERO QUE TIENE K TENER EN CUENTA EL OTRO ANTES DE ENVIARLE NADA
} 
else {

output_low(PIN_c7); MASTER=0;///0101 1001 "C5_S C4_E C3_E 01 1" 0x59 (slave torret1)
set_tris_c(0X19);  //delay_ms(2); // 0001 1001 ///"C5_S C4_E C3_E 01 1"
setup_spi(spi_slave | spi_l_to_h | spi_clk_div_16); delay_ms(2);//| SPI_XMIT_L_TO_H); //);// | SPI_XMIT_L_TO_H);  
} }

int1 PM() {/// protocolo de envio vajo SPI MAESTRO
//output_high(PIN_c6); // s.envio=true afecta PIN_B7_SLAVE/E.envio 
delay_ms(4);//4 
if(Input(PIN_C0)){ delay_ms(4); return 0; }//recivido

int8 t=0;
for(t=0;20>t;t++); { delay_ms(1);  //Impide + envios asta SLAVE lo diga con su S.pin_a0_(S.recivido) -----> E.pin_c0_MASTER(E.recivido)
if(Input(PIN_C0)){ delay_ms(2); return 1; }//recivido
}
MF++; lcd_gotoxy(33,2);   printf(lcd_putc,"MF %d ",MF); return 1;////  break; } t++; }while(!Input(PIN_C0));
//output_low(PIN_c6); // s.envio=false afecta PIN_B7_SLAVE/E.envio
//lay_ms(4);//4
}
Vigilante1 pic<18f452.h>
Código:
void Fuego(unsigned int8 dar){

 //va8=res[dar]; 
//lcd_gotoxy(x1,1);
 if(muni>0){ output_high(PIN_C7); delay_ms(1); //peticion de fuego ()
//hay un 3º micro <16f877.h> siempre slave solo avilita c0 con su a A0 si se sobrepaso el tiempo de carencia de //disparo o no esta ardiendo el cañon (fuego++; arder+20) este no me preocupa
if(Input(PIN_C0)){  impacto(dar); } //se concede fuego ()
} //else {//el controlador-disparo no puede conceder fuego
//else { output_low(PIN_C7); }//denegar fuego x falta de municion o carencia 
output_low(PIN_C7);
}

void impacto(unsigned int8 da){
///inici peti=50eliminado(XX);
 output_low(PIN_B2); output_low(PIN_B3);//Torret1 no debe girar sea izkierda/derecha
 muni--; res[da]--;
if(res[da]<1) { des=30; X0=da; eli=1; } else { eli=0; } saje=tp; //mens(da);
mens(da);
if(eli || rt || eri){//if(resistencia<1_eliminado atras=retroceso_impacto herir=true) //es necesario informarselo a microsensor
output_low(PIN_A0);//recivido=false
output_high(PIN_a1); //peticion MASTER...INTERRUPCION 
output_high(PIN_A2);//(RW TRUE) No escrive la primero INTERRUPCION solo pide la CONVERSION de ambos
CONVER(1); 
///asegurarse de que microsensor paso a slave
eli=0; saje=3; delay_ms(10);//Con spidata 150impactosCorreptos
spi_write(da); //PM();//output_high(PIN_A0); delay_ms(7); // s.recivido=true afecta pic1PIN_C0_SLAVE/E.recivido

output_low(PIN_A2);//RW FALSE
CONVER(0);


}
Esto ultimo a mejorado un poco las cosas pero aun a si tengo suerte que funcione durante mas de 1 minuto sin que falle algo
Torret-vigilante no deberia por que tener que ser slave nunca.
Al no utilizar un sensor de verdad (nisiquiera virtual) Torret normalmente slave pasa a master para decirle RW a sensor que a derribado un objetivo y ya no se debe tener en cuenta.
Por lo general es micro-sensor el master pasandole continuamente la aparicion y el desplazamiento de los Aliens que se cargan Es mas entretenido ver como todo va solo en vec de manipular tu continuamente estos componentes.
 
Atrás
Arriba