Autor Tema: Se me cuelga la comunicacion serie...  (Leído 2368 veces)

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

Desconectado __ERoS__

  • PIC10
  • *
  • Mensajes: 22
Se me cuelga la comunicacion serie...
« 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

« Última modificación: 26 de Junio de 2007, 09:09:26 por __ERoS__ »

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Se me cuelga la comunicacion serie...
« Respuesta #1 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
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: Se me cuelga la comunicacion serie...
« Respuesta #2 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.

Desconectado __ERoS__

  • PIC10
  • *
  • Mensajes: 22
Re: Se me cuelga la comunicacion serie...
« Respuesta #3 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

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: Se me cuelga la comunicacion serie...
« Respuesta #4 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.

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Se me cuelga la comunicacion serie...
« Respuesta #5 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
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado __ERoS__

  • PIC10
  • *
  • Mensajes: 22
Re: Se me cuelga la comunicacion serie...
« Respuesta #6 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?
« Última modificación: 27 de Junio de 2007, 08:23:46 por __ERoS__ »

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Se me cuelga la comunicacion serie...
« Respuesta #7 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> ?
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado dhmejia

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 260
Re: Se me cuelga la comunicacion serie...
« Respuesta #8 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.
Pereira - Colombia

Desconectado __ERoS__

  • PIC10
  • *
  • Mensajes: 22
Re: Se me cuelga la comunicacion serie...
« Respuesta #9 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