Autor Tema: interrupcion Vs retfie, como borrar la direccion almacenada en la pila  (Leído 7189 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado alogic.on

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 772
hola a todos , queria preguntarles una cosilla  :mrgreen:
Como hago para al salir de la interrupcion vuelva siempre al inicio del programa??
lo unico que se me ha ocurrido es en org  04 poner call RSI , al salir de la rutina activo las interrupciones y para volver uso return, y en org 05 un goto  PROGRAMA pero se acumulan niveles en la pila

Código: ASM
  1. org 04                 ;guarda en la pila la direccion para volver
  2. call     RSI           ;va a la rutina RSI que al ser una call guarda otro nivel en la pila
  3. goto   PROGRAMA ;si aqui pongo otro return o retfie ya no se acumula pero vuelve donde estaba antes de que saltara la interrupcion
  4. org 06                 ;06 en vez de 05
  5. goto   INICIO       ;inicia el programa

existe alguna orden como clrwdt para borrar la pila, o se puede acceder al registro para borrarlo y cargarle una direccion, eso seria mi solucion, pero no he encontrado nada  :?
intento que cada vez que termina la interrupcion espere 333ms antes de enviar un nuevo dato, este se encuentra en el programa principal, espera 333ms, envia dato, vuelve a empezar,... pero al volver de las interrupciones puede que cuando saltó estuviera cerca del envio dentro del bucle de retardo y se queda pillao el ordenador si envia datos muy seguidos, o alcontrario si no se envia en 333ms salta como Error, cable desconectado.

gracias y un saludo

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #1 en: 06 de Octubre de 2007, 09:36:36 »
En los 16F e inferiores no existe tal instrucción.  La forma más decorosa que se me ocurre es en el bucle principal del programa (con el stack vacío) hacer un 'return' con lo cual el PC se cargará con 0x0000

En los 18F sí existe una instrucción de RESET.

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado alogic.on

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 772
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #2 en: 06 de Octubre de 2007, 10:05:28 »
mmmm pues de momento no voy a cambiar de familia, quiero mascar bien esta, que todavia no manejo

 gracias por el dato no se me habria ocurrido que hacer un return con la pila a cero volveria a empezar  :shock:

un saludo y gracias

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #3 en: 06 de Octubre de 2007, 10:15:16 »
Eso sí, vuelve a empezar el programa pero no es un reinicio del pic.  No se borraran variables ni nada por el estilo.  Te lo aviso por las dudas.

Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #4 en: 06 de Octubre de 2007, 12:07:52 »
No hagas una llamada a la interrupción, si no un salto, así no se te acumularan las direcciones de retorno en la pila.

Un saludo
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #5 en: 06 de Octubre de 2007, 13:22:45 »
   
  como bien dice ifh900 en vez de CALL haces un GOTO a esa etiqueta y despues en vez de RETURN acabas la subrutina con otro GOTO a donde tu quieras ya que aqui no interviene pera nada el stack.

Desconectado alogic.on

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 772
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #6 en: 07 de Octubre de 2007, 06:50:10 »
hola y gracias, al saltar la interrupcion ya se guarda una direccion en el stack,no??  y para salir al bucle principal, tendre que usar return o retfie o se acumula el dato en el stack.
creo que la unica forma es buscar puntos estrategicos en el bucle principal para hacer un return con la pila vacía. poniendo en algun registro un señalizador , y que lo primero que haga el programa sea testear si esta a uno, cosa que le haga cambiar de direccion al programa, y empieze desde una direccion indicada. creo que a algo asi se referia Maunix al recordarme que haciendo un return con la pila vacia se mantiene el valor de los registros internosy vuelve al principio del programa
creo que puedo hacer una tabla poniendo varios señalizadores en un registro, segun lo cerca que haya saltado del final del bucle el return estara precedido de borra todos los señalizadores y enciende el suyo, por suerte puede variar el tiempo entre 200 y 333,3ms antes de enviar un dato asi segun el señalizador que este encendido la tabla te envia a una parte del bucle u otra, seria como hacer una rutina de retraso utilizando el testeo de un registro para que tarde mas o menos u tilizando el principio del programa como parte del retraso. espero haberme explicado medianamente bien, a ver si lo saco que lo estoy viendo mas dificil que usar cualquiera de los perifericos del pic  :D al tajo¡¡

un saludo y gracias

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #7 en: 07 de Octubre de 2007, 15:56:46 »

  como dices en este ultimo post funcionara no digo que no. Pero a mi forma de ver es complicarse la vida. Quien carga la pila con la direccion de retorno es la instruccion CALL, para facilitar el trabajo y que no tengas que recordar la direccion a donde retornara despues de cada subrutina si en vez de CALL usas GOTO hace igual la subrutina y en el stack no se escribe ninguna direccion. Vamos estoy convencido de que es asi,de todos modos espera la opinion de alguien que sepa mas.

     saludos

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #8 en: 07 de Octubre de 2007, 20:34:47 »
Hola a todos. Yo he estado siguiendo el tema en forma callada  :) porque no entendía bien.

Lo que dice tapi8 es verdad. Me parece que se que es lo que queres. Puedes empezar el programa de esta manera:

Código: [Seleccionar]

              ORG       4             ;vector de reset
              GOTO     PRIN        ;Ir al programa principal
              ORG       5             ;Vector de interrupción
              ...                         ;Aquí comienza la subrutina de la interrupción
              ...                         ;
              ...                         ;
              ...                         ;Fin de la subrutina de la interrupción
              GOTO    PRIN


Esto es justo lo que te recomienda tapi8 (o al menos fue lo que entendí)

Saludos.  :-/ :-/
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado alogic.on

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 772
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #9 en: 08 de Octubre de 2007, 05:40:58 »
hola y gracias,pero se me esta haciendo la cabeza un lio, conste que ahora cojo el libro  :shock: palabras de J.M.Angulo Microcontroladores Pic la solucion en un chip <yo me imagino una voz profunda con efecto hall> :D
-Una instrucción call provoca el mismo efecto que una interrupcion. Ambas detienen el programa, guardan la direccion del pc actual en la cima de la pila y cargan en el PC la direccion donde se inicia la rutina que atiende a CALL o a la interrupcion,<vector de interrupcion>. La ultima instruccion de la rutina <return,retfie> restaura el valor del PC con el salvado en la pila y asi retorna al programa principal.
esto es lo que tengo entendido, si no es asi decidmelo, no seria el primer error que encuentro, sin ir mas lejos mirad como continua el parrafo
-Como las rutinas pueden modificar el contenido de los registros del procesador, al iniciarlas conviene guardar en la pila el valor de los mismos .... mirad que dice de guardarlos en la pila y no en un registro como por ej. ALMACEN_TEMP_W, ALMACEN_TEMP_STATUS.... o como cada uno los llame, en su dia casi me vuelvo loco intentando guardar en la pila esos valores
entonces si utilizo GOTO INICIO para salir de la interrupcion, se quedaría almacenado en la pila la direccion que se guardo cuando se produjo la interrupción, precisamente es esto lo que estoy tratando de evitar.

un saludo y gracias

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #10 en: 08 de Octubre de 2007, 06:09:05 »

    Hola Alogic:
    Yo por lo poco que se en la pila el que programa no puede guardar nada, eso lo hace el propio PIC con la instruccion CALL y no se si con alguna mas. Esto es para facilitar la programacion, sobre todo cuando hay varias rutinas en un mismo programa y mas si estan anidadas unas dentro de otras, no te tienes que preocupar de saber la direccion a donde volvera al acabar la rutina. No apunta la direccion del CALL sino la siguiente a esta para al hacer el RETURN proseguir con el programa, pero si no quieres que vaya ahi sino a otro sitio si en vez de RETURN le dices GOTO INICIO te ira al inicio pero en la pila te quedara metida la direccion siguiente al CALL. Ahora bien si en vez de llamar a la rutina vas a ella mediante un GOTO RUTINA en la pila no escribira nada ( eso creo ).

   Epero no estar equivocado y te sirva de algo.


   Saludos

Desconectado alogic.on

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 772
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #11 en: 08 de Octubre de 2007, 07:35:50 »
hola tapi8
jejej me parece que ya se que pasa, puse un ejemplo en el que usaba una call para llamar a la rutina de interrupcion, y salia de ella con un goto, eso era un ejemplo para acumular un nivel en el stack, pense que se entendería mejor, pero ya veo que fue un error , se que se hace asi:
org 00
goto         INICIO
org 04
                goto interrupcion
org 05
INICIO
                goto INICIO   ;bucle inicio, el programa espera a que salte una interrupcion
-
-
interrupcion
-                              ;guarda valores en registros temporales
-                              ;test para conocer la causa de la interrupcion
-                              ;rutinas segun el tipo de interrupcion
-                               ;vuelve a cargar los registros temporales sobre los originales, status, w.... 
                 retfie       ;aqui no se puede usar un goto INICIO o se quedaría el dato en la pila que se cargó cuando saltó la interrupción, por eso preguntaba si existia
                                ;alguna forma de borrar la pila.

 en tu respuesta hay algo que me parece que no tienes en cuenta y es que al saltar la interrupcion ya se carga la direccion siguiente a la que está en el pc, en el momento de producirse la interrupcion. Por ej. si esta en la linea 22 y se produce una interrupción, en la pila se guarda automaticamente la direccion 23 no solo carga valores en la pila las call si no tambien la propia interrupcion. Así cuando vuelve al programa principal, lo hace en la siguiente instrucción a la que ocurrio cuando saltó la interrupción. cosa que yo queria evitar y hacer que volviese al principio del programa
espero no estar diciendo alguna tonteria si es así sentiros libres de comentarlo, que siempre se puede aprender algo nuevo  :mrgreen:

un saludo y gracias

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #12 en: 08 de Octubre de 2007, 08:46:01 »
Para que la técnica del goto 0x0000 funcione siempre, la pila del stack de los calls también tiene que estar vacía. 

Si por ejemplo hacemos un call (la pila está tiene 1 valor) y luego un goto 0x0000 creeremos que está todo bien , pero si eso se repite una y otra vez llegará el punto en que la pila tenga los 8 valores y por ende ya no se pueda hacer.

Por ello tanto para hacer un goto 0x0000 como para hacer un 'return' y en ambos 'simular como si fuera un reset' debemos tener el stack vacío.    La pequeña ventaja que tiene el return (y que no es una ventaja trivial) es que si el pic tiene más de una página con hacer solo el return alcanza, en cambio para usar el goto también habria que hacer un borrado del PCLATH para que apunte a la página 0.

En lo particular trato de evitar hacer estas cosas por considerar que de seguro el problema se soluciona organizando diferente el software pero bueno, si alguien lo solicita expongo lo que me parece.

En cuanto a guardar registros en el 'stack' que dice el libro de Angulo  y algun otro que lean por allí, quiero separar las cosas para no crear confusión.  También cuando yo leía hace un tiempo se me hacía lío porque si uno no está en el tema puede llegar a confundirse.

Podríamos definir 2 stacks

1) Stack de Hardware (usado para los calls)
2) Stack de Software (usado para los registros)

El stack de hardware es el que se carga/descarga automáticamente con los calls y returns. 
El stack de software, no es más que un 'vector' o 'array' o sector de memoria que reservamos para guardar registros y luego leerlos.  Esto es muy útil cuando llamamos subrutinas para 'pasarle parámetros' y para que 'devuelva el resultado'.  Entonces siempre todas las operaciones se realizan sobre la misma región de memoria lo cual nos garantiza cierto orden.  Esto es lo que hace un compilador de C por ejemplo.  Tal vez meterse con cómo funciona un stack de software y porqué es como es, sería meterse en demasiado detalle pero bueno, si alguien tiene alguna duda no tiene más que preguntar.

Saludos



- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #13 en: 08 de Octubre de 2007, 13:25:26 »
Nos puedes explicar un poco más que es lo que quieres hacer?. Tal y como tienes planteada la estructura del ejemplo funciona como quieres, ya que si tienes un bucle cerrado en el INICIO cuando salgas de la interrupción volverá a INICIO. Según los paradigmas de la programación se puede realizar cualquier estructura de sin necesidad de utilizar un GOTO por lo que seguramente puedas replantear tu problema de otra forma para sortear el problemas que tienes, como muy acertadamente te a aconsejado maunix.

Un saludo.
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: interrupcion Vs retfie, como borrar la direccion almacenada en la pila
« Respuesta #14 en: 08 de Octubre de 2007, 13:34:24 »
Hola alogic.on. Ahora te entiendo.

Lo primero que debemos saber es que tipo de interrupción usas, vamos a suponer que es por INT. Cuando ocurre una interrupción de este tipo se pone a 1 el bit INTF (hablamos de un 16f84, pero si es otro PIC, te puede servir igual mi idea que voy a exponer). Lo que debes hacer en colocar estratégicamente una lectura de este bit (INTF), entonces, si ocurrió lo limpiamos y vamos al principio del programa, si no ocurrió seguimos con el programa.

Ahora te explico bien. EL CP empieza a correr, en eso se topa con el chequeo del bit, y resulta que no hubo, entonces continua. Luego e inmediataente después, hay una iterrupción el cual ira a la dirección 05, atenderá a la instrucción y una vez finalizada, tendrá que volver con un retfie (o el que necesites) para borrar la pila, ahora el CP vuelve a dónde estaba antes, continuará con su trabajo hasta que tenga que chequear el bit, entonces detectará que si hubo una interrupción y volverá al principio del programa.

Bueno, esta es solo una solución y me parece muy poco práctico, pero es el que se me ocurrio. Espero que te sirva.

Saludos.  :-/ :-/
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.


 

anything