TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Medusa en 21 de Julio de 2009, 13:23:23

Título: #int_rda, solo una vez
Publicado por: Medusa en 21 de Julio de 2009, 13:23:23
Hola, estoy usandon parte del codigo de RedPic para capturar una serie de tramas a traves de UART usando la inetrrupcion #int_rda, el problema es que la interrupcion solo es atendida la primera ves, cuando se produce una segunda interrupcion el pic queda congelado. Aqui esta mi codigo, hay algo que estoy haciendo mal????

Código: [Seleccionar]
#include <18F452.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar

// CONSTANTES /////////////////////////////////////////////////////////////////

int const lenbuff=32; // Longitud de buffer, Ajustar
                      // a lo que desees (o te sea posible)

// VARIABLES EN RAM ///////////////////////////////////////////////////////////

int xbuff=0x00;      // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer
char rcvchar=0x00;   // último carácter recibido
char flagcommand=0;  // Flag para indicar comando disponible


char SMS_OK= 0;
char flag = 0;

// Declaración de Funciones ///////////////////////////////////////////////////

void inicbuff(void);        // Borra buffer
int addcbuff(char c);       // añade carácter recibido al buffer
void echos(char c);         // Eco selectivo sobre RS232
void procesa_comando(void); // Procesa comando

// INTERRUPCIONES /////////////////////////////////////////////////////////////

#int_rda
void serial_isr() {    // Interrupción recepción serie USART

  rcvchar=0x00;        // Inicializo carácter recibido
  if(kbhit()){          // Si hay algo pendiente de recibir ...
    rcvchar=getc();    // lo descargo y ...
    addcbuff(rcvchar); // lo añado al buffer y ...

  }
}

void inicbuff(void){ // Inicia a \0 cbuff -------------------
  int i;
  int count=32;
  for(i=0;i<count;i++){     // Bucle que pone a 0 todos los
    cbuff[i]=0x00;          // caracteres en el buffer
  }
  xbuff=0x00;               // Inicializo el índice de siguiente
                            // carácter
  flagcommand = 0;
  flag = 0;
}

int addcbuff(char c){ // Añade a cbuff -----------------------

  switch(c){
      case 0x0A:            // Enter -> Habilita Flag para procesar
        if (flag == 3 )
            flagcommand=1;   
        else
flag++;
        break;
    default:
      cbuff[xbuff++]=c; // Añade carácter recibido al Buffer
  }
}


void Verifica_Trama(){

char xcommand[12];
flagcommand=0;
strcpy(xcommand,"\r$SMS:3\r\rOK\r");
    if(!strcmp(cbuff,xcommand))
    SMS_OK=1;
else
    SMS_OK=0;
   
}
// Programa Principal /////////////////////////////////////////////////////////

void main() {

  enable_interrupts(int_rda); // Habilita Interrupción RDA
  enable_interrupts(global);
  delay_ms(200);

 do{
    SMS_OK = 0;
    inicbuff();
    printf("AT+SMS\r\n");
    flag = 0;
    delay_ms(100);
    while (flagcommand == 0);
    Verifica_Trama();

 }while (SMS_OK == 0);


  printf("Mensaje Recibido");
 

}
 
Título: Re: #int_rda, solo una vez
Publicado por: AKENAFAB en 21 de Julio de 2009, 13:32:59
Al compilar te manda un warning??

O que te pone , en estos dias nos paso algo parecido al usar INt_rda y delay_ms >_<.

Título: Re: #int_rda, solo una vez
Publicado por: Medusa en 21 de Julio de 2009, 13:37:43
No hay ningun warnig, como mensione la primera ves si funciona OK la inetrrupcion y puedo leer la trama que recibo a traves del UART el problema es la segunda ves que deberia producirse la inetrrupcion esta no ocurre !!!! :x  :x  :x
Título: Re: #int_rda, solo una vez
Publicado por: RedPic en 21 de Julio de 2009, 13:42:23
Con un cristal de 20 Mhz el fuse debe ser HS ¿No?  :shock:

Título: Re: #int_rda, solo una vez
Publicado por: Medusa en 21 de Julio de 2009, 13:57:07
Hola Redpic, ya lo cambie, si igual, a la segunda interrupcion no entra a la rutina de interrupcion
Título: Re: #int_rda, solo una vez
Publicado por: Suky en 21 de Julio de 2009, 14:27:20
No veo cuando determinas si se termino recibir la trama, para resetear el puntero xbuff y comparar la trama recibida para ejecutar alguna rutina.

Saludos!
Título: Re: #int_rda, solo una vez
Publicado por: Medusa en 21 de Julio de 2009, 14:50:46
La trama se condera completa cuando recibo el avanace de linea ((0x0A) por 4ta vez
Título: Re: #int_rda, solo una vez
Publicado por: Suky en 21 de Julio de 2009, 15:41:16
Ten en cuenta que luego de imprimir "Mensaje Recibido" el micro pasa a modo sleep.

Saludos!
Título: Re: #int_rda, solo una vez
Publicado por: Medusa en 21 de Julio de 2009, 16:01:46
Hola Suky, si tienes razon, per el pic recibe varios mensajes y sale del lazo do recien cuando recibe el mensaje correto: \r$SMS:3\r\rOK\r"
.
Título: Re: #int_rda, solo una vez
Publicado por: Suky en 22 de Julio de 2009, 01:57:32
El problema surge en definir xcommand de 12 elementos  :shock: Debe ser de 13 para que incluya el elemento '\r'
Después para el correcto funcionamiento del algoritmo, en la trama también se deben agregar los \r asi se puede hacer la comparación correctamente.
Una forma puede ser la siguiente:
Código: C
  1. // INTERRUPCIONES /////////////////////////////////////////////////////////////
  2. #int_rda
  3. void serial_isr() {          // Interrupción recepción serie USART
  4.  
  5.   rcvchar=0x00;              // Inicializo carácter recibido
  6.   if(kbhit()){               // Si hay algo pendiente de recibir ...
  7.     rcvchar=getc();          // lo descargo y ...
  8.     cbuff[xbuff++]=rcvchar;  // Añade carácter recibido al Buffer
  9.     if(rcvchar== '\r'){      // Enter -> Habilita Flag para procesar
  10.        if (flag == 3 ){
  11.            flagcommand=1;  
  12.        }else{
  13.            flag++;
  14.        }
  15.     }
  16.   }
  17. }
  18.  
  19.  
  20. void Verifica_Trama(){
  21.  
  22.    char xcommand[13];
  23.    flagcommand=0;
  24.    strcpy(xcommand,"\r$SMS:3\r\rOK\r");
  25.       if(!strcmp(cbuff,xcommand)){
  26.        SMS_OK=1;
  27.       }else{
  28.        SMS_OK=0;
  29.       }
  30. }


Saludos!



Título: Re: #int_rda, solo una vez
Publicado por: Medusa en 22 de Julio de 2009, 14:32:14
Hola Suky , tienes razon,  :-/  :-/