Autor Tema: Dos dudas acerca de interrupciones INT_RB  (Leído 9423 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Dos dudas acerca de interrupciones INT_RB
« en: 24 de Noviembre de 2009, 10:22:29 »
hola:

adjunto el siguiente codigo que al simular con proteus justo al arrancar el programa entra la interrupcion cuando no deberia ser asi


#include <16f877a.h>               //
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //
#use delay (clock=4000000)            //
#use fast_io(b)
#use fast_io(d)
#use fast_io(a)
#byte port_b=0x06                  //


///FUNCION INTERRUPCION
#INT_RB
void IntPortB4_7()
{   
      output_high(PIN_B0);      //indica interrupcion
      output_low(PIN_A0);
     
      if (bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,6 )&& !bit_test(port_b,7 )){     
      output_high(PIN_D4);   
      delay_ms(1500);
      output_low(PIN_D4);}
    if (bit_test(port_b,5 )&& !bit_test(port_b,4 )&& !bit_test(port_b,6 )&& !bit_test(port_b,7 )){   
         output_high(PIN_D5)
         delay_ms(1500);
         output_low(PIN_D5);
         }
    if (bit_test(port_b,6 )&& !bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,7 )){ 
             output_high(PIN_D6);
             delay_ms(1500);
             output_low(PIN_D6);}
    if (bit_test(port_b,7 )&& !bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,6 )){   //¿PIN_B7 genera interrupcion?
         output_high(PIN_D7);
         delay_ms(1500);
         output_low(PIN_D7);}
         
   output_low(PIN_B0);   //indica no interrupcion
}

///PROGRAMA
void main(void)
{
   set_tris_b (0b11111110);     
   set_tris_d (0x00);
   set_tris_a(0x00);
   enable_interrupts(int_rb);     
   enable_interrupts(GLOBAL);     

   while(1){
   output_high(PIN_A0);}
   }


La otra cuestion es sobre si se puede configurar el puerto a en PIC16F877 para salidas y entradas digitales mediante el registro ADCON en CCS, es decir, desactivar la configuracion de entradas y salidas analogicas.

un saludo

aitor
   

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #1 en: 24 de Noviembre de 2009, 10:31:17 »
Hay varias cositas, para leer un pin tienes la función input(PIN_B4) por ejemplo. Después podes agregar el borrado de flag de interrupción antes de la habilitación con clear_interrup(int_rb). Otro detalle es que es necesario leer/escribir el puerto B al finalizar la interrupción para que no se vuelva a ejecutar, esto lo puedes hacer con output_b(input_b()).


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #2 en: 24 de Noviembre de 2009, 11:23:48 »
Hay varias cositas, para leer un pin tienes la función input(PIN_B4) por ejemplo. Después podes agregar el borrado de flag de interrupción antes de la habilitación con clear_interrup(int_rb). Otro detalle es que es necesario leer/escribir el puerto B al finalizar la interrupción para que no se vuelva a ejecutar, esto lo puedes hacer con output_b(input_b()).


Saludos!

Hola:

seria de esta forma?

#include <16f877a.h>               //
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //
#use delay (clock=4000000)            //
#use fast_io(b)
#use fast_io(d)
#use fast_io(a)
#byte port_b=0x06                  //


///FUNCION INTERRUPCION
#INT_RB
void IntPortB4_7()
{   
      output_high(PIN_B0);      //indica interrupcion
      output_low(PIN_A0);
     
      if (bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,6 )&& !bit_test(port_b,7 )){     
      output_high(PIN_D4);   
      delay_ms(1500);
      output_low(PIN_D4);}
    if (bit_test(port_b,5 )&& !bit_test(port_b,4 )&& !bit_test(port_b,6 )&& !bit_test(port_b,7 )){   
         output_high(PIN_D5)
         delay_ms(1500);
         output_low(PIN_D5);
         }
    if (bit_test(port_b,6 )&& !bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,7 )){ 
             output_high(PIN_D6);
             delay_ms(1500);
             output_low(PIN_D6);}
    if (bit_test(port_b,7 )&& !bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,6 )){   //¿PIN_B7 genera interrupcion?
         output_high(PIN_D7);
         delay_ms(1500);
         output_low(PIN_D7);}
         
   output_low(PIN_B0);   //indica no interrupcion
   output_b(input_b());
}

///PROGRAMA
void main(void)
{
   set_tris_b (0b11111110);     
   set_tris_d (0x00);
   set_tris_a(0x00);
   clear_interrup(int rb)
   enable_interrupts(int_rb);     
   enable_interrupts(GLOBAL);     

   while(1){
   output_high(PIN_A0);}
   }

En cuanto a lo de usar bit_test es porque me interesa detectar qué pin hizo la interrupcion, simplemente hago una comparacion con el resto de pines del PORTB.

saludos

aitor

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #3 en: 24 de Noviembre de 2009, 11:42:03 »
Si, así. Te decía lo de input(PIN_B4) porque te devuelve el estado del pin, y no es necesario re-definir nada, ya todo esta hecho o casi todo  :mrgreen:

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #4 en: 24 de Noviembre de 2009, 18:08:47 »
Si, así. Te decía lo de input(PIN_B4) porque te devuelve el estado del pin, y no es necesario re-definir nada, ya todo esta hecho o casi todo  :mrgreen:

Saludos!

Hola:

Pues al simular en proteus no me entra la interrupcion al cambio de estado en ninguno de los pines RB4-7.La verdad es que no veo donde puede fallar. Podria ser el proteus?

#include <16f877a.h>             
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP     
#use delay (clock=4000000)         
#use fast_io(b)
#use fast_io(d)
#use fast_io(a)
#byte port_b=0x06               

// FUNCION INTERRUPCION
#INT_RB
void IntPortB4_7()
{
      output_high(PIN_B0);      //indicador interrupcion on
      output_low(PIN_A0);
      if (bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,6 )&& !bit_test(port_b,7 )){   
      output_high(PIN_D4);   
      delay_ms(1500);
      output_low(PIN_D4);}
    if (bit_test(port_b,5 )&& !bit_test(port_b,4 )&& !bit_test(port_b,6 )&& !bit_test(port_b,7 )){   
         output_high(PIN_D5);
         delay_ms(1500);
         output_low(PIN_D5);
         }
    if (bit_test(port_b,6 )&& !bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,7 )){
             output_high(PIN_D6);
             delay_ms(1500);
             output_low(PIN_D6);}
    if (bit_test(port_b,7 )&& !bit_test(port_b,4 )&& !bit_test(port_b,5 )&& !bit_test(port_b,6 )){ 
         output_high(PIN_D7);
         delay_ms(1500);
         output_low(PIN_D7);}     
   output_low(PIN_B0);   //indicador interrupcion off
   output_b(input_b()); // leer/escribir el puerto B al finalizar la interrupción para que no se vuelva a ejecutar
}

///PROGRAMA
void main(void)
{
   set_tris_b(0b11111110);      //portb entrada menos pin RB0 es salida
   set_tris_d(0x00);
   set_tris_a(0x00);
   output_d(0x00);
   output_a(0x00);
   output_low(PIN_B0);
   clear_interrupt(int_rb); // borro el flag de interrupción para que no entre al principio
   enable_interrupts(int_rb);      //activar interrupcion rb4:7
   enable_interrupts(GLOBAL);      //activar interrupciones
   while(1){
   output_high(PIN_A0);}
   }

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #5 en: 24 de Noviembre de 2009, 18:51:07 »
Si, así. Te decía lo de input(PIN_B4) porque te devuelve el estado del pin, y no es necesario re-definir nada, ya todo esta hecho o casi todo  :mrgreen:

Saludos!

Hola:
ya funciona. he cambiado algunas cosas que me dijiste y ya simula bien proteus.

#include <16f877a.h>             
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP     
#use delay (clock=4000000)         
#use fast_io(b)
#use fast_io(d)
#use fast_io(a)               

// FUNCION INTERRUPCION
#INT_RB
void IntPortB4_7()
{
      output_high(PIN_B0);      //indicador interrupcion on
      output_low(PIN_A0);
      if (!input(PIN_B4)&&input(PIN_B5)&&input(PIN_B6)&&input(PIN_B7))
         {
         output_high(PIN_D4);   
         delay_ms(1500);
         output_low(PIN_D4);
         }
      if (!input(PIN_B5)&&input(PIN_B4)&&input(PIN_B6)&&input(PIN_B7)){   
         output_high(PIN_D5);
         delay_ms(1500);
         output_low(PIN_D5);
         }
      if (!input(PIN_B6)&&input(PIN_B4)&&input(PIN_B5)&&input(PIN_B7)){
             output_high(PIN_D6);
             delay_ms(1500);
             output_low(PIN_D6);}
      if (!input(PIN_B7)&&input(PIN_B4)&&input(PIN_B5)&&input(PIN_B6)){ 
         output_high(PIN_D7);
         delay_ms(1500);
         output_low(PIN_D7);}     
   output_low(PIN_B0);   //indicador interrupcion off
   output_b(input_b()); // leer/escribir el puerto B al finalizar la interrupción para que no se vuelva a ejecutar
}

///PROGRAMA
void main()
{
   set_tris_b(0b11111110);      //portb entrada menos pin RB0 es salida
   set_tris_d(0x00);
   set_tris_a(0x00);
   output_d(0x00);
   output_a(0x00);
   output_low(PIN_B0);
   clear_interrupt(int_rb); // borro el flag de interrupción para que no entre al principio
   enable_interrupts(int_rb);      //activar interrupcion rb4:7
   enable_interrupts(GLOBAL);      //activar interrupciones
   while(1){
   output_high(PIN_A0);}
   }

saludos

aitor

Desconectado zagoaristides

  • PIC12
  • **
  • Mensajes: 99
    • deportes de contacto y fitness
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #6 en: 23 de Febrero de 2010, 18:10:47 »
Hola, bueno, la verdad hace 2 días que intento que funcione la bendita #int_rb en el 16f917 o en el 916. No anda en proteus la simulación. Alguien me puede ayudar? Cuando simulo el "mismo" programa con otro pic como el 877 funca de maravilla, pero en este hijo de su madre no.

Solo quiero que responda esta int, no importa el código, algo simple nada más que funcione en Proteus, ya que el simple

#include <16F917.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOCPD                    //No EE protection
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NODEBUG                  //No Debug mode for ICD

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

char Arriba, Abajo, Enter, Escape;

#int_RB
void  RB_isr(void)
{
      char auxiliar;
      disable_interrupts(INT_RB);
     
      Enter    = !input (PIN_B4);
      Arriba   = !input (PIN_B5);
      Abajo    = !input (PIN_B6);
      Escape   = !input (PIN_B7);
     
      auxiliar = input_b();

      clear_interrupt(INT_RB); 
      enable_interrupts(INT_RB);
      /*
      #asm movf Port_B,0 #endasm*/
}

void main()
{
char c;
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_lcd(LCD_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(int_rb);      //activar interrupcion rb4:7
   enable_interrupts(GLOBAL);      //activar interrupciones

//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!

   while(1){

   }
}


Esto con otro micro funciona. Por favor, créanme que ya lei todo lo que encontré en inglés y castellano, pero no me da resultado, ni los pull up, ni el fast_io, ni nada.

Gracias.
Nadie nació sabiendo...Que genio ese Nadie!!!

Desconectado pablomanieri

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 639
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #7 en: 23 de Febrero de 2010, 19:04:01 »
En este pic la interrupción por cambio de estados de los pines rb4 a rb7 se configuran individualmente,

 enable_interrupts(int_rb4); 
 enable_interrupts(int_rb5);
 enable_interrupts(int_rb6);
 enable_interrupts(int_rb7);


el manejo de esta interrupciones si los haces con
#int_rb

Desconectado mi_chell2002

  • PIC10
  • *
  • Mensajes: 15
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #8 en: 01 de Mayo de 2010, 20:29:41 »
Hola no se si este sea el lugar donde debo hacer mi consulta  pero en fin...bueno  tengo un programita que hice usando estas interrupciones #INT_RB funciona pero el problema es que cuando enciendo la fuente de alimentacion del circuito se me activa la interrupcion...la cual manipula un celular para que me llame...alguna idea de porque?...anteriormente usaba #standard_io pero la cambie a #fast_io(x) ya que pense que ese era el problema. otra cosa es que no se si el compilador borra el RBIF al salir de la subrutina de interrupcion...ya que segun entiendo borra los registros que contienen los flags PR1 y PR2 ( Cuando usamos las directivas del CCS) pero no habla de que borre los flags del registro ITCON donde se encuentra el Flag RBIF...en fin si alguien me puede ayudar...lo agradecere . Aqui esta mi programita.

#use delay (clock=20000000)
#include <retardo_minutos.c>
#BYTE ITCON=0x0B
#use standard_io(A)
#use fast_io(B)
#INT_RB
  void llamar()
 {           
        //funciones..bla..bla...                                               
   
       }
     bit_clear(ITCON,0); /*borro el flag de interrupción( RBIF=1 pasa a RBIF=0)
                          para que la interrupcion no entre al principio.*/
     enable_interrupts(GLOBAL);/* habilita G=1, para se pueda ejecutar otra interrupcion,esto
                                debe hacerse siempre al final de la subrutina o rutina de INT*/

}//las dos instrucciones anteriores las ejecuto por que tengo la duda de que el compilador lo haga.


void main()
{
 
  set_tris_b(0xF0);
  //port_b_pullups(TRUE);
  //bit_clear(ITCON,0);
  clear_interrupt(INT_RB);// borro el flag de interrupción( RBIF=1 pasa a RBIF=0) para que la interrupcion no entre al principio.
  enable_interrupts(INT_RB);//REGISTRO ITCON=0b00001000,habilita interrupcion por cambio en los bits  RB4-RB6 del PORTB.RBIE=1.
  enable_interrupts(GLOBAL);//REGISTRO ITCON=0b11000000,habilita todas las interrupciones y las de los  perifericos.GIE=1,PEIE=1.
  while(1){}
 // como GLOVAL=> G1=1 despues de sleep el programa ejecuta la siguiente instruccion y salta al vector de interrupcion 0004h.

}


Desconectado pablomanieri

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 639
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #9 en: 01 de Mayo de 2010, 20:40:30 »
Para poder borrar las interrupciones provocadas por cambio de estados de Rb4 a Rb7 si o sí hay que hacer una lectura o escritura del puerto B, aunque este valor leído no se use para nada.  Por lo tanto al alimentar el pic por primera vez, antes de habilitar las interrupciones, configuras las pullups si las usas, lees el puerto B, borras el flag de interrupción y luego las habilitas.
El ccs al entrar a la interrupción borra el flag, pero si no lees el puerto no le es posible borrarla.

Desconectado mi_chell2002

  • PIC10
  • *
  • Mensajes: 15
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #10 en: 01 de Mayo de 2010, 21:31:49 »
 #include <16F874A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay (clock=20000000)
#include <retardo_minutos.c>
#BYTE ITCON=0x0B
#use standard_io(A)
#use fast_io(B)
#INT_RB
  void llamar()
 {          
     int i;
     i=0;      
  while(i<4)
       {
         PROGRAMA BLA....BLA...
        
       i++;                                                                
    
       }
     //bit_clear(ITCON,0); // borro el flag de interrupción( RBIF=1 pasa a RBIF=0) para que la interrupcion no entre al principio.
     enable_interrupts(GLOBAL); //ESTA SI QUE TIENE QUE IR CIERTO?.

}


void main()
{
  
  set_tris_b(0xF0);
  output_b(input_b()); //PARA QUE NO SALTE DE INMEDIATO LA INTERRUPCION...(ESTA BIEN?)
  bit_clear(ITCON,0);// borro el flag de interrupción( RBIF=1 pasa a RBIF=0) para que la interrupcion no entre al principio.
  /*clear_interrupt(INT_RB);ESTA INSTRUCCION NO ME APARECE EN EL MANUAL PCW DE CCS, POR ESO USO LA FORMA ANTERIOR.
                            ADEMAS BORRA EL BIT QUE HABILITA LA  INTERRUPCION ( RBIE=1 LO PONE A RBIE=0;)  y no el flag ...?estoy bien?*/
  enable_interrupts(INT_RB);//REGISTRO ITCON=0b00001000,habilita interrupcion por cambio en los bits  RB4-RB6 del PORTB.RBIE=1.
  enable_interrupts(GLOBAL);//REGISTRO ITCON=0b11000000,habilita todas las interrupciones y las de los  perifericos.GIE=1,PEIE=1.
while(1){}
  
 
}


SE AGRADECE TU AYUDA....
Se me olvidaba que sucede lo mismo que he planteado cuando  apago la fuente de alimnetación  si la apago y enciendo a veces una vez o aveces 2 veces  salta la interrupcion ...cuando la apago y enciendo tres veces seguidas  seguro que entra la interrupcion...no tengo idea de porque sucede eseto. Otra cosa que  me gustaria  saber es si tiene que ver  algo en esto el hecho de usar ·#fast_io(x)  o  standard_io(x)?. gracias por tu ayuda...
« Última modificación: 02 de Mayo de 2010, 10:43:44 por mi_chell2002 »

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Dos dudas acerca de interrupciones INT_RB
« Respuesta #11 en: 02 de Mayo de 2010, 15:11:06 »
Otro detalle es que es necesario leer/escribir el puerto B al finalizar la interrupción para que no se vuelva a ejecutar, esto lo puedes hacer con output_b(input_b()).
Apa, eso no lo sabia :shock:

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein


 

anything