Autor Tema: RS232_Buffered  (Leído 2478 veces)

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

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
RS232_Buffered
« en: 26 de Febrero de 2009, 14:36:12 »
Hola, este es una aplicacion de RedPIC que me tomado la libertad de modificarlo segun mi necesidad, el objetivo es que cuando el pic el cual esta enlazado a un controlador reciba a traves de su puerto serie una serie de mensajes (comandos) este responda tambien con otros comandos  al controlador.
Cuando el pic reciben cualquiera de los tres comandos ("OK", "ABC OK" y "ABC:9 OK"), debe de responder con (">MSG1" o ">MSG41" o ">MSG8") el programa funciona correctamente  :-/, solo cuando cuando recibe los tres comando validos ("OK", "ABC OK" y "ABC:9 OK"), pero cuando recibe otro comando direfentea a estos tres, no debe de responder y cuando vueva a recibir nuevamente cualquiero de estos comandos validos deberia de responder nuevamente, pero esto no sucede  :(, a pesar de que el pic esta recibiendo comando validos, a menos de resete el pic. Cual es mi error  :? o como podria corregir esto  :g).

Código: [Seleccionar]
#include <16f877a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=20M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

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

int const lenbuff=64;                  // 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 caracter recibido
int1 flagcommand=0;                    // Flag para indicar comando disponible

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

void inicbuff(void);                   // Borra buffer
int  addcbuff(char c);                 // añade caracter 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 caracter recibido                   
   if(kbhit()){                        // Si hay algo pendiente de recibir ...
      rcvchar=fgetc();                  // lo descargo y ...
      addcbuff(rcvchar);               // lo añado al buffer y ...
   }
}

// Desarrollo de Funciones ////////////////////////////////////////////////////

void inicbuff(void){                   // Inicia a \0 cbuff -------------------
   int i;

   for(i=0;i<lenbuff;i++){             
      cbuff[i]=0x00;                   
   }
   xbuff=0x00;                         
}

int addcbuff(char c){                  // Añade a cbuff -----------------------
      switch(c){
         case 0x0D:                    // Enter -> Habilita Flag para procesar
            flagcommand=1;             // Comando en Main
         break;
         default:
            cbuff[xbuff++]=c;          // Añade caracter recibido al Buffer
      }
}

// Programa Principal /////////////////////////////////////////////////////////

void main() {
   inicbuff();                                   // Borra buffer al inicio
   printf("\r\n\Inicializando el Controladorr\r\n");
   enable_interrupts(int_rda);                   // Habilita Interrupción RDA
   enable_interrupts(global);                    // Habilita interrupciones
   do {
         if(flagcommand)
         procesa_comando();         
   } while (TRUE);
}

// Procesador de Comandos /////////////////////////////////////////////////////
void procesa_comando(void){
   char arg[lenbuff];                   
   flagcommand=0;                       
   if(cbuff[0]=='O'&&cbuff[1]=='K'){            // Comparo inicio del buffer con comando "OK"
         printf(">MSG1");   
   }
   if(cbuff[0]=='A'&&cbuff[1]=='B'&&cbuff[2]=='C'&&cbuff[3]==' '&&cbuff[4]=='O'&&cbuff[5]=='K'){            // Comparo inicio del buffer con comando "ABC OK"
         printf(">MSG41");   
   }
   if(cbuff[0]=='A'&&cbuff[1]=='B'&&cbuff[2]=='C'&&cbuff[3]==':'&&cbuff[4]=='9'&&cbuff[5]=='K'&&cbuff[6]==' '&&cbuff[7]=='O'&&cbuff[8]=='K'){            // Comparo inicio del buffer con comando "ABC:9 OK"
         printf(">MSG8");   
   }
   inicbuff();                                  // Borro buffer.
}
« Última modificación: 26 de Febrero de 2009, 19:59:57 por Medusa »

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5552
    • Picmania by Redraven
Re: RS232_Buffered
« Respuesta #1 en: 26 de Febrero de 2009, 18:16:52 »
Aparentemente debería funcionar ... no le veo nada que lo impida ... pero cualquier programa nos puede dar una sorpresa.

Ponle algo que vemos lo que recibe el procesador de comandos para ver si hay alguna diferencia en la "segunda vuelta" ... no vaya a ser que al controlar posiciones absolutas de cada carácter en cbuff tengamos desplazados los caracteres dentro de él y no estemos comparando bien ....

Código: C#
  1. // Procesador de Comandos /////////////////////////////////////////////////////
  2. void procesa_comando(void){
  3.    char arg[lenbuff];                  
  4.    flagcommand=0;                      
  5.    if(cbuff[0]=='O'&&cbuff[1]=='K'){            // Comparo inicio del buffer con comando "OK"
  6.          printf(">MSG1");    
  7.    }
  8.    if(cbuff[0]=='A'&&cbuff[1]=='B'&&cbuff[1]=='C'&&cbuff[2]==' '&&cbuff[3]=='O'&&cbuff[4]=='K'){            // Comparo inicio del buffer con comando "ABC OK"
  9.          printf(">MSG41");    
  10.    }
  11.    if(cbuff[0]=='A'&&cbuff[1]=='B'&&cbuff[1]=='C'&&cbuff[2]==':'&&cbuff[3]=='9'&&cbuff[4]=='K'&&cbuff[2]==' '&&cbuff[3]=='O'&&cbuff[4]=='K'){            // Comparo inicio del buffer con comando "ABC:9 OK"
  12.          printf(">MSG8");    
  13.    }
  14.    // He recibido .... ////////////////
  15.    printf("%s",cbuff);
  16.    /////////////////////////////////////
  17.    inicbuff();                                  // Borro buffer.
  18. }
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Re: RS232_Buffered
« Respuesta #2 en: 26 de Febrero de 2009, 20:10:14 »
Hola RedPIC,  :-/ gracias por responder a mi duda, esto me parece raro, he  hecho lo que me has sugerido es decir he aumentado

 
Código: [Seleccionar]
printf("%s",cbuff);
Y ahora el programa hace lo que debe  :mrgreen: y cuando quito esta linea el problema se presenta nuevamente  :( , a que crees que se deba esto :?

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5552
    • Picmania by Redraven
Re: RS232_Buffered
« Respuesta #3 en: 26 de Febrero de 2009, 20:11:50 »
 :shock:

absolutamente incomprensible

 :shock:

Haz otra prueba. Quita el printf() y pon un delay_ms(10), por ejemplo.
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: RS232_Buffered
« Respuesta #4 en: 26 de Febrero de 2009, 23:23:27 »
Seria bueno cambiar los if por else if para garantizar que solo evalue uno de los condicionales y colocar a lo ultimo un else para garantizar que procese tambien el estado de un comando invalido.

Otra forma de compararlos es como te dije en el otro post, usando la libreria string.h, de esa manera pordrias colocar la comparacion en un for recorriendo cada una de las opciones.
El papel lo aguanta todo

Desconectado joseto

  • PIC10
  • *
  • Mensajes: 11
Re: RS232_Buffered
« Respuesta #5 en: 27 de Febrero de 2009, 02:02:10 »
Hola Medusa :)
Compile el código y me funciono bien a acepción del comando ABC:9 OK que dentro de procesa_comando() tu comparas con una ‘K’ extra. Prueba el siguiente código, solo cambie ciertos detalles pequeños que te los explico más abajo.


Código: [Seleccionar]

#include <16f877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=20M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

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

int const lenbuff=64;                  // 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 caracter recibido
int1 flagcommand=0;                    // Flag para indicar comando disponible

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

void inicbuff(void);                   // Borra buffer
void  addcbuff(char c);                 // añade caracter 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 caracter recibido                   
                                       // Si hay algo pendiente de recibir ...
   rcvchar=fgetc();                    // lo descargo y ...
   addcbuff(rcvchar);                  // lo añado al buffer y ...
   
}

// Desarrollo de Funciones ////////////////////////////////////////////////////

void inicbuff(void){                   // Inicia a \0 cbuff -------------------
   int i;

   for(i=0;i<lenbuff;i++){             
      cbuff[i]=0x00;                   
   }
   xbuff=0x00;                         
}

void addcbuff(char c){                  // Añade a cbuff -----------------------
      switch(c){
         case 0x0D:                    // Enter -> Habilita Flag para procesar
            flagcommand=1;             // Comando en Main
         break;
         default:
            cbuff[xbuff++]=c;          // Añade caracter recibido al Buffer
      }
}

// Programa Principal /////////////////////////////////////////////////////////

void main() {
   inicbuff();                                   // Borra buffer al inicio
   printf("\r\n\Inicializando el Controladorr\r\n");
   enable_interrupts(int_rda);                   // Habilita Interrupción RDA
   enable_interrupts(global);                    // Habilita interrupciones
   do {
         if(flagcommand)
         procesa_comando();         
   } while (TRUE);
}

// Procesador de Comandos /////////////////////////////////////////////////////
void procesa_comando(void){
                     
   flagcommand=0;                       
   if(cbuff[0]=='O'&&cbuff[1]=='K'){            // Comparo inicio del buffer con comando "OK"
         printf(">MSG1");   
   }
   if(cbuff[0]=='A'&&cbuff[1]=='B'&&cbuff[2]=='C'&&cbuff[3]==' '&&cbuff[4]=='O'&&cbuff[5]=='K'){            // Comparo inicio del buffer con comando "ABC OK"
         printf(">MSG41");   
   }
   if(cbuff[0]=='A'&&cbuff[1]=='B'&&cbuff[2]=='C'&&cbuff[3]==':'&&cbuff[4]=='9'&&cbuff[5]==' '&&cbuff[6]=='O'&&cbuff[7]=='K'){            // Comparo inicio del buffer con comando "ABC:9 OK"
         printf(">MSG8");   
   }
   inicbuff();                                  // Borro buffer.
}


Si usas un cristal de 20Mhz el fuse debe ser HS
Si la función int  addcbuff(char c); no retorna nada preferible usa void addcbuff(char c);
De manera personal dentro de la interrupción de recepción serial no utilizo kbhit () ya que no es necesario, pero si decides ponerlo no debería causar inconvenientes

Un saludo   :-)




Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Re: RS232_Buffered
« Respuesta #6 en: 27 de Febrero de 2009, 18:14:20 »
Hola redPic,  :-/ funciona.. gracia por tu ayuda y de los demas..


 

anything