TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: Leon Pic en 13 de Junio de 2009, 14:28:28

Título: Duda con interrupción.
Publicado por: Leon Pic en 13 de Junio de 2009, 14:28:28
Estoy desarrollando un programa el cual trabaja sobre los tres bancos de memoria del 16f877.

En la interrupción coloco:

Código: ASM
  1. RESET           ORG                     H'00'
  2.                         GOTO            INICIO
  3.                         ORG                     H'04'                   ;VECTOR INTERRUPCIÓN
  4. INTERRUP
  5.                         MOVWF           SALVAR_W                        ;SALVA EL CONTENIDO DE W
  6.                         SWAPF           STATUS,W                        ;PASAMOS A W STATUS (ES CON SWAPF PARA NO AFECTAR EL BIT Z)
  7.                         MOVWF           SALVAR_STATUS           ;SALVA EL CONTENIDO DE STATUS
  8.                         SWAPF           FSR,W                           ;PASAMOS A W FSR
  9.                         MOVWF           SALVAR_FSR                      ;SALVA FSR
  10.                         SWAPF           PCLATH,W                        ;PASAMOS A W PCLATH (Pagina de programa)
  11.                         MOVWF           SALVAR_PCLATH           ;SALVA EL CONTENIDO DE PCLATH
  12.                         SWAPF           OPTION_REG,W            ;PASAMOS A W OPTION_REG (Bancos)
  13.                         MOVWF           SALVAR_OPTION_REG       ;SALVA EL CONTENIDO DE OPTION_REG
  14.                         .......
  15.                         .......
  16.                         .......
  17.                         SWAPF           SALVAR_OPTION_REG,W ;RESTAURA EL VALOR A OPTIO_REG
  18.                         MOVWF           OPTION_REG
  19.                         SWAPF           SALVAR_PCLATH,W         ;RESTAURA EL VALOR A PCLATH
  20.                         MOVWF           PCLATH
  21.                         SWAPF           SALVAR_FSR,W            ;RESTAURA EL VALOR A FSR
  22.                         MOVWF           FSR
  23.                         SWAPF           SALVAR_STATUS,W         ;RESTAURA EL VALOR A STATUS
  24.                         MOVWF           STATUS
  25.                         SWAPF           SALVAR_W,W                      ;RESTAURA EL VALOR A W
  26.                         RETFIE

Cada posición de memoria está alojado en el banco 0. La duda que tengo es, ¿que pasaría si justo ocurre un interrupción cuando estoy trabajando sobre el banco 3? ¿se salvarían bien los datos?
Título: Re: Duda con interrupción.
Publicado por: Leon Pic en 13 de Junio de 2009, 22:15:45
Me respondo a mi mismo.

Luego de haber reinstalado el MPLAB porque no había forma de simularlo correctamente, logré simular mi duda (por eso había echo la pregunta porque el MPLAB se comportaba raro). Si justo quedo en el banco 3, los valores a salvar temporalmente serán guardado en el banco que quedó justo el registro STATUS en el momento de la interrupción. A mi ejemplo anterior los datos salvados quedarán en el banco 3  :( (pensaba que mágicamente, y al tratarse la interrupción, se salvaba en el banco 0, pero no).

¿Algún concejo que me puedan dar para encarar este problema? ¿La única solución factible es que cada vez que trabaje fuera del banco 0 desactive las interrupciones?
Título: Re: Duda con interrupción.
Publicado por: alogic.on en 14 de Junio de 2009, 03:53:14
hola Leon, puedes utilizar las posiciones de memoria de la 0x70 a 0x7f que se pueden acceder desde cualquier banco

un saludo
Título: Re: Duda con interrupción.
Publicado por: BrunoF en 14 de Junio de 2009, 04:12:42
Me respondo a mi mismo.

Luego de haber reinstalado el MPLAB porque no había forma de simularlo correctamente, logré simular mi duda (por eso había echo la pregunta porque el MPLAB se comportaba raro). Si justo quedo en el banco 3, los valores a salvar temporalmente serán guardado en el banco que quedó justo el registro STATUS en el momento de la interrupción. A mi ejemplo anterior los datos salvados quedarán en el banco 3  :( (pensaba que mágicamente, y al tratarse la interrupción, se salvaba en el banco 0, pero no).

¿Algún concejo que me puedan dar para encarar este problema? ¿La única solución factible es que cada vez que trabaje fuera del banco 0 desactive las interrupciones?

Ahh..Interesante. Una solución sería la que te dió alogic.on.

Otra, sería que si no usas el FSR podrías guardar temporalmente allí a W y luego hacer un artilugio para pasar al banco cero.
Por ahora, te dejo con esta alternativa:

Sólo el registro "SALVAR_W" debe estar en el intervalo de memoria [0x70-0x7F]. El resto puede estar en cualquier posición de memoria(del banco 0).

Código: ASM
  1. RESET           ORG                     H'00'
  2.                         GOTO            INICIO
  3.                         ORG                     H'04'                   ;VECTOR INTERRUPCIÓN
  4. INTERRUP
  5.                         MOVWF           SALVAR_W                        ;SALVA EL CONTENIDO DE W
  6.                         SWAPF           STATUS,W                        ;PASAMOS A W STATUS (ES CON SWAPF PARA NO AFECTAR EL BIT Z)
  7.                         CLRF            STATUS                          ;ASEGURO BANCO 0
  8.                         MOVWF           SALVAR_STATUS           ;SALVA EL CONTENIDO DE STATUS
  9.                         SWAPF           FSR,W                           ;PASAMOS A W FSR
  10.                         MOVWF           SALVAR_FSR                      ;SALVA FSR
  11.                         SWAPF           PCLATH,W                        ;PASAMOS A W PCLATH (Pagina de programa)
  12.                         MOVWF           SALVAR_PCLATH           ;SALVA EL CONTENIDO DE PCLATH
  13.                         SWAPF           OPTION_REG,W            ;PASAMOS A W OPTION_REG (Bancos)
  14.                         MOVWF           SALVAR_OPTION_REG       ;SALVA EL CONTENIDO DE OPTION_REG
  15.                         .......
  16.                         .......
  17.                         .......
  18.                         SWAPF           SALVAR_OPTION_REG,W ;RESTAURA EL VALOR A OPTIO_REG
  19.                         MOVWF           OPTION_REG
  20.                         SWAPF           SALVAR_PCLATH,W         ;RESTAURA EL VALOR A PCLATH
  21.                         MOVWF           PCLATH
  22.                         SWAPF           SALVAR_FSR,W            ;RESTAURA EL VALOR A FSR
  23.                         MOVWF           FSR
  24.                         SWAPF           SALVAR_STATUS,W         ;RESTAURA EL VALOR A STATUS
  25.                         MOVWF           STATUS
  26.                         SWAPF           SALVAR_W,W                      ;RESTAURA EL VALOR A W
  27.                         RETFIE

Saludo.
Título: Re: Duda con interrupción.
Publicado por: alogic.on en 14 de Junio de 2009, 05:38:23
esa es mejor solucion, esas posiciones de memoria hay que guardarlas como oro en paño, que hay muy pocas.
 sueño con que saquen algun modelo de pic con toda la ram asi, ya de paso una pagina de 8kb  :D puestos a pedir

un saludo
Título: Re: Duda con interrupción.
Publicado por: Leon Pic en 14 de Junio de 2009, 10:25:05
Gracias a ambos por la respuesta.

Núnca había entendido en el datasheet eso que decía accesses 70h-7Fh no le encontraba lógica pero por lo que me dice alogic.on ahora lo entendí. Esas posiciones de memoria no las utilizo, asi que lo voy a aprovechar.

Bruno, lamentablemente, utilizo el FSR por lo que no puedo usarlo como memoria temporal, aunque la idea es excelente, no se me había ocurrido utilizarlo así.

Alogic.on si no me equivoco, la familia 24 viene con un solo banco de memoria
Título: Re: Duda con interrupción.
Publicado por: BrunoF en 14 de Junio de 2009, 14:50:23
A partir de la familia 18F se cambió la arquitectura, y estas cosas han mejorado mucho...

Un saludo.
Título: Re: Duda con interrupción.
Publicado por: zerc79 en 16 de Junio de 2009, 09:22:29
Aprovecho el hilo de Leon PIc y me disculpo en entrometerme... pero tengo otra duda acerca de las interrupciones??   :lol: :shock:

que tanto codigo yo puedo ingresar en una interrupcion y que tanto me puedo demorar en ella...
y es posible que el retorno de una interrupcion me lleve a otra parte del codigo que tengo escrito en forma inmediata...

lo que pasa es que tengo un codigo con un lcd y en el momento de la interrupcion deseo pasar a otro ciclo del programa pero no he podido en forma directa, lo que ago es establecer un bit de una variable al entrar a la interrupcion lo cambio y asi en el desarrollo del primer ciclo encuentra este condicionamiento y lo envia al segundo ciclo pero tarda entre 20 a 30 seg... una eternidad para la respuesta de una programa...   :?  :?

Gracias, por las ayudas :-/
Título: Re: Duda con interrupción.
Publicado por: alogic.on en 16 de Junio de 2009, 09:50:27
para zerc79
no puedes volver de la interrupcion en otra posicion de programa, se te van a acumular niveles de la pila si no utilizas un return/retfie al terminar la int. lo que puedes hacer es que haga el codigo dentro de la interrupcion. me parece que pic18 puede alterar los valores de la pila pero.... de eso no tengo ni dea

Citar
Alogic.on si no me equivoco, la familia 24 viene con un solo banco de memoria
esto me lo apunto  :mrgreen:
Citar
A partir de la familia 18F se cambió la arquitectura, y estas cosas han mejorado mucho...
a partir de la 18f tambien¡¡¡''  :shock: si es asi que hago yo con un 16f me parecio leer en un post que habian sacado una familia mejorada de 16f que tenia varias caracteristicas de la 18f  :? sabeis a que me refiero??

un saludo
Título: Re: Duda con interrupción.
Publicado por: zerc79 en 16 de Junio de 2009, 11:42:14
para zerc79
no puedes volver de la interrupcion en otra posicion de programa, se te van a acumular niveles de la pila si no utilizas un return/retfie al terminar la int. lo que puedes hacer es que haga el codigo dentro de la interrupcion. me parece que pic18 puede alterar los valores de la pila pero.... de eso no tengo ni dea


Gracias alogic. com, lo puedo hacer sin importar lo prolongado del codigo???...
existe alguna forma de interrumpir una interrupcion??
 :P
Título: Re: Duda con interrupción.
Publicado por: Leon Pic en 16 de Junio de 2009, 11:46:02
Si quieres que en alguna parte del código (fuera de la interrupción) no ocurra ninguna, lo que tienes que hacer es desactivar el bit GIE del registro INTCON y por mas que ocurra una interrupción, no hirá al vector 0004h y por ende, no habrá interrupción. Luego de terminar la parte que no quieres en que alla una iterrupción, vuelve a habilitar el bit GIE
Título: Re: Duda con interrupción.
Publicado por: zerc79 en 16 de Junio de 2009, 17:41:34
Si quieres que en alguna parte del código (fuera de la interrupción) no ocurra ninguna, lo que tienes que hacer es desactivar el bit GIE del registro INTCON y por mas que ocurra una interrupción, no hirá al vector 0004h y por ende, no habrá interrupción. Luego de terminar la parte que no quieres en que alla una iterrupción, vuelve a habilitar el bit GIE
Si es el bit 7 de INTCON, gracias pero lo que quiero es poder reaccionar de inmediato ante una interrupcion es decir trasladarme directamente a otra parte del codigo, pero como me dice alogic y lo que estuve leyendo el PLC no se puede escribir desde el codigo, se puede modificar el PCLAH para redireccionar los bancos pero igual no me sirve porque no se a donde llegue tons nop...

Este bloqueo de interrupcion lo utilizo cuando presento datos al LCD  o guardo datos en eeprom interna y/o externa
Título: Re: Duda con interrupción.
Publicado por: Leon Pic en 16 de Junio de 2009, 18:44:45
¿Lo que quieres hacer si dentro de una interrupción tener otra interrupción de mayor prioridad?
Título: Re: Duda con interrupción.
Publicado por: zerc79 en 16 de Junio de 2009, 19:15:27
¿Lo que quieres hacer si dentro de una interrupción tener otra interrupción de mayor prioridad?

eso... eso... eso... :-/
si se puede??? :shock:
Título: Re: Duda con interrupción.
Publicado por: Leon Pic en 17 de Junio de 2009, 01:01:53
Si. Yo aún no lo probé ni mucho menos me puse a analizar el programa. Lo vi, lo marqué como favorito y te lo paso. Dale una hojeada y analizalo

http://www.todopic.com.ar/foros/index.php?topic=6063.0
Título: Re: Duda con interrupción.
Publicado por: zerc79 en 17 de Junio de 2009, 10:52:42
OK Gracias Leon Pic

Voy a leer y te cuento como me va...

 :-/
Título: Re: Duda con interrupción.
Publicado por: zerc79 en 17 de Junio de 2009, 11:08:16
PUes no era exactamente lo que necesitaba pero como el conocimiento nunca se pierde es bueno saber mas....

Alli explican que se pueden originar varias interrupciones internas y externas, oviamente cada una genera un flag en los registros de INTCON Y PIR y pues dependiendo de esos flags se puede establecer la rutina deseada, oviamente en el orden que tu revises los flags estaras dando prioridad a algunas interrupciones....

Pero como interrupcion externa los de gama media solo tienen una (caso que es el mio con un 16f873a) y en el momento de entrar a la interrupcion son deshabilitadas para direccionar al vector 0X04 desactivando el GIE pero los flags de las interrupciones internas siguen funcionando y se marcaran para poderlos revisar en la rutina de interrupciones....

Gracias de todos modos por el dato.
Título: Re: Duda con interrupción.
Publicado por: Suky en 17 de Junio de 2009, 11:17:11
Como ya te han dicho desde una interrupción no se puede direccionar a una parte del código especifica, así que quedan 2 soluciones a tu problema. Una sería ejecutar el código dentro de la interrupción, y que tan largo puede ser el código dentro de ella? Pues la única limitación que veo es que si tenes una interrupción cada 1ms, tu rutina no puede ser mayor a eso, sino estarás perdiendo eventos. La segunda es tratar de reducir el tiempo del bucle. Porque se demora tanto en realizar el bucle?
Título: Re: Duda con interrupción.
Publicado por: zerc79 en 17 de Junio de 2009, 11:35:10
Estoy tomando registro de temp y lo llevo cada 20 seg guardandolo en un eeprom externa, tomarlo en ciclos mas cortos me llenaria de datos y no es la idea, entonces realizo un bucle y al final coloco un delay de 20 seg y al volver a reanudar el bucle verifico los bits de mi variable para ver si entro a alguna interrupcion durante este tiempo, si asi sucedio entro a otra rutina para poder visualizar los datos de la eeprom por el lcd y ver un comportamiento promedio , luego salta nuevamente al bucle de toma de temperaturas.....
Pensé que era posible realizarlo en forma mas rapida pero creo que no lo es....

Lei en algun otro post la posibilidad en el caso de escritura a eeprom externa por I2C de asignar a otros pines las funciones de SDA Y SCK, saben si se pueden duplicar los puertos de interrupcion...

(creo que no si no alguien ya hubiera contestado.. pero por si acas   :lol:   :D)
Título: Re: Duda con interrupción.
Publicado por: Suky en 17 de Junio de 2009, 12:12:59
Una solución sencilla es colocar una demora de menor valor, por ejemplo 100ms y utilizar una variable para contar la cantidad de veces, entonces cuando este llegue a 200 (20seg) guardas en la memoria, pero tui bucle se repite cada 100ms.

Lo de cambiar los pines de I2C, si estas usando el hardware del PIC no puedes cambiar nada, pero si lo estas haciendo por software puedes elegir lo que quieras.
Título: Re: Duda con interrupción.
Publicado por: zerc79 en 17 de Junio de 2009, 12:28:34
Una solución sencilla es colocar una demora de menor valor, por ejemplo 100ms y utilizar una variable para contar la cantidad de veces, entonces cuando este llegue a 200 (20seg) guardas en la memoria, pero tui bucle se repite cada 100ms.

Lo de cambiar los pines de I2C, si estas usando el hardware del PIC no puedes cambiar nada, pero si lo estas haciendo por software puedes elegir lo que quieras.

Sencilla y practica para lo que necesito....
sip definitivamente sera la solucion mientras encuentro algo mas.....   :P
Gracias suky por tu tiempo y conocimientos... :-/