Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

01/07/2011 #1

Avatar de COSMICO

No retornar despues de una interrupcion.
Saludos.
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..
Gracias por la ayuda amigos.
01/07/2011 #2
Moderador

Avatar de Chico3001

No.... eso violaria el principio de programacion estructurada... ademas de poder generar otros problemas extras... como desbordamientos de memoria y errores en los calculos...
01/07/2011 #3

Avatar de COSMICO

Bueno, en asembler se puede hacer, y no pasa nada.
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.
Gracias...
01/07/2011 #5

Avatar de cosmefulanito04

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.
01/07/2011 #6

Avatar de Basalto

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?
02/07/2011 #7

Avatar de Moyano Jonathan

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.
02/07/2011 #8

Avatar de COSMICO

Saludos y gracias por contestar.

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.
gracias de nuevo por su colaboracion.
02/07/2011 #9

Avatar de Basalto

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
02/07/2011 #10

Avatar de Dr. Zoidberg

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...
02/07/2011 #11

Avatar de fdesergio

COSMICO dijo: Ver Mensaje
Bueno, en asembler se puede hacer, y no pasa nada.
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.
Gracias...
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
03/07/2011 #12

Avatar de COSMICO

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.
05/05/2012 #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
05/05/2012 #14

Avatar de albertoxx

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.
05/05/2012 #15

Avatar de chclau

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.
05/05/2012 #16

Avatar de Eduardo

fabian711 dijo: Ver Mensaje
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

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.
05/05/2012 #17

Avatar de albertoxx

chclau dijo: Ver Mensaje
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.
06/05/2012 #18

Avatar de Scooter

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.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.