Autor Tema: si me espero, ... se para  (Leído 4056 veces)

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

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
RE: si me espero, ... se para
« Respuesta #15 en: 02 de Diciembre de 2004, 14:02:00 »
Hola a todos:

pacalaconcurso y TOniO

Perdonad mi torpeza.

Quiero aclarar que no es obstinacion, es solo mi deseo de aprender y comprender.

Repito una afirmacion que ya he relizado en otras ocasiones: En general, la mejor forma de hacer un programa que utilice la usart para recibir datos es mediante interrupciones. Creo que todos estamos deacuerdo en esto.

Pero....

Para probar lo que me decis he hecho el siguiente programita:

#INCLUDE <16F876.H>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=16000000)
#use RS232(BAUD=4800,RCV=PIN_C7,XMIT=PIN_C6,PARITY=N,BITS=8,ERRORS)

#define use_portb_lcd TRUE
#include <LCD.C>

#include <string.h>
#include <stdlib.h>


//VARIABLES GLOBALES

char buffer[73];
int1 recibido=0;


#int_rda      
void int_serie()
{
    gets(buffer);

    disable_interrupts(int_rda);
    recibido=1;
}

void main()
{
    char cadena[17];

    delay_ms(50);

    lcd_init();
    printf(lcd_putc,"fIniciando...");  
    delay_ms(500);
    lcd_putc("f");

    enable_interrupts(int_rda);
    enable_interrupts(global);

   while(1)
   {
       if(recibido==1)
       {
           strncpy(cadena,buffer,13);
           lcd_gotoxy(1,1);
           printf(lcd_putc,"C=%s",cadena);
           delay_ms(5000);  // este retardo es para simular que tardo algun tiempo
                                        // procesando la informacion y haciendo otras cosas
           recibido=0;
           enable_interrupts(int_rda);
      }
   }
}

No esta muy refinado, pero creo que es lo que vosotros sugeris.

Como yo me temia, si no utilizo ERRORS el programa se cuelga. Exactamente igual que me pasaba a mi antes.

Si ahora quito el retardo, el programa funciona bien.

El problema sigue estando en que, en el momento que desabilito la int., para poder procesar los datos, los car. que siguen llegando a la usart la saturan.

Por lo tanto, no se me colgaba a mi el programa porque perdia tiempo con el if(c==$), como habeis sugerido.

Me ha surgido otro problema derivado de utilizar gets, y es que, cuando desabilito la int. dejo por un tiempo de recibir car. por la usart, cuando vuelvo a habilitarla y utilizo gets, el inicio de la cadena leida nunca coincide con el inicio de una sentencia ($XXXXX), por lo tanto como no tengo una sentencia completa que empiece por $XXXXX, es imposible saber que sentencia es y donde estan los valores que interesan.
La unica manera de salvar el problema es utilizando getc(), hasta encontrar el caracter de inicio "$" , ahora si podria utilizar gets, y luego trocear y sacar los valores, pero es mas sencillo seguir con getc() y recoger los valores aqui mismo, puesto que entre getc() y getc() no tengo que hacer nada, solo poner los car. en sus variables correspondientes.

Sigo pensando que en este caso, utilizar int. no aporta ninguna ventaja (no me habeis razonado ninguna), es mas, creo que el procesador tiene que realizar mas trabajo utilizando int. que si se utiliza una llamada a una funcion.

Repasad el programa, corregidme si estoy equivocado (muy probable).

Modificare el programa con vuestras sugerencias y volveremos a probar.

Otra cosa, he estado trasteando con el GPS y no me permite cambiar nada de las sentencia NMEA que trasmite, solo puedo cambiar la velocidad y que el protocolo sea NMEA 0180 o NMEA 0183.


Saludos

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: si me espero, ... se para
« Respuesta #16 en: 02 de Diciembre de 2004, 15:29:00 »
dentro de la int rda mejor lees caracter a caractec (queda tiempo entre ellos para hacer otras cosas Sonrisa GiganteSonrisa GiganteSonrisa Gigante)

no pares la int, no hace falta.



a grandes rasgos puedes hacer esto...
para optimizar localiza en la int rda el caracter inicio de tu cadena... veras como asi te funciona sin el errors..


struct _comm
{
 int16 paquetes_rx; //numero de paquetes recibidos desde inicio
int16 paquetes_tx; //numero de paquetes transmitidos
int16 errores; //numero de errores de comunicacion
int1 nuevo_paquete; //hay un nuevo paquete a analizar
int8 cuenta_rx; //caracteres recibidos en el ultimo paquete
int8 cuenta_tx;
int8 datos_tx;
char trama[50];
int1 ocupado;//flag que indica si estamos procesando un paquete
char bite; //caracter dummy, para sacar del puerto serie
} comm;

/***********************************************************
* interrupcion de recepcion completa del paquete *
***********************************************************/
#int_TIMER1
TIMER1_isr()
{
disable_interrupts(int_TIMER1);
comm.ocupado=1;
comm.nuevo_paquete=1; // tenemos un paquete a la espera
++comm.paquetes_rx; // Paquetes recibidos
}

/***********************************************************
* interrupcion de recepcion completa del paquete *
***********************************************************/
#int_rda
void serial_isr()
{
comm.bite=getc(); //contenedor temporal
if (!comm.ocupado) //si estamos procesando un envió no se hace caso..
{
comm.trama[comm.cuenta_rx]=comm.bite;
comm.cuenta_rx++;
set_timer1(20000); // esperar el tiempo que deseemos como timeout
clear_interrupt(int_TIMER1); // limpiar el flag de overflow del timer1
enable_interrupts(int_TIMER1);
}
}


en tu main...

if (comm.nuevo_paquete)
{


// tienes un paquete esperando de "comm.cuenta_rx" bytes de tamaño
// en el array "comm.trama"
//haces lo que quieras con el

//liberar la recepcion
comm.ocupado=0;
comm.nuevo_paquete=0;
comm.cuenta_rx=0;
}

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: si me espero, ... se para
« Respuesta #17 en: 03 de Diciembre de 2004, 03:32:00 »
Supongo que si sabes cambiar de velocidad sabras calcular el checksum no?

De todos modos aquí va una inicialización:
Codigo:

        printf("$PSRF103,01,00,00,00*24
"Giño;
   printf("$PSRF103,02,00,00,00*27
"Giño;
   printf("$PSRF103,03,00,00,00*26
"Giño;
   printf("$PSRF103,05,00,00,00*20
"Giño;
   printf("$PSRF103,00,00,00,00*25
"Giño;
   printf("$PSRF103,04,00,05,00*24
"Giño;



Mi GPS no tiene el WPL, recuerda que para enviar comandos se debe poner CRLF y que el GPS seguramente también los envia RollEyesRollEyes
- T0ni0 -
30RCF112

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: si me espero, ... se para
« Respuesta #18 en: 03 de Diciembre de 2004, 03:43:00 »
Vaya gracia que les hace je je je
- T0ni0 -
30RCF112

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: si me espero, ... se para
« Respuesta #19 en: 03 de Diciembre de 2004, 13:14:00 »
Puedes hacerlo con getc o con gets es lo mismo, con gets perderas más tiempo en el main.

Como te comentaba normalmente los GPS envian el comando terminado con CR LF , la función gets() lee hasta CR por lo que despues de ella tendras q poner un getc para limpiar el lf (almenos así lo hago yo) ah! recuerda que buffer ahora no contiene el $.

En principio tendría q funcionar.
Puedes probar de entrar los comandos que te puse en el otro post teoricamente son universales.

RebotadoRebotadoRebotadoRebotadoRebotadoRebotado venga q estas cerca
- T0ni0 -
30RCF112

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
RE: si me espero, ... se para
« Respuesta #20 en: 05 de Diciembre de 2004, 12:43:00 »
Hola

Ok TOniO

Pero para que sirven esos comandos que le enviamos al GPS.

Te agradeceria un poco mas de informacion.

Gracias por todo. Sonrisa