TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: ro en 14 de Abril de 2008, 13:30:11

Título: ¿por qué no interrumpe?
Publicado por: ro en 14 de Abril de 2008, 13:30:11
hola, tengo un problemilla con las interrupciones, no consigo que mi programa interrumpa, y no encuentro el error por ningún lado.



#include <p30f4013.h>
#include <ports.h>
 

//FUSES
_FOSC(CSW_FSCM_OFF &  XT_PLL4);
_FGS(CODE_PROT_OFF);
_FWDT( WDT_OFF);
_FBORPOR(PBOR_OFF & MCLR_DIS & PWRT_OFF);

void CONFIGinterrups(void) {

   CloseINT1();

   ConfigINT1(EXT_INT_ENABLE & EXT_INT_PRI_6 & RISING_EDGE_INT);

}




int main (void){

/*********************************************************************
* Al empezar habilito las interrupciones, les doy prioridad 6
* y las activo a flanco de subida
********************************************************************/

CONFIGinterrups();


TRISB = 0;


while(1){


   if(IFS1bits.INT1IF==1){
      PORTB=0x0F;
   } else{
      PORTB=0xF0;
   }
      

return 0;
}


}

para probarlo cambio la señal de entrada INT1 de cero a uno y el bit INT1IF debería ponerse a uno, pero no lo hace (lo veo con PORTB que lo llevo a los leds).

¿Alquien sabe que puede estar pasando? Muchas graccias
Título: Re: ¿por qué no interrumpe?
Publicado por: migsantiago en 14 de Abril de 2008, 18:12:28
Hola

¿Qué compilador usas?

Cuando yo uso el compilador CCS hay una sección del código que "atiende" la interrupción. En esa sección es donde yo cambiaría el estado del puerto B.

Viendo tu programa no la encuentro pero me imagino que solo estás al pendiente de la bandera de que se activa la interrupción. Un detalle...

Código: [Seleccionar]
   if(IFS1bits.INT1IF==1){
      PORTB=0x0F;
   } else{
      PORTB=0xF0;
   }

Cuando se activa la bandera, portb vale 0x0f, pero inmediatamente después se desactiva ya que me imagino que tu compilador limpia las banderas automáticamente poniéndolas a cero después de atenderlas. Al hacerse esto portb vale 0x00 y tus ojos no lo ven encender porque es rapidísimo.

¿Puedes poner un delay o sleep justo después de encender portb para ver si realmente enciende?
Título: Re: ¿por qué no interrumpe?
Publicado por: ro en 15 de Abril de 2008, 06:31:17
hola, mi compilador es el C30, pues estoy intentando eso qeu me dices de parar la ejecución y nada, no interrumpe, de todos modos creo que debo cambiar yo a mano el valor de INT1IF, pero eso ya lo veré.
Lo de la rutina que atiende a la interrupción, ¿a que te refieres? Muchas gracias.

saludos
Título: Re: ¿por qué no interrumpe?
Publicado por: migsantiago en 15 de Abril de 2008, 19:13:21
Hola

Es que en los pocos compiladores que he usado cuando quiero atender una subrutina pongo...

void int_por_rb0()
{
//aquí hago lo que tengo que hacer cuando rb0
//es interrumpido, por ejemplo
}

main()
{
//programa normal
//configuro mi interrupción, pero aquí no
//ejecuto nada que tenga que ver con ella
}

Cuando ocurre la interrupción, el apuntador de programa brinca inmediatamente a void int_por_rb0 y ejecuta lo que está ahí dentro. Talvez ahí deberías poner tu portb=0xf0, pero no sé cómo lo debes hacer en C30  :oops:
Título: Re: ¿por qué no interrumpe?
Publicado por: Modulay en 16 de Abril de 2008, 01:46:07
¿Qué ficheros tienes incluídos en el proyecto?
Título: Re: ¿por qué no interrumpe?
Publicado por: Modulay en 16 de Abril de 2008, 01:53:21
Por lo pronto,tienes el "return (0)" dentro del while.
Sácalo y vuelve a probar
Título: Re: ¿por qué no interrumpe?
Publicado por: ro en 16 de Abril de 2008, 04:43:24
ya lo he conseguido, no llamaba bien a la rutina de atención, por si a alguien más le pasa, hay que poner una nueva función que es:

void main (void){

   while (1) { // para que se ejecute continuamente,
   }
}

void __attribute__((__interrupt__)) _INT1Interrupt(void){

   /*todo lo que quiero que haga*/
   IFS1bits.INT1IF=0; //limpiar el flag
}



Título: Re: ¿por qué no interrumpe?
Publicado por: firepic en 24 de Abril de 2008, 17:28:07
Saludos! Qué bien que resolviste tu problema!!
Pero por eso es que me encanta CCS!
Antes de la rutina de interrupción colocas:

#INT_tipo de interrupción
nombre_de_función()
{
    Lo que quieres que haga;
}

Y cuando se origina la interrupción, el programa busca el #INT apropiado y ejecuta la rutina. Al salir de esa función, él automáticamente limpia la bandera de interrupción y habilita la interrupción nuevamente.
Genial!  :-/
Título: Re: ¿por qué no interrumpe?
Publicado por: vszener en 25 de Abril de 2008, 06:23:22
Cuidado en creer que el CCS limpia los 'flag's' automáticamente....hay casos en los que no.

Normalmente el CCS sigue el datasheet del micro con respecto a estos menesteres.


Suerte!!! ;)
Título: Re: ¿por qué no interrumpe?
Publicado por: Nocturno en 25 de Abril de 2008, 07:01:36
¿Sabes en qué caso no limpia el flag?
Título: Re: ¿por qué no interrumpe?
Publicado por: firepic en 25 de Abril de 2008, 14:17:46
Citar
Cuidado en creer que el CCS limpia los 'flag's' automáticamente....hay casos en los que no
Respeto la experiencia del amigo vszener, me imagino que si dices eso tienes tus razones.
Mi opinión la digo por lo que dice el manual del CCS. Especifico el manual: "C Compiler Reference Manual, Version 4, August 2007"... en su página 101 donde habla de la sentencia #INT_xxxx, después de enumerar todas las interrupciones, al final dice:
"Purpouse: " y en el párrafo dos: "The compiler will generate code to jump to the function when the interrupt is detected. It will generate code to save and restore the machine state, and will clear the interrupt flag. To prevent the flag from being cleared add NOCLEAR after the #INT_xxxx." (Cursivas y Negrillas mías).

No soy un gran hablante de inglés, pero se entiende que "el compilador generará el código para saltar a la función cuando se detecta la interrupción. Generará código para salvar y restaurar el estado de máquina y limpiará la bandera de interrupción. Para prevenir que la bandera de interrupción sea limpiada desde el inicio, añada un NOCLEAR después de #INT_xxxx". O sea que si uno no quiere que limpie la bandera, para eso hay una sentencia especial; se supone que para todos los demás casos lo hace.
Así que tengo duda con respecto a la opinión de vszener. Por favor cuando tengas tiempo explica con más detalles si te ha ocurrido en algún caso que no haya limpiado la bandera de interrupción.
Saludos!
Título: Re: ¿por qué no interrumpe?
Publicado por: RedPic en 25 de Abril de 2008, 14:53:20
Hasta ahora yo jamás he limpiado un flag de interrupción en CCS y siempre me han funcionado las interrupciones que he utilizado.

De echo si quisiera o quisiese limpiar un fla de interrupción tendría que empezar por preguntaros cómo se hace (en CCS) o sumergirme en el Datasheet del micro para ver su dirección y subirlo/bajarlo según corresponda.

Las interrupciones que he usado (en CCS) son:

#int_rda
#rtcc
#ad
#int_timer0
#int_timer1
#int_timer2
#int_eeprom
#int_ext
#int_ext1
#int_ext2
#int_ccp1
#int_ccp2
#int_rb

Estas, al menos, no necesitan intervención adicional a la de declararlas y habilitarlas.
Título: Re: ¿por qué no interrumpe?
Publicado por: pocher en 25 de Abril de 2008, 15:28:33
La interrupción #int_rb no va bien: http://www.todopic.com.ar/foros/index.php?topic=21226.0

¡¡¡ Comprobado !!!
Título: Re: ¿por qué no interrumpe?
Publicado por: firepic en 25 de Abril de 2008, 22:59:15
Gracias por el dato amigo porcher!!  :-)
Yo ya había usado esa interrupción pero sí había leído del puerto para detectar qué botón había sido presionado (tenía cuatro botones, en RB4:7)... creo que por eso me funcionó bien.
Pero tomaré en cuenta ese "bug" del CCS.
De todos modos, cuando hay un problemita que persiste y dudo del compilador, siempre me voy por analizar el archivo .lst y veo la "traducción" al ASM. Creo que es una buena forma de detectar bugs.
Pero sencillamente me quedo asombrado con ustedes, los Moderadores y Seres Supremos de este foro... son unos coquitos  :D , no se les puede igualar...
Bien nos estamos escribiendo.  :-)
Título: Re: ¿por qué no interrumpe?
Publicado por: migsantiago en 25 de Abril de 2008, 23:05:10
Pero sencillamente me quedo asombrado con ustedes, los Moderadores y Seres Supremos de este foro... son unos coquitos  :D , no se les puede igualar...

jajaja

hay seres supremos que no lo son por contestar todas las preguntas difíciles, lo somos por hacer todas las preguntas difíciles, así que existen excepciones firepic  :D

De todos mis mensajes, la mayoría son peticiones de ayuda  :oops:
Título: Re: ¿por qué no interrumpe?
Publicado por: firepic en 25 de Abril de 2008, 23:41:06
Jeje puede que sí Migsantiago... y de las preguntas difíciles vienen las investigaciones y soluciones más interesantes...  :-/
Es buena tu modestia... todos deberíamos mantener esa cualidad siempre.  :)
Eso es lo bueno de este foro, que todo el mundo se ayuda entre sí... a veces le toca el papel a uno de ayudar y muchas otras veces de ser el ayudado.
Saludos cordiales!
Título: Re: ¿por qué no interrumpe?
Publicado por: pocher en 26 de Abril de 2008, 01:44:59
Hola, yo también me siento uno más de esta gran familia y me llena de satisfacción cuando a alguién le ha podido ser útil tu pequeño consejo.

Saludos cordiales.
Título: Re: ¿por qué no interrumpe?
Publicado por: ro en 29 de Abril de 2008, 12:08:56
Hola de nuevo, una vez más me están volviendo loca las interrupciones, os cuento:
estoy intentando configurar la entrada IC2 (input capture) para que me cuente cuantos ciclos de relo está alta la señal que le meto por ese pin. Entonces hago (sólo el código importante):

void CONFIGcapture(void) {
  CloseCapture2();
  unsigned int configura = IC_DLE_STOP & IC_TIMER3_SRC & IC_INT_1CAPTURE & IC_EVERY_EDGE;
  //captura parada en modo idle, lectura del timer3, se interrumpe en la primera lectura y cada flanco de subida y de bajada
  OpenCapture2(configura);
 }

int void (main) {
  CONFIGcapture();
  while(1) {

  }
  return 1;
}


void __attribute__((__interrupt__)) _IC2Interrupt(void){
  IFS0bits.IC2IF = 0;
  putsUART1("interrupcion");
}



Sin embargo sólo me interrumpe una vez, lo sé por el mensaje de "interrupción" sólo me aparece una vez. ¿Tengo que hacer algo más en el caso de este tipo de interrupción además de limpiar el bit?

Muchas gracias



Título: Re: ¿por qué no interrumpe?
Publicado por: firepic en 29 de Abril de 2008, 20:46:22
Saludos!
No conozco el compilador que usas, el C30, yo uso el CCS... así que no sé a ciencia cierta qué hace al salir de la rutina de interrupción... Como hemos estado mencionado, CCS limpia automáticamente la bandera de interrupción... Pero si en C30 estás limpiando "manualmente" la bandera, no sé... prueba habilitar nuevamente la interrupción antes de salir de la rutina de servicio... a ver qué tal... aunque no creo que ese sea el problema, pero por si acaso...  :D
Exito en tu proyecto!  :mrgreen:
Título: Re: ¿por qué no interrumpe?
Publicado por: ro en 30 de Abril de 2008, 04:28:06
hola estoy mandando el bit de enable de la interrupción directamente a un led y está encendido, asi que en ningún momento se me deshabilitan las interrupciones.

Otra cosa que me está sacando loca es que si pongo a los leds el registro IC2CON la primera vez (cuando escribe) se me ilumina el bit de "buffer no vacio" (perfecto) y cuando pasan otros 4 ciclos (donde supuestamente debería interrumpir) se ilumina el de overflow (que también está bien porque el tamaño del buffer es de cuatro, y al quinto desborda) pero... ¿como es posible que esté captando datos si no me está interrumpiendo?

Muchas gracias por la ayuda.