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.11Código: C
#include <16F887.h> //Librería para usar el PIC16F887. #fuses XT, NOWRT, NOPUT, NOWDT, NOLVP, NOCPD //Configuración de fusibles. #use delay (clock=4000000) //FOSC = 4 MHz. #byte port_b = 0xF06 //Identificador del Puerto B. #byte port_d = 0xF08 //Identificador del Puerto D. #byte port_c = 0xF07 // port C #use standard_io(b) //Usa la librería estándar B. #use standard_io(d) //Usa la librería estándar D. #use standard_io(c) //Usa la librería estándar c. int1 X; #int_ext Void interrupcion() { while(true){ X=input(pin_b0); if (X==1){ output_c(0xFF); output_d(0xFF); delay_ms(1000); output_c(0x00); output_d(0x00); delay_ms(1000); } else { // parte que falla del programa return ; // parte que falla del programa [attachment id=1 msg=420527] [attachment id=1 msg=420527] } } } Void main(){ //Función main. enable_interrupts(GLOBAL); enable_interrupts(INT_EXT); //Habilita interrupción externa while(TRUE){ output_high(PIN_C0); output_high(PIN_C4); output_high(PIN_D2); output_high(PIN_D4); delay_ms(2000); output_low(PIN_D4); output_high(PIN_D3); delay_ms(23000); output_low(PIN_C0); output_high(PIN_C1); delay_ms(3000); output_high(PIN_D4); output_low(PIN_D3); delay_ms(2000); output_low(PIN_D2); output_low(PIN_C1); output_high(PIN_D0); output_high(PIN_C2); delay_ms(2000); output_low(PIN_C4); output_high(PIN_C3); delay_ms(23000); output_low(PIN_D0); output_high(PIN_D1); delay_ms(3000); output_low(PIN_C3); output_high(PIN_C4); delay_ms(2000); output_low(PIN_C2); output_low(PIN_D1); output_high(PIN_C0); output_high(PIN_D2); } }
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.11Código: C
#include <16F887.h> //Librería para usar el PIC16F887. #fuses XT, NOWRT, NOPUT, NOWDT, NOLVP, NOCPD //Configuración de fusibles. #use delay (clock=4000000) //FOSC = 4 MHz. #byte port_b = 0xF06 //Identificador del Puerto B. #byte port_d = 0xF08 //Identificador del Puerto D. #byte port_c = 0xF07 // port C #use standard_io(b) //Usa la librería estándar B. #use standard_io(d) //Usa la librería estándar D. #use standard_io(c) //Usa la librería estándar c. int1 X; #int_ext Void interrupcion() { while(true){ X=input(pin_b0); if (X==1){ output_c(0xFF); output_d(0xFF); delay_ms(1000); output_c(0x00); output_d(0x00); delay_ms(1000); } else { // parte que falla del programa return ; // parte que falla del programa [attachment id=1 msg=420527] [attachment id=1 msg=420527] } } } Void main(){ //Función main. enable_interrupts(GLOBAL); enable_interrupts(INT_EXT); //Habilita interrupción externa while(TRUE){ output_high(PIN_C0); output_high(PIN_C4); output_high(PIN_D2); output_high(PIN_D4); delay_ms(2000); output_low(PIN_D4); output_high(PIN_D3); delay_ms(23000); output_low(PIN_C0); output_high(PIN_C1); delay_ms(3000); output_high(PIN_D4); output_low(PIN_D3); delay_ms(2000); output_low(PIN_D2); output_low(PIN_C1); output_high(PIN_D0); output_high(PIN_C2); delay_ms(2000); output_low(PIN_C4); output_high(PIN_C3); delay_ms(23000); output_low(PIN_D0); output_high(PIN_D1); delay_ms(3000); output_low(PIN_C3); output_high(PIN_C4); delay_ms(2000); output_low(PIN_C2); output_low(PIN_D1); output_high(PIN_C0); output_high(PIN_D2); } }
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
Void interrupcion() { if (pin_b0) { mantenimiento = true } else { mantenimiento = false; } /// limpiar bandera de interrupción. } Void main() { //Función main. bool mantenimiento = false; enable_interrupts(GLOBAL); enable_interrupts(INT_EXT); //Habilita interrupción externa while(TRUE) { if (mantenimiento) tareaMantenimiento(); else tareaSemaforo() }
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.
... 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.11Se ha perdido en el ciberespacio.