Autor Tema: Problema: Habilitar/Deshabilitar interrupciones INT_EXT2  (Leído 2208 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado juanjo_gaspa

  • PIC10
  • *
  • Mensajes: 4
Problema: Habilitar/Deshabilitar interrupciones INT_EXT2
« en: 27 de Febrero de 2014, 14:06:17 »
El problema es el siguiente: Estoy trabajando con un PIC18f14k50 conectado a 2 periféricos cada uno por un puerto serie. Uno por Hardware y el otro implementado por software. Utilizo la interrupción INT_EXT2 en el pin RX del puerto rs232 por software para recibir un caracter del periférico.

El problema surge al encender por primera vez el PIC. El programa se cuelga cuando llega a la etapa de habilitación de interrupción por primera vez en el mail. Lo extraño es que sigue colgado hasta que llega el primer caracter y me dispara la int_EXT2. En ese punto el PIC se "reanima" y comienza a funcionar perfectamente de ahí en adelante.

El compilador no me acusa ningun error ni warning pero se cuelga cuando se ejecuta por primera vez la habilitación de interrupción enable_interrupts(GLOBAL);
Será que estoy utilizando mal esta instrucción? Adjunto el código .c

Compilador CCS V4.104


Fusibles y defines
Código: [Seleccionar]
#include <18F14K50.h>

#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV19               
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOMCLR                   //Master Clear pin disabled (Set as Digital Input)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES HFOFST               
#FUSES NOWRT0               
#FUSES NOWRT1               
#FUSES USBDIV1               
#FUSES BBSIZ2K                  //2K words Boot Block size
#FUSES PLLEN                 
#FUSES CPUDIV4                  //System Clock by 4
#FUSES PCLKEN               

#use delay(clock=12000000)

#use rs232(baud=9600,parity=N,xmit=PIN_B7,rcv=PIN_B5,bits=8,stream=SERIAL_SIM900)
#use rs232(baud=9600,parity=N,xmit=PIN_C3,rcv=PIN_C2,bits=8,stream=SERIAL_XBeePRO)

#define PIN_ON  output_high
#define PIN_OFF output_low
#define RELAY1  PIN_C0
#define RELAY2  PIN_C1
//#define PULSADOR1  PIN_C2
//#define PULSADOR2  PIN_C3
#define PULSADOR3  PIN_B6
#define PWM_LED  PIN_C5
#define LED1  PIN_C6
#define LED2  PIN_C7
#define TEMP PIN_B4
#define POWERKEYGSM  PIN_C4


variables globales y funciones:

Código: [Seleccionar]
char valor=0;
boolean x=0;


#int_EXT2                    //interrupción externa ligada al Stream XBeePRO puerto COM por software.
void  EXT2_isr(void)
{

   valor=getc(SERIAL_XBeePRO);
   x=1;
   
   return;

}


void inicializacionSIM900(void)
{
   int cont;
   delay_ms(1000);
   puts("A",SERIAL_SIM900); //para sincronizar el baudrate del SIM 900
   delay_ms(300);
   putchar(0x0d,SERIAL_SIM900);
   delay_ms(1000);
   for(cont=0;cont<5;cont++)              // mando varios AT para el autobauding
         {
         puts("AT",SERIAL_SIM900);
         delay_ms(200);
         putchar(0x0d,SERIAL_SIM900);
         delay_ms(200);
         PIN_ON(LED1);
         delay_ms(200);
         PIN_OFF(LED1);
         }
//-----------------------------------seteos de configuracion del SIM900------------------------         
   puts("AT+CMGF=1\r",SERIAL_SIM900);                  // configuro para que trabaje en modo texto y no PDU
   delay_ms(100);
   putchar(0x0d,SERIAL_SIM900);
   delay_ms(100);
   return;
}



Main:

Código: [Seleccionar]
void main()
{
   int8 i;
   enable_interrupts(INT_EXT2_H2L);
   
   set_tris_b(0b00001100);
   set_tris_c(0b01110100);   
   
   setup_adc_ports(NO_ANALOGS);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);

   PIN_OFF(RELAY1);
   PIN_OFF(RELAY2);
   PIN_ON(LED1);
   PIN_ON(LED2);
   
   PIN_OFF(POWERKEYGSM);    //Enciendo modulo GSM
   delay_ms(1000);
   inicializacionSIM900();  //Inicializo el SIM900

   for(i=0;i<50;i++)
      {
       OUTPUT_TOGGLE(LED2);
       delay_ms(50); 
      };
     
   PIN_ON(LED1);
   PIN_OFF(LED2);
     
   enable_interrupts(GLOBAL);
     
     
for(;;){

  if (x==1)   
     {
     disable_interrupts(GLOBAL);
     PIN_ON(LED1);
     PIN_ON(LED2);
   
     fprintf(SERIAL_SIM900,"AT+CMGS=\"0380154631193\"\r"); // aca poner el numero de celular que recibe el SMS
     delay_ms(300);
   
     PIN_OFF(LED2);
     
     fprintf(SERIAL_SIM900,"Valor recibido: %c",valor);
   
     delay_ms(300);
   
     PIN_ON(LED2);
     
     fprintf(SERIAL_SIM900,"%c",0x1a);
   
     PIN_OFF(LED2);
     delay_ms(200);
     PIN_ON(LED2);
     delay_ms(200);
     PIN_OFF(LED2);
     delay_ms(200);
     PIN_ON(LED2);
     delay_ms(200);
     PIN_OFF(LED2);
     delay_ms(200);
     
     x=0;
     
     enable_interrupts(GLOBAL);
     }
 
 
  else
     {
     Output_toggle(LED1);
     Output_toggle(LED2);
     delay_ms(100);
     }

}


}



Saludos.
« Última modificación: 27 de Febrero de 2014, 14:13:35 por juanjo_gaspa »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema: Habilitar/Deshabilitar interrupciones INT_EXT2
« Respuesta #1 en: 27 de Febrero de 2014, 14:32:24 »
Hola Juanjo,

puede ser otro motivo, pero intentá agregando el modificador ERRORS al #use RS232 (sólo debería ser relevante en la UART que usa el periférico hardware).

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado juanjo_gaspa

  • PIC10
  • *
  • Mensajes: 4
Re: Problema: Habilitar/Deshabilitar interrupciones INT_EXT2
« Respuesta #2 en: 27 de Febrero de 2014, 15:10:19 »
Gracias BrunoF por responder. Acabo de probar con ERRORS en ambos #use  y el problema persiste..
El cuelgue es rarisimo porque solo ocurre una sola vez al encender el pic. Luego del primer caracter que llega y hace saltar la int_EXT2 se acomoda todo y sale funcionando lo mas bien. Sera algún problema del compilador?

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema: Habilitar/Deshabilitar interrupciones INT_EXT2
« Respuesta #3 en: 27 de Febrero de 2014, 17:44:51 »
No creo.

Las interrupciones externas a veces suelen activarse una vez en "falso" durante el encendido.

Seguramente durante el encendido se dispare la interr. EXT2, aún sin recibir ningún caracter, y el getc() te está bloqueando el micro. Deberías considerar que si ingresa un ruido de esa índole, aún durante el funcionamiento (no en el encendido) tu micro va a quedar colgado hasta que arrive el próximo caracter por esa UART.

Probá poniendo al inicio una demora de unos cuantos milisegundos, y justo antes de habilitar las interrupción global, limpiar el flag de la interr. del EXT2.


Saludos
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado juanjo_gaspa

  • PIC10
  • *
  • Mensajes: 4
Re: Problema: Habilitar/Deshabilitar interrupciones INT_EXT2
« Respuesta #4 en: 28 de Febrero de 2014, 00:48:09 »
Sigue sin funcionar pero ahora creo q se cual es el problema. Tenias razón con que el getc(); es el que provoca el cuelgue porque probé agregando 2 seguidos (con la intención de limpiar el buffer) y el programa se cuelga justo donde estan los getc();

Por más que borre el flag antes del enable_interrupt(global); se sigue colgando cada vez que llega al getc();.

Por alguna razón cuando enciendo el pic se dispara la interrupción por más deshabilitada que esté y como no hay ningun dato en el buffer el getc() frena la secuencia hasta que le llega el caracter. Existe alguna forma de borrar el buffer al principio? Porque por alguna razón no puedo evitar que la int_EXT2 se dispare al energizar el circuito.

Creo que había leido algo sobre configurar los TRIS antes o después de habilitar las interrupciones pero me parece extraño.

Código: [Seleccionar]
void main()
{
   int8 i;
   
   delay_ms(1000);
   
   x=0;
   
   enable_interrupts(INT_EXT2_H2L);
   
   set_tris_b(0b00001100);
   set_tris_c(0b01110100);   
   
   setup_adc_ports(NO_ANALOGS);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);

   PIN_OFF(RELAY1);
   PIN_OFF(RELAY2);
   PIN_ON(LED1);
   PIN_ON(LED2);
   
   PIN_OFF(POWERKEYGSM);    //Enciendo modulo GSM
   delay_ms(1000);
   inicializacionSIM900();  //Inicializo el SIM900

   for(i=0;i<50;i++)
      {
       OUTPUT_TOGGLE(LED2);
       delay_ms(100); 
      };
     
   PIN_ON(LED1);
   PIN_OFF(LED2);
     
   x=0;
   enable_interrupts(GLOBAL);
     
   for(;;){

        if (x==1)   
          {
            disable_interrupts(GLOBAL);
     
            PIN_ON(LED1);
            PIN_ON(LED2);
   
 
            fprintf(SERIAL_SIM900,"AT+CMGS=\"0380154631193\"\r"); // aca poner el numero de celular que recibe el SMS
            delay_ms(300);
   
            PIN_OFF(LED2);
     
            fprintf(SERIAL_SIM900,"Valor recibido: %c",valor);
   
            delay_ms(300);
   
            PIN_ON(LED2);
     
            fprintf(SERIAL_SIM900,"%c",0x1a);
   
            PIN_OFF(LED2);
            delay_ms(200);
            PIN_ON(LED2);
            delay_ms(200);
            PIN_OFF(LED2);
            delay_ms(200);
            PIN_ON(LED2);
            delay_ms(200);
            PIN_OFF(LED2);
            delay_ms(200);
     
            x=0;
     
            enable_interrupts(GLOBAL);
           }
 
 
  else
     {
     Output_toggle(LED1);
     Output_toggle(LED2);
     delay_ms(100);
     }



}





}



Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema: Habilitar/Deshabilitar interrupciones INT_EXT2
« Respuesta #5 en: 28 de Febrero de 2014, 00:59:15 »
Hola. El problema no es el buffer. El "buffer" no puede llenarse ya que es un RS232 por software, y por lo tanto ya ni siquiera tiene algo llamado "buffer". Lo único que se llena es una variable dentro de la función getc() siempre y cuando se reciba el bit de Start al menos. Si se dispara en falso la EXT2, pasa lo que te está pasando, que es que getc() se queda esperando un bit de Start que nunca existió ni existe hasta el momento.

No es infalible, pero al incio del código de la interr. EXT2 podés poner:

if(input(PIN_C2)) return;

De esa manera, si el disparo fué en falso, entonces debería ignorar la interr.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado juanjo_gaspa

  • PIC10
  • *
  • Mensajes: 4
Re: Problema: Habilitar/Deshabilitar interrupciones INT_EXT2
« Respuesta #6 en: 28 de Febrero de 2014, 02:53:31 »
Efectivamente con esa línea de código me solucionaste el problema! Y gracias por la info sobre la 232, ni lo habia pensado.

Saludos!


 

anything