TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: __ERoS__ en 26 de Junio de 2007, 09:01:13

Título: Se me cuelga la comunicacion serie...
Publicado por: __ERoS__ en 26 de Junio de 2007, 09:01:13
Hola a todos

Queria comentaros un problemilla que tengo usando un 18F4550 y comunicacion serie con el PC. Uso max232 con los esquemas que he visto por ahi, y programo en CCS.

Bien, mi programa lee caracteres del puerto serie mediante la interrupcion rda (con getc) hasta que lee un '?', en ese momento lo toma como que se acabo la orden y me devuelve la orden leida al completo (hago esto por ahora para ver que me ha llegado todo bien). Uso el SIOW del compilador CCS para monitorear, y a veces se me queda colgada la comunicacion, y me fijo que el bit TXD del SIOW esta encendido como si estuviera presionando una tecla seguido, y tengo que resetear el PIC.

Alguien sabe una posible causa?

Comento tb que veo que las lineas DSR y CTS a veces se encienden y no se que significan ni si deberian hacerlo

Saludos y gracias de antemano

PD: si necesitais algun trozo del codigo, los fuses o algo los copio en un momento

Título: Re: Se me cuelga la comunicacion serie...
Publicado por: jfh900 en 26 de Junio de 2007, 09:47:22
Seria interesante que postearas todo el código para ver por donde puede andar el problema.

Un saludo
Título: Re: Se me cuelga la comunicacion serie...
Publicado por: Azicuetano en 26 de Junio de 2007, 10:41:36
Se puede dar el caso de que suceda una colisión en tú comunicación? Si esto sucediera pasaría exáctamente lo que comentas.

Un saludo desde ALicante.
Título: Re: Se me cuelga la comunicacion serie...
Publicado por: __ERoS__ en 26 de Junio de 2007, 11:21:31
Pues todo el codigo es mucho, os pego lo importante, si hay algo que creeis que debo poner avisarme:

Primero de todo los fuses y lo de la comunicacion:
#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOWRT,NOLVP,NODEBUG,USBDIV,CPUDIV1,PLL2,VREGEN,NOPBADEN
#use delay(clock=48000000)
// el clock que tendremos a la entrada del CPU, en este caso 48MHZ
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)


Ahora la interrupcion rda (igual os parece larga, pero cuando no se queda colgada va bien y no pierdo caracteres)

#int_rda
void serial_isr() {

   /* Interrupcion de recepcion por puerto serie */

  int i;

   if(kbhit())          //Si hay algo pendiente de recibir
   {
      gets(cmd);        //Leo el comando
      tamanhoOrden=strlen(cmd);

      if(tamanhoOrden>=longitudComando)
      {
         printf("CEOF%c",finRespuesta);
         tamanhoOrden=0;
         return;
      }
      for(i=0;i<=tamanhoOrden;i++)  //Almaceno el comando en el buffer
      {
         bufferRecepcion[siguienteIN]=cmd;
         siguienteIN++;

         if(siguienteIN==longitudBuffer)
           siguienteIN=0;
      }
      tamanhoOrden=0;
   }
}


Esta funcion saca un comando del buffer y lo almacena en la variable comando:

void obtenerComando()
{
   /* Saca un comando del buffer y actualiza el puntero siguienteOUT */

  int i;

   for(i=0;bufferRecepcion[siguienteOUT]!=finOrden;i++)
   {
      comando=bufferRecepcion[siguienteOUT];
      siguienteOUT++;

      if(siguienteOUT==longitudBuffer)
         siguienteOUT=0;
   }
   comando=finOrden;
   siguienteOUT=(siguienteOUT+1) % longitudBuffer;

}

Segun el comando recibido hace lo que sea: (por ahora no hacen nada util)

void procesarComando()
{
   /* Ejecuta la accion asociada a un comando */

   if(comando[0]=='c' && comando[1]=='o' && comando[2]=='n')
   {
      //comando de conexion: con
      printf("ok%c",finRespuesta);
      return;
   }
   if(comando[0]=='f' && comando[1]=='i' && comando[2]=='n')
   {
      //comando de desconexion: fin
      seguir=0;
      printf("ok%c",finRespuesta);
      return;
   }
   //si recibimos un comando no conocido
   printf("CMD_UNKOWN%c",finRespuesta);
}

Y el main en bucle:

while(seguir)
{
      if(comRecibidoSerie)  //Recibimos comando por RS232 //hay un define asi: #define comRecibidoSerie siguienteIN!=siguienteOUT   //Flag que indica comando recibido por serie

      {
         obtenerComando();       //Obtenemos un comando del buffer
         procesarComando();      //Lo procesamos
      }
   }

El funcionamiento es correcto, pero tarde o temprano se termina colgando (a veces tarda mucho). Cuando se cuelga (luz TXD del SIOW encendida seguida) lo que hago es cerrar el SIOW y volverlo a arrancar, en ese momento puedo seguir metiendo caracteres donde estaba....curioso

En cuanto a una colision, pues no se porque podria ser...no hago nada raro

Saludos y muchas gracias
Título: Re: Se me cuelga la comunicacion serie...
Publicado por: Azicuetano en 26 de Junio de 2007, 20:14:00
Prueba a inicializar la comunicación así:

Código: [Seleccionar]
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)
A ver que tal funciona.


Un saludo desde Alicante.
Título: Re: Se me cuelga la comunicacion serie...
Publicado por: jfh900 en 26 de Junio de 2007, 21:16:52
A mi me queda una duda: tienes dentro de la subrutina de interrupción un return, como el CCS se encarga de gestionar toda la interrupciín (salvar el contexto y retornar de interrupción [iret]) no se si saldria correctamente de la interrupción. Por que no pones un else:

Código: C
  1. if(tamanhoOrden>=longitudComando)
  2.       {
  3.          printf("CEOF%c",finRespuesta);
  4.          tamanhoOrden=0;
  5. //         return;      --------> Eliminada
  6.       }
  7.       else  //---------> Anadido
  8.       {
  9.       for(i=0;i<=tamanhoOrden;i++)  //Almaceno el comando en el buffer
  10.       {
  11.          bufferRecepcion[siguienteIN]=cmd;
  12.          siguienteIN++;
  13.  
  14.          if(siguienteIN==longitudBuffer)
  15.            siguienteIN=0;
  16.       }
  17.       tamanhoOrden=0;
  18.       }

Saludos
Título: Re: Se me cuelga la comunicacion serie...
Publicado por: __ERoS__ en 27 de Junio de 2007, 08:11:15
Primero de todo gracias por contestarme.

Vamos por partes:

Azicuetano : he probado lo que dices y me pasa lo mismo.....

jfh900 : lo que dices no lo acabo de entender, pero voi a probarlo y te cuento, pero de todas maneras, cuando le mando una orden muy grande recibo correctamente CEOF y puedo seguir mandandole ordenes. El cuelgue es algo aleatorio digamos.....

Saludos

PD: ya he probado eso y me pasa igual, con los return.

Lo que puedo decir, es si me comunico por serie en Linux con un programa que tengo hecho, eso no me ha pasado nunca aun....es curioso.....me pasa en windows con el SIOW y el hyperterminal. Aun asi, alguien sabe si se deberian encender las luces del SIOW de DSR y CTS en algun caso? O que significan al menos? Es que yo entiendo que si uso solo 3 pines del puerto serie....los demas daria igual no?
Título: Re: Se me cuelga la comunicacion serie...
Publicado por: maunix en 27 de Junio de 2007, 22:21:30
Suponiendo que tu hardware está ok... el cts y dtr no solucionará tu problema.

has probado revisar el estado del bit RCSTA<OERR> ?
Título: Re: Se me cuelga la comunicacion serie...
Publicado por: dhmejia en 28 de Junio de 2007, 11:04:04
Veo que estas usando gets(cmd) para recibir los datos por el puerto serie, el problema con esta instrucción es que se queda esperando hasta que reciba un enter (número 13 en decimal), si la trama no termina con 'enter' el programa se queda en un ciclo infinito de espera.

Intenta con los siguiente:

Código: C
  1. //Declarar primero cmd de la longitud máxima que esperas recibir serial
  2.  
  3. #int_rda
  4. void serial_isr() {
  5.     if(kbhit()){
  6.         cmd[a] = getc();
  7.         if(cmd[a] == '?'){
  8.             //Aca el codigo
  9.             //El dato queda en cmd, la longitud en a
  10.             //despues de procesar se debe borrar a para recibir una nueva trama de datos
  11.         }
  12.         else{
  13.             a++;
  14.         }
  15.     }
  16. }

La idea es no usar gets() para no depender del caracter enter, además si el código despues de recibida la trama de datos es muy largo te recomiendo que cuando termines de recibir actives una bandera y proceses el dato recibido fuera de la rutina de interrupcion.

saludos.
Título: Re: Se me cuelga la comunicacion serie...
Publicado por: __ERoS__ en 28 de Junio de 2007, 19:15:20
Weno

Gracias a todos por responder

Al final, a pesar de lo comentado por dhmejia he usado gets y he acabado las tramas con \r, y en mi programa en linux hice un bucle inifnito para probar enviando seguido datos y recibiendo y todo parece funcionar bien. Tb probe con el minicom a meterle datos manualmente y 0 problemas tb

Me he ido a windows y probe el SIOW, y de nuevo el mismo problema, pero como donde tiene que funcionar es en linux voi a dejar de preocuparme por eso

Saludos a todos