No se puede recibir respuesta de SIM900

0

Estoy intentando comunicarme con SIM900 con PIC18F2520 . Puedo enviar comandos AT usando UART pero también quiero recibir su respuesta como OK o ERROR .

A continuación se muestra el código para la interrupción de RX

#pragma code rx_interrupt = 0x8
void rx_int(void)
{
  _asm goto rx_handler _endasm
}
#pragma code
#pragma interrupt rx_handler
void rx_handler(void)
{
  while (!DataRdyUSART());   //if data is ready to receive
  for(k=0;k<=20;k++)
  {

    Rx[k] = getcUSART();    //read a byte from UART

  }
  UARTSend("We have read everything");   //I have a put a breakpoint here
  if(strstr(Rx,"OK") != NULL)
  {
    UARTSend("OK received"\n);
  }

   PIR1bits.RCIF = 0;   //Clear the interrupt flag 

}

Arriba está el código que estoy usando para recibir datos de SIM900. En el modo de depuración, envío UARTSend("AT\r"); . He puesto un punto de interrupción en UARTSend("We have read everything"); . En esta línea, busco el búfer Rx en la variable, pero no tiene OK , en cambio tiene pocos caracteres aleatorios, mientras que en el terminal obtengo la respuesta adecuada.

Entonces, cómo leer la respuesta de SIM900. El enfoque lo estoy utilizando correctamente o no. Por favor, ayuda.

    
pregunta S Andrew

2 respuestas

1

Varios errores aquí:

  • Esperando que un byte entre dentro de la interrupción de RX; el hecho de que estés allí prácticamente te dice que ha llegado un byte.

  • Leer 20 bytes cuando todo lo que tienes es una notificación de que ha llegado un byte.

  • Suponiendo que una respuesta del módulo será exactamente 20 bytes. Puede ver en su terminal que 'OK' + se devuelve un montón de CRLFs cuando envía 'AT', ¿por qué leer 20 bytes?

  • Parece que estás usando las mismas líneas UART para hablar con el SIM900 y tu PC. Manera de causar confusión.

  • Está enviando datos dentro del ISR a la PC. Los ISR están diseñados para ejecutarse rápidamente y regresar.

Debe usar los tiempos de espera seleccionados cuidadosamente para saber cuándo el módulo ha terminado de hablarle. Su manejador debe verse así:

void rx_handler(void) {
  Rx[k++] = getcUSART(); //read a byte from UART
  lastRead = 0;
  PIR1bits.RCIF = 0; //Clear the interrupt flag
}

Supongo que k es una variable de alcance de archivo y se declara volátil. Ya que está usando un PIC y, por lo tanto, no tiene el Arduino millis() o ARM SysTicks disponibles, puede implementar algo similar con un periférico Timer o usar demoras como una solución alternativa a corto plazo.

Declara esto:

  #define TIMEOUT 100
  volatile static unsigned int lastRead;

Tu main() debería verse así:

  Uart_Send("AT\r");
  while (lastRead < TIMEOUT){
    __delay_ms(1);
    lastRead++;
  }
  if (strstr(Rx, "OK") != NULL){
    while (1){
      LATBbits.RB0 = 0; // blink quickly
      __delay_ms(500);
      LATBbits.RB0 = 1;
      __delay_ms(500);
    }
  }
  else {
    while (1) {
      LATBbits.RB0 = 0; // blink slowly
      __delay_ms(1500);
      LATBbits.RB0 = 1;
      __delay_ms(1500);
    }
  }

Configure RB0 como pin de salida y conecte un LED. He utilizado las tasas de parpadeo del LED para indicar el éxito o el fracaso de su comando. Si desea leer la respuesta real, obtenga un LCD o configure un puerto UART de software para hablar con la PC; IIRC, las bibliotecas periféricas incluyen una biblioteca Soft_Uart .

Comprende que este código es solo para probar si puedes hablar con el módulo. Para cualquier uso interesante, deberá implementar un búfer circular / circular y Software UART, si también desea hablar con su PC. Le sugiero que busque una biblioteca SIM900 existente y que intente trasladar las funciones relevantes, utilizadas para enviar comandos y analizar respuestas, a C18 C.

    
respondido por el TisteAndii
0

el problema principal es que 20 números de caracteres no se reciben al mismo tiempo. Por lo tanto, debe usar while (!DataRdyUSART()); antes de cada lectura.

while (!DataRdyUSART());   //if data is ready to receive
  for(k=0;k<=20;k++)
  {
    while (!DataRdyUSART());   //if data is ready to receive
    Rx[k] = getcUSART();    //read a byte from UART
  }

Ahora el siguiente problema será con el número 20. Todas las respuestas no tendrán una longitud de 20. Por lo tanto, intente leer hasta que reciba o

Le sugiero que escriba estos códigos en main, en lugar de ISR. Simplemente establezca una marca en ISR y verifique el estado de la bandera en el código principal. Pero esto solo depende del algoritmo que necesita implementar, pero asegúrese de que no se produzcan múltiples interrupciones dentro de la ejecución del ISR anterior

    
respondido por el Sanu - Open Maker

Lea otras preguntas en las etiquetas