Autor Tema: Problemas de comparacion de cadenas  (Leído 1902 veces)

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

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Problemas de comparacion de cadenas
« en: 13 de Julio de 2017, 11:49:35 »
Hola, estoy tratando de comparar dos cadenas tipo char usando  "strncmp" en CCS, pero no logro que funcione correctamente alguien me podria decir cual es el error que estoy cometiendo...

Aqui esta mi codigo...
Código: [Seleccionar]
#include <18F4520.h>
#device PASS_STRINGS=IN_RAM
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOSTVREN
#use delay(clock=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)// RS232 Estándar

#include <stdlib.h>

#define LED PIN_D0
#define ON      output_high
#define OFF    output_low

int const maxLongBuffRX=42;
char bufferRX[maxLongBuffRX];
int indBufferRX=0x00;
char XCommand[maxLongBuffRX];
char flag_RptaCommand;
int i;

void Add_bufferRX(char c);
void SendATCommand( char *pCommandTX );

#int_rda
void serial_isr() {
  if(kbhit()){
    Add_bufferRX(getc());
  }
flag_RptaCommand = 1;
}

void Ini_buff_rec(void){
  int i;
  for(i=0;i<maxLongBuffRX;i++){
    bufferRX[i]=0x00;
  }
  indBufferRX=0x00;
}

void Add_bufferRX(char c){
  switch(c){
    case 0x0D:
      break;
    case 0x0A:
      break;
    default:
      bufferRX[indBufferRX++]=c;
  }
}

void SendATCommand( char *pCommandTX, char *pRXCommand ){
char *ptr;

Ini_buff_rec();
flag_RptaCommand = 0;

printf ("%s",pCommandTX);
putc('\r');

while ( flag_RptaCommand == 0);

//ptr=strstr(bufferRX,pRXCommand);

if(strncmp(bufferRX,pRXCommand,strlen(pRXCommand))== 0)
ON (LED);
else
OFF (LED);
}

void main(){

OFF(LED);
enable_interrupts(INT_RDA);
clear_interrupt(INT_RDA);
enable_interrupts(GLOBAL);

    SendATCommand("AT", "OK");

delay_ms(200);

while (TRUE);
}
« Última modificación: 13 de Julio de 2017, 11:57:17 por Medusa »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problemas de comparacion de cadenas
« Respuesta #1 en: 13 de Julio de 2017, 15:18:27 »
Dos problemas con tu codigo, en realidad es ilogico lo que estas haciendo, y una ves que te lo explique espero que te des cuenta del error que tenes.

Veamos que haces:

- Llamas a la funcion SendATCommand
- Limpias el buffer de recepcion
- Envias el comando "AT\r"

Y luego esperas por un flag que se ponga en 1.
Aca es donde comienza a fallar todo. Por que no recibis TODO completo en una interrupcion, recibis caracter a caracter. El problema esta en esto:

Código: C
  1. #int_rda
  2. void serial_isr() {
  3.   if(kbhit()){
  4.     Add_bufferRX(getc());
  5.   }
  6.         flag_RptaCommand = 1;
  7. }

Segun el codigo apenas entre a la interrupcion, reciba o no algo procede a poner en 1 el flag.
Al ponerlo en 1 solo recibiste 1 caracter y no todo el string! Este es el primer error

La funcion Add_bufferRX, tambien posee un error:

Código: C
  1. void Add_bufferRX(char c){
  2.   switch(c){
  3.     case 0x0D:
  4.       break;
  5.     case 0x0A:
  6.       break;
  7.     default:
  8.       bufferRX[indBufferRX++]=c;
  9.   }
  10. }

Un string en C se espera que termine con un caracter nulo, es decir si esperas un OK en tu array deberias tener 'O','K','\0', para poder compararlo, pero en ningun momento terminas ese el array en nulo, tal ves porque pensaste que al ponerlo a todos como caracter nulo iba a servir, lo cual es cierto, pero nos trae a otro problema.
En ningun momento indBufferRX vuelve a 0. Es decir si recibis "AT\r\nERROR\r\n" en tu array vas a tener "ATERROR" y asi hasta que se desborde el array y tengas un problema aun mayor.
Este es tu segundo error

Seguido recien alli comparamos. y vemos si se cumplio o no.

-------------------------------------------------------------

Mejoras
En ves de usar:

Código: C
  1. void Ini_buff_rec(void){
  2.   int i;
  3.   for(i=0;i<maxLongBuffRX;i++){
  4.     bufferRX[i]=0x00;
  5.   }
  6.   indBufferRX=0x00;
  7. }

Podes usar:

Código: C
  1. memset ( bufferRX, 0, sizeof bufferRX );
  2. indBufferRX = 0;

---------------------

Esto:

Código: C
  1. printf ("%s",pCommandTX);
  2.         putc('\r');

Se puede resumir en :

Código: C
  1. printf ("%s\r",pCommandTX);

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Re:Problemas de comparacion de cadenas
« Respuesta #2 en: 13 de Julio de 2017, 17:52:06 »
Hola Killerjc,

Sera posible detectar el  carácter nulo como fin de la trama recibida, digo esto por que no puedo usar \r o \n como fin de trama por que recibo respuestas con varios de estos y no siempre son iguales...


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problemas de comparacion de cadenas
« Respuesta #3 en: 13 de Julio de 2017, 18:01:37 »
El problema es que el carácter nulo es parte de como se expresa un string en C, pero el módulo no tiene ninguna obligación de hacerlo, usualmente el \r o \n es cuando finaliza la sentencia, así que usaría estos para determinar cuándo es que termino de recibir la trama.

Así que podrías hacer:
- poner a 0 todo el buffer.
- recibir, poner el flag a 1 cuando detecte \r o \n y poner a 0 el índice.
- en caso de llegar otro dato más distinto y el flag está activo quitas el flag por las dudas


 

anything