Hola alesgare, ahora un poco más tranquilo, vamos a revisar tus preguntas:
1.- Como he dicho antes, tuve que cambiar la rutina de inicialización, pues no funcionaba la que me mandaste, entonces, ¿es realmente importante esa rutina? o la modifico de todas formas?
Obviamente las directivas de preprocesador son fundamentales (lo que tu llamas rutina de inicialización en realidad no es una rutina en si, sino la configuración del PIC que se realiza cuando se graba el micro) y de ello dependen que el programa ande o no. Yo extraje el segmento de preprocesadores de un programa que tenia, porque estaba realmente apurado y no lo revise, el programa inclusive estaba configurado para una transmisión USB asi que no necesariamente la configuración que puse es la óptima para tu programa. Ya más adelante nos dedicaremos a eso.
2.- En el código también agregué ciertas cosas que pensé que faltaban como desactivar las interrupciones cuando entra a la interrupción y activarlas nuevamente cuando sale. También agregué los set_tris_x que no estaban antes y #BYTE PORTX=XXXX que también faltaban... he hecho bien???
Tal como te lo ha dicho el compañero Pocher, CCS desactiva la interrupción automáticamente al entrar en ella y la activa nuevamente al salir de ella, por lo que no necesitas hacerlo manualmente. Los #byte para definir los registros de los puertos no son realmente necesarios, pero de todas formas no influyen en el funcionamiento o no del programa. Con respecto a configurar los registros TRIS, como no has definido ninguna configuración específica de entrada y salida con #USE XXX_IO el programa utiliza la predeterminada o standard_io. En este modo el compilador se encarga de definir las direcciones en los puertos automáticamente cada vez que van a ser utilizados, por lo que el set_tris es seguramente una redundancia. Como no me quedo tranquilo y no me gusta el método standard_io (pero es el más facil de implementar) utilizaremos a partir de ahora el metodo fast_io. Ya lo veremos mas adelante.
3.- Y lo más importante: porqué aún no funciona la interrupción?? De que otra manera puede funcionar?? Que falta!?
La interrupción tal como fue definida deberia andar, revisa el datasheet del 18F2550 pero estoy casi seguro que la interrupción externa 0 corresponde al pin RB0. Si RB0 es definido como entrada y si se habilita la interrupción por software, no hay motivo por el cual no funcione.
Vamos con el código, veo que otra vez hay un desparramo de rutinas y configuraciones sin sentido, pero nada que no se pueda arreglar, de todas formas prueba el código que te doy y dime si no he metido la pata
. Vamos a repasar un poco el código que has posteado:
#device adc=8
No estas utilizando el ADC asi que esta configuración sobra. Quitemos todo lo innecesario para probar lo básico y luego podremos ir profundizando, que te parece?
#FUSES WDT //No Watch Dog Timer
En realidad el fuse WDT si activa el Watchdog y aunque lo reinicias en durante cada delay, yo lo apagaria porque tu código no lo necesita por ahora.
El resto de los fuses esta bien, mi configuración no te andaba porque yo lo coloque para que funcione con cristal externo y además con el MCLR activado. Error mio, pues tu no tienes nada de eso en tu circuito, imposible que andase
do{
output_low(PIN_A1); //led off
delay_ms(500);
output_high(PIN_A1); //led on
delay_ms(500);
}while(1);
if (Flag_LED){
output_high(PIN_A0); // Coloca en 1 la salida AN0 por medio segundo cuando pasa alguien y luego la vuelve a 0.
delay_ms(500);
output_low(PIN_A0);
Flag_LED = 0;
}
}
}
Seguramente la interrupción se produce pero como nunca sale del while, el código despues de él nunca se ejecuta, me extraña que el compilador no te halla tirado una advertencia de "code unreachable" porque ese segmento es inalcanzable en tiempo de ejecución. Ahora posteo el código que debería funcionar, esta vez dejo los fuses como estan:
// DIRECTIVAS DE PREPROCESADOR.
#include <18F2550.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOMCLR //Master Clear pin disabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL1 //No PLL PreScaler
#use delay(clock = 8000000) // Reloj interno de 8 Mhz.
#use fast_io(A) // Las direcciones de los puertos solo pueden ser configuradas mediante set_tris_x() y _
#use fast_io(B) // no se cambian cada vez que se ejecuta una operación de entrada o salida. Esto acelera la velocidad de procesamiento.
// VARIABLES GLOBALES.
int Cuenta = 0;
short Flag_LED = 0;
// PROCEDIMIENTO DE INTERRUPCION POR FLANCO DESCENDENTE EN EL PIN B0.
#int_ext
void ISR_ext()
{
Cuenta++;
Flag_LED = 1;
}
// PROCEDIMIENTO PRINCIPAL.
void main()
{
enable_interrupts(int_ext); // Habilita la interrupción externa.
enable_interrupts(global); // Habilita en forma global las interrupciones.
ext_int_edge (0, H_TO_L); // La interrupción se produce cuando se produce un flanco descendente.
set_tris_a(0b00000000);
set_tris_b(0b00000001); // Solo RB0 es entrada.
while(1){
if (Flag_LED){
output_high(PIN_A0); // Coloca en 1 la salida AN0 por medio segundo cuando pasa alguien y luego la vuelve a 0.
delay_ms(500);
output_low(PIN_A0);
Flag_LED = 0;
}
}
Prueba el código, si no tienes el HW mal conectado deberia funcionar, si lo hace en forma correcta postea un mensaje con el titulo del tema mas (SOLUCIONADO) asi queda disponible para los demás usuarios. Esperamos tu respuesta.
Saludos.