No retornar despues de una interrupcion.

#1
Saludos.:apreton:
Quiero saber, si hay alguna forma en ccs; despues de atender una interrupcion externa
que el programa no retorne al lugar en que estaba cuando se produjo la interrupcion.
Mas bien, que se dirija a donde yo quiera enviarlo. como a mitad de programa o al inicio
de la rutina.
en asembler, es facil; pero en ccs no se como hacerlo..:unsure:
Gracias por la ayuda amigos.
 
#2
No.... eso violaria el principio de programacion estructurada... ademas de poder generar otros problemas extras... como desbordamientos de memoria y errores en los calculos...
 
#3
Bueno, en asembler se puede hacer, y no pasa nada.:rolleyes:
Entoces seria otra; enviar el programa a la direccion 0x00, despues de que se produsca la interrupcion
Esto si sera posible; como ves no soy un mago en ccs, por eso pregunto estas cositas.
desafoortunadamente debe ser en ccs, donde haga esto.:unsure:
Gracias...:apreton:
 
#5
Usa maquina de estados, algo asi:

Código:
...
unsigned char estado=0;
....

void rutina_interrupcion()
{
...
estado=1;
return;
}


int main()
{
....
while(1)
  {
  switch(estado)
    {
     case 0: {.... rutina del estado 0 .... break;}
     case 1: {.... rutina del estado 1, la que necesitas ejecutar despues de la interrupcion .... break;}
     case n-1:{.... rutina del estado n-1 .... break;}
     case n:{.... rutina del estado n, aca pondria una rutina de bajo consumo ....}
    }
  }
}
Jugando con la variable "estado" podes cambiar que rutina ejecutar y cual no.
 
#6
en CSS no te permite poner algo asi como:
_asm
_endasm
Para poder cambiar el valor del contador de programa, justo al acabar la interrupcion?
 
#7
Las interrupciones en ASM son manejables pero en CCS, quizás se compliquen. Lo que se recomienda por lo general...digo general por que quizás haya cientos de formas de abordar el tema es usar la interrupción solo para asignar valores y activar flags o banderas. Todos los datos que se guarden o procesen en la interrupción tendrían que usar variables del tipo volatile, para obligar al micro a actualizar el valor en tiempo de ejecución y poder usar la información en otras partes del programa.

Para toma de decisiones lineales lo más seguro es usar máquinas de estado como las que muestra cosmefulanito04.

Yo personalmente reseteo antes del main, todas las variables de la RAM usando el comando #zero_RAM de CCS. Esto es para asegurarme que los valores de todas las variables van a ser 0x00....a no ser que sean constantes con valores fijos por programación.

Espero te ayude la explicación.
 
#8
Saludos y gracias por contestar.:apreton:

supongamos esto.

#int_rb
void RB_isr(void){ //función de interrupción
delay_ms(50);
if(input(PIN_B7)){
...Aqui quiero saltar al inicio RUTINA 1 este donde este el programa , y que siga por ahy como si fuese la primera ves que se ejecuta.

}


void main() {
do{

//RUTINA 1
if(flagstar==1){
for(contador=0;contador<=retardo;contador++){
delay_us(1000);//250us
output_high(PIN_led);
delay_ms(100);

output_low(PIN_led);
}

//RUTINA 2
for(contador=0;contador<=20;contador++){
delay_ms(2500);//800us
output_high(PIN_led);
delay_ms(2000);
output_low(PIN_led);

}
}while(1);
}

Este es mi dilema ahy esta la otra pata que le nace al gato.:unsure:
gracias de nuevo por su colaboracion.
 
#9
Utiliza una variable que pongas a uno en la interrupción. Y pon el While, que abarque todo el main. Cuando esa variable es 1 ejecutas la rutina 1 y 2. Al principio pones esa variable a 1 fuera del main, para que la primera vez se ejecute. Aunque sería bastante chapuza. Porque no copias y pegas el codigo en la interrupción. Un saludo
 
Última edición:

Dr. Zoidberg

Well-known-Papá Pitufo
#10
COSMICO:
No le busqués vueltas raras al asunto. El aproblema es claro: Tenés un error conceptual de diseño. PUNTO.
En C no se programa como en assembler (y programar lo que querés en assembler también sería erróneo), así que primero te recomiendo que leas y estudies la programación de alto nivel y estructurada.
Ya te han dado recomendaciones de como señalar el bloque de código a ejecutar cuando retornés de la ISR, y esa es la forma correcta en C y en assembler. Cualquier otra cosa es una "chapuza" como dicen los españoles...
 
#11
Bueno, en asembler se puede hacer, y no pasa nada.:rolleyes:
Entoces seria otra; enviar el programa a la direccion 0x00, despues de que se produsca la interrupcion
Esto si sera posible; como ves no soy un mago en ccs, por eso pregunto estas cositas.
desafoortunadamente debe ser en ccs, donde haga esto.:unsure:
Gracias...:apreton:
Poderse se puede que este bien hacerlo NO, cuando ingresas a la INT el valor del PC se guarda en el STACK, si no sales de la INT no se recupera el valor del PC y se desvia a otro lado, como la INT es asincrona (no esta ubicada en una parte especifica del programa) puede suceder en cualquier lado del programa y puede dar lugar a errores en operaciones que se realizen en ese momento, no tiene sentido a mi modo de ver atender una interrupcion para dejar "tirado" el resto del programa normal de ejecucion, sin contar que ocupas una posicion de la pila o stack para dejarla solo ahi, chauuuuuu

PD: aclaro, tirado=abandonado=olvidado
 
#12
Bueno todo eso lo sé perfectamente; me toco criarme en el asembler donde se obliga a pensar a nivel de pic pero ccs es otro cuento, aunque ahorra líneas de programacion a coste de memoria.
Entonces. Tal como me sugirio uno de ustedes por ahy metere todo en una interrupcion.
pero en ves de usar "delays"; usare el TMR1 para los retardos; el "for2 seguira haciendo lo mismo
y como estoy en interrupcion por TMR1, podre pararlo y recargar su valor fuera de la interrupción
lo mismo los registros para conteo en el for; y listo el pollo.
creo que eso es muy estructurado, tal cual se me sugirio por ahy.
Gracias por sus opiniones y ayuda; sabiendo que no se puede hacer, se pude determinar que si se pude.:aplauso:
:apreton:
 
#13
disculpen muchahos, yo tengo el mismo problema.... pero lo quiero hacer en asm, retornar despues de un interrupcion.. a un punto que yo elija.. y no a donde estaba antes de la interrupcion, por ahi lei que en asm si es posible, agradeceria si alguien me orienta sobre como hacerlo.. gracias
 
#14
en asm se puede hacer de todo, total lo que hace el compilador es pasar de C a asm y ahorrar tanta tecleadera de codigo en asm, para saltar en asm a la linea que tu quieras usa goto <direccion>o<etiqueta> o call si es un procedimiento.
 
#15
Para REGRESAR de una interrupción adonde uno quiera no se puede usar un goto o call, hay que tocar la dirección de retorno de interrupción que está almacenada en el Stack, pero un procedimiento así es altamente NO recomendable, es programación chapucera y muy difícil de mantener y de encontrarle fallas.
 
#16
disculpen muchahos, yo tengo el mismo problema.... pero lo quiero hacer en asm, retornar despues de un interrupcion.. a un punto que yo elija.. y no a donde estaba antes de la interrupcion, por ahi lei que en asm si es posible, agradeceria si alguien me orienta sobre como hacerlo.. gracias
Aclaremos un par de cosas:
1- Lo que querés hacer es una chanchada, que la maldición de Dijkstra te persiga por generaciones (n)

2- Si estabas en un bucle esperando la interrupción, lo correcto es que ese bucle decida donde saltar (mediante la lectura de un registro), no desde la interrupción.



Ahora bien... ¿vos querés saltar desde la interrupción? --> pues previa limpieza de los bits de interrrupción saltás a donde te plazca, y como vas a hacer bosta el STACK, si querés usá un CALL.
Total... ya no podés volver.

Los PICs tienen un STACK circular de 8 niveles, si hay Stack Overflow no pasa nada, salvo en algunos 18F donde se puede programar un reset en caso de stack overflow o underflow.


En cuanto a la simulación. El MPLAB interrumpe la ejecución para avisarte que sos un indio, pero puede desactivarse.
 
#17
Para REGRESAR de una interrupción adonde uno quiera no se puede usar un goto o call, hay que tocar la dirección de retorno de interrupción que está almacenada en el Stack, pero un procedimiento así es altamente NO recomendable, es programación chapucera y muy difícil de mantener y de encontrarle fallas.
El pregunto si se podia y de echo si se puede, que sea un metodo de programacion no recomendable y que despues le de stack overflow como dice eduardo no es la muerte ni se va a quemar el pic, como dicen aqui en mi pais ya son otros 5 centavos.
 
#18
Yo también opino que no es recomendable pero bueno, lo que habría que hacer es sacar de la pila la dirección de retorno (y lo que guarde el ccs si es que guarda algo mas) y saltar a donde se quiera.
Me suena que ese sistema lo he empleado alguna vez, aunque ya digo que es una programación "rebuscada".

Edito, ahora que recuerdo me parece que hice lo contrario; para no escribir dos veces la misma rutina una con retorno de interrupción y otra normal, guardaba en la pila la dirección de retorno y llamaba a la rutina que luego "volvía" a donde le había indicado. Eso se hacía tras un reset y luego en cada interrupción.
 
Última edición:
Arriba