Autor Tema: PIC 16f887-CCS-Como salir de INT_EXT hacia mi programa principal reiniciándolo?  (Leído 2199 veces)

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

Desconectado Miguel_AngelHC

  • PIC10
  • *
  • Mensajes: 1
Hola gracias por leer esto, tengo un problema, estoy iniciando con el mundo del PIC, y estoy desarrollando un semáforo de 2 vías con 2 pases peatonales, el problema me plantea que tengo que incluir un switch para mantenimiento y funcionamiento normal, en mantenimiento los LED tiene que oscilar, el problema que tengo es que implemente una interrupción externa para que en cualquier parte del programa, entre en mantenimiento, pero no encuentro la forma de que cuando salga del mantenimiento vuelva al programa principal reiniciándolo, intente incluir un reset pero no funciona, y su coloco un return vuelve a la parte donde se quedo el programa antes de entrar en mantenimiento , adjunto el también el archivo en proteus 8.11

Código: C
  1. #include <16F887.h> //Librería para usar el PIC16F887.
  2. #fuses  XT, NOWRT, NOPUT, NOWDT, NOLVP, NOCPD //Configuración de fusibles.
  3. #use delay (clock=4000000) //FOSC = 4 MHz.
  4. #byte port_b = 0xF06 //Identificador del Puerto B.
  5. #byte port_d = 0xF08 //Identificador del Puerto D.
  6. #byte port_c = 0xF07 // port C
  7. #use standard_io(b) //Usa la librería estándar B.
  8. #use standard_io(d) //Usa la librería estándar D.
  9. #use standard_io(c) //Usa la librería estándar c.
  10.  
  11. int1 X;
  12. #int_ext
  13. Void interrupcion() {
  14. while(true){
  15. X=input(pin_b0);
  16. if (X==1){
  17.  output_c(0xFF);
  18.  output_d(0xFF);
  19.  delay_ms(1000);
  20.  output_c(0x00);
  21.  output_d(0x00);
  22.  delay_ms(1000);
  23. }
  24. else {     //  parte que falla del programa
  25. return ;  //  parte que falla del programa [attachment id=1 msg=420527]  [attachment id=1 msg=420527]
  26. }
  27. }
  28. }
  29.  
  30. Void main(){ //Función main.
  31. enable_interrupts(GLOBAL);
  32. enable_interrupts(INT_EXT); //Habilita interrupción externa
  33.  
  34.   while(TRUE){
  35.    
  36.     output_high(PIN_C0);
  37.     output_high(PIN_C4);
  38.     output_high(PIN_D2);
  39.     output_high(PIN_D4);
  40.     delay_ms(2000);
  41.     output_low(PIN_D4);
  42.     output_high(PIN_D3);
  43.     delay_ms(23000);
  44.     output_low(PIN_C0);
  45.     output_high(PIN_C1);
  46.     delay_ms(3000);
  47.     output_high(PIN_D4);
  48.     output_low(PIN_D3);
  49.     delay_ms(2000);
  50.     output_low(PIN_D2);
  51.     output_low(PIN_C1);
  52.     output_high(PIN_D0);
  53.     output_high(PIN_C2);
  54.     delay_ms(2000);
  55.     output_low(PIN_C4);
  56.     output_high(PIN_C3);
  57.     delay_ms(23000);
  58.     output_low(PIN_D0);
  59.     output_high(PIN_D1);
  60.     delay_ms(3000);
  61.     output_low(PIN_C3);
  62.     output_high(PIN_C4);
  63.     delay_ms(2000);
  64.     output_low(PIN_C2);
  65.     output_low(PIN_D1);
  66.     output_high(PIN_C0);
  67.     output_high(PIN_D2);
  68.     }
  69.    }

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:PIC 16f887-CCS-Como salir de INT_EXT hacia mi programa principal reiniciándolo?
« Respuesta #1 en: 11 de Diciembre de 2021, 12:58:02 »
Hola gracias por leer esto, tengo un problema, estoy iniciando con el mundo del PIC, y estoy desarrollando un semáforo de 2 vías con 2 pases peatonales, el problema me plantea que tengo que incluir un switch para mantenimiento y funcionamiento normal, en mantenimiento los LED tiene que oscilar, el problema que tengo es que implemente una interrupción externa para que en cualquier parte del programa, entre en mantenimiento, pero no encuentro la forma de que cuando salga del mantenimiento vuelva al programa principal reiniciándolo, intente incluir un reset pero no funciona, y su coloco un return vuelve a la parte donde se quedo el programa antes de entrar en mantenimiento , adjunto el también el archivo en proteus 8.11

Código: C
  1. #include <16F887.h> //Librería para usar el PIC16F887.
  2. #fuses  XT, NOWRT, NOPUT, NOWDT, NOLVP, NOCPD //Configuración de fusibles.
  3. #use delay (clock=4000000) //FOSC = 4 MHz.
  4. #byte port_b = 0xF06 //Identificador del Puerto B.
  5. #byte port_d = 0xF08 //Identificador del Puerto D.
  6. #byte port_c = 0xF07 // port C
  7. #use standard_io(b) //Usa la librería estándar B.
  8. #use standard_io(d) //Usa la librería estándar D.
  9. #use standard_io(c) //Usa la librería estándar c.
  10.  
  11. int1 X;
  12. #int_ext
  13. Void interrupcion() {
  14. while(true){
  15. X=input(pin_b0);
  16. if (X==1){
  17.  output_c(0xFF);
  18.  output_d(0xFF);
  19.  delay_ms(1000);
  20.  output_c(0x00);
  21.  output_d(0x00);
  22.  delay_ms(1000);
  23. }
  24. else {     //  parte que falla del programa
  25. return ;  //  parte que falla del programa [attachment id=1 msg=420527]  [attachment id=1 msg=420527]
  26. }
  27. }
  28. }
  29.  
  30. Void main(){ //Función main.
  31. enable_interrupts(GLOBAL);
  32. enable_interrupts(INT_EXT); //Habilita interrupción externa
  33.  
  34.   while(TRUE){
  35.    
  36.     output_high(PIN_C0);
  37.     output_high(PIN_C4);
  38.     output_high(PIN_D2);
  39.     output_high(PIN_D4);
  40.     delay_ms(2000);
  41.     output_low(PIN_D4);
  42.     output_high(PIN_D3);
  43.     delay_ms(23000);
  44.     output_low(PIN_C0);
  45.     output_high(PIN_C1);
  46.     delay_ms(3000);
  47.     output_high(PIN_D4);
  48.     output_low(PIN_D3);
  49.     delay_ms(2000);
  50.     output_low(PIN_D2);
  51.     output_low(PIN_C1);
  52.     output_high(PIN_D0);
  53.     output_high(PIN_C2);
  54.     delay_ms(2000);
  55.     output_low(PIN_C4);
  56.     output_high(PIN_C3);
  57.     delay_ms(23000);
  58.     output_low(PIN_D0);
  59.     output_high(PIN_D1);
  60.     delay_ms(3000);
  61.     output_low(PIN_C3);
  62.     output_high(PIN_C4);
  63.     delay_ms(2000);
  64.     output_low(PIN_C2);
  65.     output_low(PIN_D1);
  66.     output_high(PIN_C0);
  67.     output_high(PIN_D2);
  68.     }
  69.    }

Para salir de un while se utiliza un break, aun que un lazo infinito dentro de una interrupción me parece algo absurdo. Una interrupción debe hacer un proceso lo más corto posible y retornar.

Podrías hacerlo así:

Código: C
  1. Void interrupcion()
  2. {
  3.   if (pin_b0)
  4.   {
  5.       mantenimiento = true
  6.   }
  7.    else
  8.    {
  9.        mantenimiento = false;
  10.    }
  11.    /// limpiar bandera de interrupción.
  12. }
  13.  
  14.  
  15.  
  16. Void main()
  17. { //Función main.
  18.    bool mantenimiento = false;
  19.    enable_interrupts(GLOBAL);
  20.    enable_interrupts(INT_EXT); //Habilita interrupción externa
  21.   while(TRUE)
  22.   {
  23.         if (mantenimiento)
  24.            tareaMantenimiento();
  25.         else
  26.            tareaSemaforo()
  27.   }


dentro de tareaMantenimiento y tareaSemaforo escribes todos tus delays y procesos que deseas hacer.

No recuerdo mucho del CCS, pero me parece que también olvidas limpiar la bandera de interrupción.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:PIC 16f887-CCS-Como salir de INT_EXT hacia mi programa principal reiniciándolo?
« Respuesta #2 en: 11 de Diciembre de 2021, 13:01:44 »
Hola gracias por leer esto, tengo un problema, estoy iniciando con el mundo del PIC, y estoy desarrollando un semáforo de 2 vías con 2 pases peatonales, el problema me plantea que tengo que incluir un switch para mantenimiento y funcionamiento normal, en mantenimiento los LED tiene que oscilar, el problema que tengo es que implemente una interrupción externa para que en cualquier parte del programa, entre en mantenimiento, pero no encuentro la forma de que cuando salga del mantenimiento vuelva al programa principal reiniciándolo, intente incluir un reset pero no funciona, y su coloco un return vuelve a la parte donde se quedo el programa antes de entrar en mantenimiento , adjunto el también el archivo en proteus 8.11

Código: C
  1. #include <16F887.h> //Librería para usar el PIC16F887.
  2. #fuses  XT, NOWRT, NOPUT, NOWDT, NOLVP, NOCPD //Configuración de fusibles.
  3. #use delay (clock=4000000) //FOSC = 4 MHz.
  4. #byte port_b = 0xF06 //Identificador del Puerto B.
  5. #byte port_d = 0xF08 //Identificador del Puerto D.
  6. #byte port_c = 0xF07 // port C
  7. #use standard_io(b) //Usa la librería estándar B.
  8. #use standard_io(d) //Usa la librería estándar D.
  9. #use standard_io(c) //Usa la librería estándar c.
  10.  
  11. int1 X;
  12. #int_ext
  13. Void interrupcion() {
  14. while(true){
  15. X=input(pin_b0);
  16. if (X==1){
  17.  output_c(0xFF);
  18.  output_d(0xFF);
  19.  delay_ms(1000);
  20.  output_c(0x00);
  21.  output_d(0x00);
  22.  delay_ms(1000);
  23. }
  24. else {     //  parte que falla del programa
  25. return ;  //  parte que falla del programa [attachment id=1 msg=420527]  [attachment id=1 msg=420527]
  26. }
  27. }
  28. }
  29.  
  30. Void main(){ //Función main.
  31. enable_interrupts(GLOBAL);
  32. enable_interrupts(INT_EXT); //Habilita interrupción externa
  33.  
  34.   while(TRUE){
  35.    
  36.     output_high(PIN_C0);
  37.     output_high(PIN_C4);
  38.     output_high(PIN_D2);
  39.     output_high(PIN_D4);
  40.     delay_ms(2000);
  41.     output_low(PIN_D4);
  42.     output_high(PIN_D3);
  43.     delay_ms(23000);
  44.     output_low(PIN_C0);
  45.     output_high(PIN_C1);
  46.     delay_ms(3000);
  47.     output_high(PIN_D4);
  48.     output_low(PIN_D3);
  49.     delay_ms(2000);
  50.     output_low(PIN_D2);
  51.     output_low(PIN_C1);
  52.     output_high(PIN_D0);
  53.     output_high(PIN_C2);
  54.     delay_ms(2000);
  55.     output_low(PIN_C4);
  56.     output_high(PIN_C3);
  57.     delay_ms(23000);
  58.     output_low(PIN_D0);
  59.     output_high(PIN_D1);
  60.     delay_ms(3000);
  61.     output_low(PIN_C3);
  62.     output_high(PIN_C4);
  63.     delay_ms(2000);
  64.     output_low(PIN_C2);
  65.     output_low(PIN_D1);
  66.     output_high(PIN_C0);
  67.     output_high(PIN_D2);
  68.     }
  69.    }

Para salir de un while se utiliza un break, aun que un lazo infinito dentro de una interrupción me parece algo absurdo. Una interrupción debe hacer un proceso lo más corto posible y retornar.

Podrías hacerlo así:

Código: C
  1. Void interrupcion()
  2. {
  3.   if (pin_b0)
  4.   {
  5.       mantenimiento = true
  6.   }
  7.    else
  8.    {
  9.        mantenimiento = false;
  10.    }
  11.    /// limpiar bandera de interrupción.
  12. }
  13.  
  14.  
  15.  
  16. Void main()
  17. { //Función main.
  18.    bool mantenimiento = false;
  19.    enable_interrupts(GLOBAL);
  20.    enable_interrupts(INT_EXT); //Habilita interrupción externa
  21.   while(TRUE)
  22.   {
  23.         if (mantenimiento)
  24.            tareaMantenimiento();
  25.         else
  26.            tareaSemaforo()
  27.   }


dentro de tareaMantenimiento y tareaSemaforo escribes todos tus delays y procesos que deseas hacer.

No recuerdo mucho del CCS, pero me parece que también olvidas limpiar la bandera de interrupción.


También algo que recuerdo es que la interrupción externa funciona por flancos, por ejemplo si la activaste por flanco positivo, la interrupción sucede cuando pasa de 0 lógico a 1 lógico, pero al retronar de 1 lógico a 0 lógico, no se produce interrupción.  Al menos que estés utilizando la interrupción por cambio de estado.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:PIC 16f887-CCS-Como salir de INT_EXT hacia mi programa principal reiniciándolo?
« Respuesta #3 en: 11 de Diciembre de 2021, 21:34:46 »
... pero no encuentro la forma de que cuando salga del mantenimiento vuelva al programa principal reiniciándolo, intente incluir un reset pero no funciona, y su coloco un return vuelve a la parte donde se quedo el programa antes de entrar en mantenimiento

En CCS tenés la función  reset_cpu() que hace honor a su nombre: Salta a la dirección de inicio (0x0000) para nunca volver.

Citar
, adjunto el también el archivo en proteus 8.11
Se ha perdido en el ciberespacio.