• Domingo 22 de Diciembre de 2024, 02:15

Autor Tema:  Activar Interrupción Pic16f84  (Leído 4834 veces)

xernovil

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Activar Interrupción Pic16f84
« en: Jueves 8 de Marzo de 2007, 10:56 »
0
Hola, pues bién... estoy "formandome" sobre PIC's, ya que en mi proyecto fin de carrera debo "solapar" dos mandos a radio frecuencia y tengo que programar el resultante. Bien, pues el caso es que tengo un pequeño problema, no se bien bien como se activan las interrupciones, he hecho un programa sencillo en el cual al finalizar una serie de procesos (hacer correr una luz) entra en modo sleep. Mi intención es que al activar una de las interrupciones, se salga del modo sleep y vuelva a reiniciar el programa. Se que no es muy complicado, pero de momento no me sale.

Recursos utilizados:

PROGRAMADOR: Micro PIC trainer v1.1
PIC: 16F84A
software: PicAnt IDE, MPlab, IC-PROG

Se que el vector de interrupciones se situa en la 0x04h, y que para que se activen las interrupciones debe estar a 1 el GIE (a parte de su correspondiente bandera de interrupción), lo que no se es si debo poner yo a 1 el GIE al inicio del programa... en fin, que voy algo perdido en interrupciones.


Código:


Código: Text
  1.  
  2. #include <system.h>
  3.  
  4. asm
  5.  
  6. {
  7. list p=16F84A
  8. __config H'3FF1'
  9. }
  10.  
  11.  
  12. main()
  13. {
  14.  
  15. int j,k,i,m;
  16.  
  17. set_bit( STATUS, RP0 );            
  18. OPTION_REG= 01010000b;
  19. set_tris_b(0);
  20. clear_bit( STATUS, RP0 );
  21.  
  22. while(1)
  23. {
  24.  
  25. j=0;
  26. PORTB=1;
  27.  
  28. while(j<3)
  29. {
  30. for(k=0;k<8;k++)
  31.   {
  32.   for(i=0;i<255;i++)
  33.     {
  34.     for(m=0;m<255;m++);
  35.     }
  36.   PORTB = PORTB * 2;
  37.   }
  38. j++;
  39. PORTB=1;
  40. }
  41.  
  42. PORTB=0;
  43. asm
  44. {
  45. sleep
  46. }
  47. }
  48. }
  49.  
  50.  

Agradezco vuestra ayuda.

xernovil

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Re: Activar Interrupción Pic16f84
« Respuesta #1 en: Jueves 8 de Marzo de 2007, 19:04 »
0
He intentado avanzar, pero no lo consigo, ya que las ideas que voy teniendo solo hacen que incluir errores en la compilación, uno de mis cambios sería:


Código: Text
  1.  
  2. #include <system.h>
  3. asm
  4. {
  5. list p=16F84A
  6. __config H'3FF1'
  7. include        "p16F84A.inc"
  8.  
  9. ORG 0x00
  10.  
  11. goto INICIO
  12.  
  13. ORG 0x04
  14.  
  15. BCF INTCON,GIE    &#59;pongo el GIE a 0 para que no haya otra interrupción hasta
  16.                             &#59;que no acabe la secuencia
  17.  
  18. goto INICIO          &#59;vuelvo a inicio ya que lo que quiero es reinicializar el                                      
  19.                            &#59;desplazamiento de las luces
  20.  
  21. INICIO:               &#59;esto no debería dar problema no?? a partir de aquí se mete en el
  22.                            &#59;main() otra vez directamente, no?
  23. }
  24.  
  25.  
  26. main()
  27. {
  28.  
  29.  
  30. int j,k,i,m;
  31.  
  32. set_bit( STATUS, RP0 );            
  33. OPTION_REG= 01010000b;           //al estar el bit 6 a 1 (INTEDG), se activará la
  34.                                                   //interrupción por flanco de subida, no?
  35. set_tris_b(0);                              
  36. clear_bit( STATUS, RP0 );
  37.  
  38. .
  39. .              &#59;hago correr la luz
  40. .
  41.  
  42. asm
  43. {
  44.  
  45. BSF INTCON,GIE  &#59;activo el permiso para interrupciones
  46. BSF INTCON,INTE &#59;activo el permiso para interrupción externa INT/RB0
  47.  
  48. sleep
  49.  
  50.  
  51. }
  52.  
  53.  
  54.  


Al poner ese código me pone todo el rato estos errores:

Overwritting previous address contents (0000)
Overwritting previous address contents (0000)
Overwritting previous address contents (0004)
Overwritting previous address contents (0004)
Overwritting previous address contents (0005)
Overwritting previous address contents (0005)


No se como solucionarlos...

Toph

  • Moderador
  • ******
  • Mensajes: 420
  • Nacionalidad: sv
    • Ver Perfil
    • http://www.electronicayotros.blogspot.com/
Re: Activar Interrupción Pic16f84
« Respuesta #2 en: Jueves 8 de Marzo de 2007, 23:41 »
0
Cita de: "xernovil"

Al poner ese código me pone todo el rato estos errores:

Overwritting previous address contents (0000)
Overwritting previous address contents (0000)
Overwritting previous address contents (0004)
Overwritting previous address contents (0004)
Overwritting previous address contents (0005)
Overwritting previous address contents (0005)


No se como solucionarlos...
cambia esto:

Citar
ORG 0x00

goto INICIO

ORG 0x04

BCF INTCON,GIE    ;pongo el GIE a 0 para que no haya otra interrupción hasta
                           ;que no acabe la secuencia

goto INICIO          ;vuelvo a inicio ya que lo que quiero es reinicializar el                                     
                          ;desplazamiento de las luces

INICIO:               ;esto no debería dar problema no?? a partir de aquí se mete en el
                          ;main() otra vez directamente, no?
}


main()
{
por esto


Código: Text
  1.  
  2. ORG 0x00
  3.  
  4. goto INICIO
  5.  
  6. ORG 0x04
  7.  
  8. goto INTERRUPCION
  9.  
  10. ORG 0x05
  11.  
  12. INICIO:              
  13. }
  14. main()
  15. {
  16. .
  17. .
  18.  
  19.  

en esta rutina INTERRUPCION debes poner la rutina que  necesitas hacer cuando ocurra la interrupcion o sea lo siguiente:

Código: Text
  1.  
  2. INTERRUPCION:
  3. BCF INTCON,GIE    
  4. goto INICIO
  5. retfie; retorno de interrupcion vuelve a donde estaba el programa antes de la interrupcion
  6.  

el otro problema que veo es aqui:
Código: Text
  1.  
  2. BSF INTCON,GIE &#59;activo el permiso para interrupciones
  3. BSF INTCON,INTE&#59;activo el permiso para interrupción externa INT/RB0
  4.  
  5. sleep
  6. }
  7.  
  8.  
cuando iniciamos se viene para aca activa las interrupciones, hace lo de las luces y entra en modo sleep pero cuando se da la interrupcion se va a la posicion 0x04 de ahi se va a la rutina INTERRUPCION desabilita las interrupciones y luego se viene otra vez a INICIO y cae en sleep el problema es que NUNCA se retorna de la interrrupcion y nunca he visto un programa en que pase esto.  :ph34r:
ademas  es mejor activar los permisos para las diferente interrupciones y despues activar el permiso global o sea poner la sentencia  BSF INTCON,INTE primero y despues la del GIE.

checalo y nos cuentas saludos  :hola:
Por favor leer esto antes de postear. Gracias
NO alimenten al TROLL y morirá
¿Querés ayudar?, pues doná comida gratis con un simple clic aqui ,sin trucos
photobucket , Google , wine y cutepdf Rock!!!


programacion,c,c++,
Microcontroladores,java,linux,videojuegos,
,.NET,asm,codigo
por favor este 2012 que sea

Huguen_aus_Tirol

  • Miembro MUY activo
  • ***
  • Mensajes: 318
    • Ver Perfil
    • http://www.erhard-automation.co.cc
Re: Activar Interrupción Pic16f84
« Respuesta #3 en: Jueves 8 de Marzo de 2007, 23:43 »
0
Hola!
Me mareo un poco tu programa... programas en asembler o en C? :unsure:
Si lo haces en C, por lo general no deberías preocuparte de que las rutinas de interrupción se inicien en la dirección 0x4; el compilador lo hace automáticamente. Claro, debes indicar de que se trata de una interrupción...
Si lo haces en asembler, si debes indicar la dirección 0x4 (org 0x4). Al entrar a la interrupción (en asm) es importante guardar los registros STATUS y W, y restaurarlos al salir (Encontrarás un buen ejemplo en la hoja de datos del micro!).
Al inicio del programa, no importa que sea C o asm, debes habilitar individualmente las interrupciones y, por último, globalmente (activar GIE)
Para salir de una interrupción (asm) usas RETFIE, que es un RETURN más re-habilitar las interrupciones.
Mi consejo es que practiques un poco en asembler, prueba el clásico "hacer parpadear un led", con y sin interrupciones. Asembler te permitirá conocer un poco más al micro, y después encaras el C.
En lo posible, prueba sobre un PIC real, y no con el simulador; no porque sea más lindo  ver parpadear un led, sino por una cuestión de tiempo real ;)
Bueno, sigue probando que ya lo lograrás, y no olvides que aqui estamos para cualquier consulta...

Saludos

Huguen_aus_Tirol

  • Miembro MUY activo
  • ***
  • Mensajes: 318
    • Ver Perfil
    • http://www.erhard-automation.co.cc
Re: Activar Interrupción Pic16f84
« Respuesta #4 en: Viernes 9 de Marzo de 2007, 00:01 »
0
Hola Tania! Estabamos escribiendo al mismo tiempo!! :D
Un detalle: usas ORG 0x0 para el inicio del programa (vector de reset), luego usas un ORG 0x4 para las interrupciones, con un GOTO a algún lado... luego ORG 0x5.
La instrucción GOTO ocupa más de una posición de memoria, por lo tanto el error de sobreescritura al compilar (overwriting...)
Mi consejo:

ORG 0x0
GOTO main

ORG 0x4
ISR
;salvo STATUS y W (atención!! salvar registros sin modificar STATUS!! solución en microchip.com)
;veo que interrupción es y salto según cual sea con un CALL...
;retorno a la linea que sigue:
ISR_END
;repongo los valores de STATUS y W (sin modificar STATUS!! solución en...)
RETFIE

;y sin poner otro ORG...
main
;programa principal....

El compilador se las arreglará...
Espero haber sido claro..., y si no, siempre podemos hacer un reset y goto main... :P

Saludos :hola:

xernovil

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Re: Activar Interrupción Pic16f84
« Respuesta #5 en: Viernes 9 de Marzo de 2007, 00:13 »
0
Citar
Me mareo un poco tu programa... programas en asembler o en C?

Esque utilizo el PicANT IDE, y tengo que programar en C2C, pero en alguna ocasión tengo que intercalar ASM, como en el caso del sleep, ya que no conozco su equivalente en C.

La interrupción es para que salga del estado sleep y reactive el programa desde el inicio, es decir, es como hacer un reset, la verdad es que no importaría mantener los estados anteriores ya que vuelve a empezar de 0. La idea solo es practicar, ya que los leds serán los indicadores de teclas, y tendré que hacer otro algoritmo para detectar qué tecla se ha activado después (la tecla que esté "iluminada"). Ahora solo quería practicar el poner el pic en reposo y sacarlo de él volviendo a iniciar el programa.


Citar

ademas es mejor activar los permisos para las diferente interrupciones y despues activar el permiso global o sea poner la sentencia BSF INTCON,INTE primero y despues la del GIE.


No daría igual hacer una antes que otra sin importar el orden?
Al fin y al cabo sólo se activarán las interrupciones después de haber en el estado sleep, no?



Mi avance

Buscando por ahí he logrado lo siguiente:

Código: Text
  1.  
  2. #include <system.h>
  3.  
  4. asm
  5. {
  6. list p=16F84A
  7. __config H'3FF1'
  8. include        "p16F84A.inc"
  9. }
  10.  
  11. void interrupt(void)
  12. {
  13. disable_interrupt(GIE);
  14. clear_bit(INTCON,INTF);      //esto en realidad es lo mismo que disable_interrupt, no?
  15. asm reset;                         //no se si hago bien con este reset
  16. }
  17.  
  18. main()
  19. {
  20.  
  21. int j,k,i,m;
  22.  
  23. set_bit( STATUS, RP0 );            
  24. OPTION_REG= 01010000b;
  25. set_tris_b(0);
  26. clear_bit( STATUS, RP0 );
  27.  
  28. j=0;
  29. PORTB=1;
  30.  
  31. while(1)
  32. {
  33. while(j<3)
  34. {
  35. for(k=0;k<8;k++)
  36.   {
  37.   for(i=0;i<255;i++)
  38.     {
  39.     for(m=0;m<55;m++);
  40.     }
  41.   PORTB = PORTB * 2;
  42.   }
  43. j++;
  44. PORTB=1;
  45. }
  46.  
  47. enable_interrupt(INTE);
  48. enable_interrupt(GIE);
  49.  
  50. asm
  51. {
  52. sleep
  53. }
  54. }
  55.  
  56. }
  57.  
  58.  


De esta manera no me sale ningún error, lo que pasa es que hago el flanco para activar la interrupción y no se si realmente funciona, ya que no vuelve a iniciar el programa... y no he podido hacer modificaciones porque el pic se me ha estropeado ya que llevaba ya muchas grabaciones ... mañana iré a comprar más.


Decidme qué os parece y si tenéis alguna idea. Gracias

xernovil

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Re: Activar Interrupción Pic16f84
« Respuesta #6 en: Viernes 9 de Marzo de 2007, 00:21 »
0
Tu y yo también estábamos escribiendo al mismo tiempo Huguen_aus_Tirol jejeje


Citar
Mi consejo:

ORG 0x0
GOTO main

ORG 0x4
ISR
;salvo STATUS y W (atención!! salvar registros sin modificar STATUS!! solución en microchip.com)
;veo que interrupción es y salto según cual sea con un CALL...
;retorno a la linea que sigue:
ISR_END
;repongo los valores de STATUS y W (sin modificar STATUS!! solución en...)
RETFIE

;y sin poner otro ORG...
main
;programa principal....

Te has explicado bien, he probado lo que dices y de todas formas me da el mismo error de overwriting, no se qué hacer  :blink:

Toph

  • Moderador
  • ******
  • Mensajes: 420
  • Nacionalidad: sv
    • Ver Perfil
    • http://www.electronicayotros.blogspot.com/
Re: Activar Interrupción Pic16f84
« Respuesta #7 en: Viernes 9 de Marzo de 2007, 00:59 »
0
Cita de: "Huguen_aus_Tirol"
Hola Tania! Estabamos escribiendo al mismo tiempo!! :D
Un detalle: usas ORG 0x0 para el inicio del programa (vector de reset), luego usas un ORG 0x4 para las interrupciones, con un GOTO a algún lado... luego ORG 0x5.
La instrucción GOTO ocupa más de una posición de memoria, por lo tanto el error de sobreescritura al compilar (overwriting...)
:huh: pues no se porque decis esto, esta estructura la he tomado de un libro de microcontroladores y la he  ocupado siempre sin problemas ni errores, aqui dejo un link de uno de tantos programas en lo que he hallado la estructura de org 0, org 4 y org 5  http://pantuflo.escet.urjc.es/~rocapal/pro...a/dado/dado.asm

Citar
No daría igual hacer una antes que otra sin importar el orden?
Al fin y al cabo sólo se activarán las interrupciones después de haber en el estado sleep, no?

NO no es igual siempre, en este caso estas usando solo una interrupcion por lo cual no hay mayor problema pero es mejor acostumbrarse ya que cuando uses mas de una interrupcion si activas las interrupciones globales primero se te puede disparar alguna interrupcion en lo que estas activando otras. por eso tanto yo como  Huguen_aus_Tirol
Citar
Al inicio del programa, no importa que sea C o asm, debes habilitar individualmente las interrupciones y, por último, globalmente (activar GIE)
te recomendamos eso.

Citar
he probado lo que dices y de todas formas me da el mismo error de overwriting, no se qué hacer

ya tomaste encuenta lo que te dije  

Citar
el problema es que  NUNCA se retorna de la interrrupcion
Por favor leer esto antes de postear. Gracias
NO alimenten al TROLL y morirá
¿Querés ayudar?, pues doná comida gratis con un simple clic aqui ,sin trucos
photobucket , Google , wine y cutepdf Rock!!!


programacion,c,c++,
Microcontroladores,java,linux,videojuegos,
,.NET,asm,codigo
por favor este 2012 que sea

xernovil

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Re: Activar Interrupción Pic16f84
« Respuesta #8 en: Viernes 9 de Marzo de 2007, 10:33 »
0
Citar
NO no es igual siempre, en este caso estas usando solo una interrupcion por lo cual no hay mayor problema pero es mejor acostumbrarse ya que cuando uses mas de una interrupcion si activas las interrupciones globales primero se te puede disparar alguna interrupcion en lo que estas activando otras.

Vale, lo tendré en cuenta para mis próximas programaciones  :)


Citar
esta estructura la he tomado de un libro de microcontroladores y la he ocupado siempre sin problemas ni errores

Yo también he visto esta estructura en muchos sitios, el caso es que la he visto siempre que se ha programado únicamente en ASM, quizás me dé estos errores al utilizar este compilador (PicANT IDE) y mezclar los dos lenguajes de programación (C2C y ASM).

Citar
ya tomaste encuenta lo que te dije

Citar
el problema es que  NUNCA se retorna de la interrrupcion


Sí, lo tomo en cuenta, pero al hacer esto
Código: Text
  1.  
  2. void interrupt(void)
  3. {
  4. disable_interrupt(GIE);
  5. clear_bit(INTCON,INTF);      //esto en realidad es lo mismo que disable_interrupt, no?
  6. asm reset;                         //no se si hago bien con este reset
  7. }
  8.  
  9.  

no estoy reiniciando el programa  con el reset? o quizás falta la rutina de retorno de interrupción RETFIE?

Huguen_aus_Tirol

  • Miembro MUY activo
  • ***
  • Mensajes: 318
    • Ver Perfil
    • http://www.erhard-automation.co.cc
Re: Activar Interrupción Pic16f84
« Respuesta #9 en: Viernes 9 de Marzo de 2007, 11:08 »
0
Si quieres mediante una senal externa reiniciar tu programa desde 0, no te olvides que el micro tiene una pata de reset... este pin esta ahi para usarlo cuando se quiera ;)
Hay unas banderas que te indican que tipo de reset fue el mas reciente.
Creo que podrias buscar por ese lado la solucion a tu problema...

Tengo que rectificar algo... la instruccion GOTO ocupa una direccion de memoria, necesita dos ciclos para ejecutarse... perdon por la equivocacion :whistling:

Saludos

xernovil

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Re: Activar Interrupción Pic16f84
« Respuesta #10 en: Viernes 9 de Marzo de 2007, 11:34 »
0
Citar
Si quieres mediante una senal externa reiniciar tu programa desde 0, no te olvides que el micro tiene una pata de reset... este pin esta ahi para usarlo cuando se quiera

Es lo que he ido haciendo mientras no conseguía hacerlo mediante el programa, pero mi idea es aprender a utilizar las interrupciones y saber volver del estado sleep. La verdad es que estoy algo verde todavía en esto, pero espero aprender rápido con vuestros consejos  :rolleyes:

Este PIC no será el definitivo que se usará para implementar lo que tengo que hacer, pero he leído por ahí que para aprender es el ideal. He hecho ya varios programas pero lo de las interrupciones se me resiste.

Toph

  • Moderador
  • ******
  • Mensajes: 420
  • Nacionalidad: sv
    • Ver Perfil
    • http://www.electronicayotros.blogspot.com/
Re: Activar Interrupción Pic16f84
« Respuesta #11 en: Sábado 10 de Marzo de 2007, 00:31 »
0
xernovil lo que se me ocurre sin pensarlo mucho  para poder regresar de la interrupcion es hacer hacer algo asi:

Código: Text
  1.  
  2. ORG 0x00
  3.  
  4. goto INICIO
  5.  
  6. ORG 0x04
  7.  
  8. goto INTERRUPCION
  9.  
  10. ORG 0x05
  11.  
  12. INICIO:              
  13. call LUCES;en LUCES iria la rutina donde enciende las luces
  14. ETIQ:
  15. sleep&#59;despues se duerme hasta que se da la interrupcion
  16. nop &#59;estas instrucciones nop no hacen nada y solo se ponen porque al producirse
  17. nop &#59;una instruccion SLEEP. El microcontrolador Pre-cachea las proximas 2 instrucciones.
  18. goto ETIQ&#59; cuando se regresa de la interrupcion caemos aca esto nos hace saltar al modo sleep a esperar otra interrupcion
  19.  
  20. ;aqui en INTERRUPCION
  21. INTERRUPCION:
  22. BCF INTCON,GIE    
  23. call LUCES
  24. retfie; retorno de interrupcion vuelve a donde estaba el programa cuando ocurrio la interrupcion osea a la instruccion justo despues de sleep
  25.  

realmente el programa no se vuelve a reiniciar pero pareciese que si, no se si es lo que buscas.  :unsure:

Cita de: "Huguen_aus_Tirol"
Tengo que rectificar algo... la instruccion GOTO ocupa una direccion de memoria, necesita dos ciclos para ejecutarse... perdon por la equivocacion :whistling:

:no:, bueno ya quedo aclarado no hay problema :comp:
Por favor leer esto antes de postear. Gracias
NO alimenten al TROLL y morirá
¿Querés ayudar?, pues doná comida gratis con un simple clic aqui ,sin trucos
photobucket , Google , wine y cutepdf Rock!!!


programacion,c,c++,
Microcontroladores,java,linux,videojuegos,
,.NET,asm,codigo
por favor este 2012 que sea

xernovil

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Re: Activar Interrupción Pic16f84
« Respuesta #12 en: Lunes 12 de Marzo de 2007, 11:05 »
0
Citar
realmente el programa no se vuelve a reiniciar pero pareciese que si, no se si es lo que buscas.

Sí, es lo que busco, ahora mismo estoy intentando implementar el código que me has descrito en mi programa, ya que tengo que utilizar otro tipo de instrucciones al programar en C... por el momento no me da error, pero no consigo que salga del estado sleep. Seguiré investigando y haciendo pruebas.

xernovil

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Re: Activar Interrupción Pic16f84
« Respuesta #13 en: Martes 13 de Marzo de 2007, 17:49 »
0
Bueno... he desistido, ya que pienso que lo que no funciona es la interrupción externa de la placa, ya que si lo configuro para que haga la interrupción con el TMR0 si que funciona, me habéis ayudado mucho, gracias a todos y ya os expondré más dudas, jejeje  :rolleyes: