TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Tavo en 09 de Diciembre de 2014, 15:55:37

Título: Problemas lectura de pulsadores por medio de interrupciones
Publicado por: Tavo en 09 de Diciembre de 2014, 15:55:37
Hola.
Tengo este sencillo programa donde hago parpadear un led y "atiendo" cuatro pulsadores por interrupciones.
El problema es que después de un tiempo se clava y deja de parpadear el led o no me lee los pulsadores.
El programa considero que es muy sencillo, pero no encuentro el error.

En ISIS 7 Profesional Release 7.7 SP2 funciona bien pero cuando lo armo en un protoboard empiezan los problemas.

Si alguien me puede dar una mano, se los agradezco.
Gracias.
Título: Re: Problemas lectura de pulsadores por medio de interrupciones
Publicado por: KILLERJC en 09 de Diciembre de 2014, 17:21:19
Citar
#INT_TIMER1
void temp1_isr(void)
{
   disable_interrupts(GLOBAL);
   static int8 Temp_led=0;
   
   //Hago parpadear el led de RUN
   if(Temp_led>5)
   {
      //Hago que el port del led de RUN parpadee
      //pin es la pata donde esta conectado el led
      puerto_C=puerto_C ^ 0b00000100;
      Temp_led=0;
   }
   else
   {
      Temp_led++;
   }
   
   set_timer1(Valor_TMR1);
   enable_interrupts(GLOBAL);
}

No se como te puede andar... Temp_led nunca va a superar 1, ya que siempre que entre a esa interrupcion se va a poner a 0. Por lo que tu rutina de interrupcion no serviria. ( A no ser que me equivoque por el static que tiene antes, pero me parece que no )
Y pienso que podes ver que cambia la salida debido a que estas usando el puerto C como un variable para guardar un dato. Y deberias crear una variable en los registros de proposito general apartir de 0x20h (o definir una variable y dejar que el compilador lo haga por si solo) si te fijas en el datasheet para ese motivo. Y actuar segun lo que necesites

Citar
#int_RB
void  RB_isr(void)
{
   disable_interrupts(GLOBAL);
   delay_ms(50);
   puerto_C=puerto_C ^ puerto_B; //^ es un XOR
   delay_ms(100);
   enable_interrupts(GLOBAL);
}

El principal problema ademas del tmr, es que estas valiendote nomas de la entrada RB3, cada ves cambia de estado RB4:Rb7 salta a la interrupcion, suponete esto. Presionas el boton RB4 y tu led esta apagado es decir RC3=0 y RB3=0 (supongo que es 0 pero puede ser cualqueir cosa por que es una entrada y no se si lo tenes a GND o VCC o al aire libre metiendo ruido que es lo que creo que esta pasando )
Si da la casualidad que es 0 entonces
RC3 XOR RB3 = LED
0 XOR 0 = 0 , tu led no prendio para nada.

Si da la casualidad que es uno y el led estaba apagado entonces va a prender .
0 XOR 1 = 1

De aca deberia de leer un 1 para poder volver a su estado normal. Si sigue leyendo 0 quedaria el led prendido para siempre.
1 XOR 1 = 0 // Volveria a apagarse y al primer estado que comente
1 XOR 0 = 1 // Seguiria en 1 y no cambiaria mas.


En fin a arreglar:
Timer: una constante global que se mantenga fuera de la funcion
Interrupcion RB: Aca depende que quieras hacer, si detectaras un cambio preguntaria al menos el nivel en que se encuentra y cual entrada para atender a "4 botones separados"

interrupcion rb
desactivo int global
Rb4 en 1 ? -> hago tal cosa
Rb5 en 1 ? -> hago otra
Rb6 en 1 ? -> otra cosa
Rb7 en 1 ? -> otra
activo int global
salgo


Pregunto si esta en 1 por que no detecta flancos sino cambios de nivel, si pasa de 1 a 0 por que soltaste el boton entraria a la interrupcion por igual pero la condicion va a hacer que no se lo tome en cuenta.
Ademas buscaria distintas salidas y no todo en un led. Tambien probaria el codigo separado, primero el timer y luego lo de los puertos aunque sea para ver que ande todo.
Y creo que es todo, recuerdo que algo mas iba a escribir pero me olvide, ya paresco dorothy de buscando a nemo.

EDIT:
Ya me acorde, imagino que estas usando antirebotes en hardware.