Autor Tema: Detectar fin de transmisión  (Leído 7849 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Detectar fin de transmisión
« en: 20 de Septiembre de 2009, 09:05:23 »
Hoy he estado peleando con una comunicación RS485 y he tenido que utilizar un recurso que jamás había usado y me ha venido como anillo al dedo.
Supongo que muchos de vosotros ya lo conoceréis, pero lo voy a escribir por si es de utilidad a alguien que tenga el mismo problema que yo.

El RS485, además de las señales TX y RX, requiere de una señal más que indica en cada momento si estamos transmitiendo o recibiendo, para lo que se utiliza un pin adicional del PIC. En mi caso este pin va conectado a dos pines del MAX485 indicando con un 1 que estamos transmitiendo y con un 0 que estamos recibiendo.

El estado habitual de mi circuito es "escuchando", y sólo se pone esa señal a 1 cuando trasmite, volviendo a 0 una vez finalizada la comunicación.
Y aquí aparece el problema. Tras un printf en CCS, el programa descarga sobre la USART la labor de envío de los bytes, y continúa su ejecución, por lo que si bajamos la señal a 0 justo detrás del printf lo normal es que cortemos la transmisión antes de que haya terminado.

Pues bien, para esperar a que la transmisión termine he utilizado un bit de la USART llamado TRMT, en el registro TXSTA (estoy trabajando con un 18F). Este bit permanece a 0 mientras haya una transmisión pendiente.

Mi código por tanto tiene estas definiciones al principio:
#define TXSTA  0xFAC
#bit TRMT =  TXSTA.1

Y luego, cuando transmito me limito a lo siguiente:
      RS485_emite();
      printf ("Hola mundo");
      while (!TRMT);
      RS485_recibe();

Bueno, pues como veis es una chorradita, pero me ha hecho perder toda la mañana, así que se ha merecido al menos este post.

(*) Las funciones RS485_emite y RS485_recibe se limitan a poner a 1 y a 0 el pin que antes describí.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Detectar fin de transmisión
« Respuesta #1 en: 20 de Septiembre de 2009, 11:27:59 »
Hola.

Cuando trabaje con el RS485 tuve problemas algo similares, los cuales se solucionaron dejando un delay_ms(2) luego del final de la transmisión. Muy elegante solución maestro.

Saludos
El papel lo aguanta todo

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Detectar fin de transmisión
« Respuesta #2 en: 20 de Septiembre de 2009, 14:11:31 »
Lo mismo nos pasó a Akenafab y a mi con los sn75176b.

La solución fue similar a la que comenta MLO, colocar un delay, pero nosotros calculamos el tiempo que tarda un byte en enviarse por rs232...

Velocidad 9600bps = 960B/s

Dividido en 10 por el bit start, 8 bits de datos y bit stop. La velocidad por un byte es entonces la inversa: 1.0416us/B.

El código nos quedó así:

Código: [Seleccionar]
output_high(TX_ENABLE); //Habilita terminal TX para envío
//Envía el paquete 3 veces para redundancia
for(j=0; j<3; ++j)
   {
   for(i=0; i<8; ++i)
      {
      putc(com_tx[i]);
      delay_us(1042); //En lo que se envía el byte por serial
      }
   }
output_low(TX_ENABLE);  //Deshabilita para recibir

Cabe señalar que putc nunca envía un byte si no se ha terminado de enviar el anterior, pero al enviar un último byte sí es necesario agregar el delay antes de desactivar TX en el módulo rs485.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Detectar fin de transmisión
« Respuesta #3 en: 20 de Septiembre de 2009, 14:15:13 »
Código: CSS
  1. /** \brief Envía un mensaje por el Canal RS485 (vía Canal Serie USART)
  2.   *
  3.   * Envia un mensaje conmutando el Canal serie hacia el Canal RS485. Restaura las comunicaciones estandar tras enviar el mensaje.
  4.   *
  5.   * \param psMessage Puntero a un string con el comando a enviar.
  6.   *
  7.   * \return void
  8.   *
  9.   */
  10. void USART_send_message_485(char* psMessage){
  11.  
  12.    open_485_for_transmit();
  13.    delay_25();
  14.    printf("%s\r\n",psMessage);
  15.    delay_25();
  16.    close_485_after_process();
  17. }
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Detectar fin de transmisión
« Respuesta #4 en: 20 de Septiembre de 2009, 14:15:56 »
Santiago, en tu caso podrías poner el delay fuera del bucle, para sólo esperar cuando se transmita el último byte, puesto que los anteriores ya van siguiendo su ritmo a medida que la usart se va quedando libre.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Detectar fin de transmisión
« Respuesta #5 en: 20 de Septiembre de 2009, 14:27:05 »
Sip. Aunque a final de cuentas es igual creo yo... un ejemplo de envío de 2 bytes...

- Poniendo el delay_us después de cada putc
  + Putc pone el 1er byte en TXREG
  + Pasa el delay y TXREG ya estará vacío
  + Putc pone el 2do byte en TXREG
  + Pasa el delay y TXREG ya estará vacío
  Tiempo total: 2 delays_us (justamente equivalentes a envío de 2 bytes)

- Poniendo el delay_us después de que los dos bytes se han enviado
  + Putc pone el 1er byte en TXREG
  + Putc espera a que se vacíe TXREG (el 1er byte todavía se está enviando)
  + Putc pone el 2do byte en TXREG
  + Pasa el delay_us del final (tarda un tiempo equivalente a 1 byte)
  Tiempo total: 1 periodo de envío de 1 byte más un delay_us

Ambas tardan casi lo mismo... aunque poniendo el delay_us al terminar el envío de todo byte nos ahorra unos cuantos nanosegundos por la precisión de los delays internos del primer método ;-)

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Detectar fin de transmisión
« Respuesta #6 en: 20 de Septiembre de 2009, 14:35:21 »
Otra posible solución es utilizar la #INT_TBE que nos salta cuando el buffer de transmisión de la USART se queda vacío.

Yo nunca la he utilizado pero sería similar a la #INT_EEPROM que si uso para saber cuando ha terminado de escribir la EEPROM y así no uso delay aproximado sino que se cuando puedo continuar.

Edito: Esto es algo similar a lo que haces, Manolo, con el bit TRMT

« Última modificación: 20 de Septiembre de 2009, 14:37:35 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Detectar fin de transmisión
« Respuesta #7 en: 20 de Septiembre de 2009, 15:07:14 »
Antes de probar con el método del bit, he estado peleando con esa interrupción, la #INT_TBE. Seguro que lo he hecho mal porque no lo he conseguido.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Detectar fin de transmisión
« Respuesta #8 en: 20 de Septiembre de 2009, 21:17:57 »
Creo yo que la mejor alternativa si es checar el estado del registro, aunque, cuando las lineas de transmisión son muy largas, puede haber cierto "retraso" en relación  al dato recibido, por lo que habría que verificarlo experimentalmente.

Saludos
El papel lo aguanta todo

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: Detectar fin de transmisión
« Respuesta #9 en: 20 de Septiembre de 2009, 21:36:20 »
Paso lo que comenta Santiago

Y le mandaba muchos mensajes xD porque a usar putc este espera a que termine la transmision , sin embargo , se perdía un byte .Recuerdo hasta enviarle varias imagenes con los tiempos de transmision y se apreciaba el byte perdido , en si el tiempo de este cuando poniamoso en low la habilitacion de transmision.

Con el retardo fuera del ciclo no funcionaba correctamente.

Yo le insistia en que habia un bit xD porque lo usaba en asm ,luego me confundi mucho xD y lo dejamos con el retardo.
Por las prisas y demas problemas que daba con el compilador ya no probe bien el bit,me confundo con el TSR.

Con el retardo quedo solucionado.

Probare nuevamente con el bit y les cuento lo que ocurre.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Detectar fin de transmisión
« Respuesta #10 en: 20 de Septiembre de 2009, 21:40:46 »
Checa con el bit TXIF de la interrupción, yo lo busqué hace rato pero no lo encontré.

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: Detectar fin de transmisión
« Respuesta #11 en: 20 de Septiembre de 2009, 21:54:37 »
Lo acabo de revisar y ya se donde esta la confusion xD

Con TXIF y TRMT .

Primero se carga el TXREG y de ahi lo `pasa al TSR .

putc revisa el TXIF

Cuando termina de enviar el ultimo bit por el TSR se pone a 0 y el byte ya ha salido del micro.

Saludos!
« Última modificación: 20 de Septiembre de 2009, 22:00:17 por AKENAFAB »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Detectar fin de transmisión
« Respuesta #12 en: 21 de Septiembre de 2009, 00:07:33 »
Muchachos por ahi estoy equivocandome, o no estaban al tanto pero exìste en el CCS un modificador del RS-232 llamado ENABLE que permite configurar el pin que se utiliza en los IC's que lo requieren(gralmente para RS485).

Este comando(ENABLE) permite seleccionar el bit del uC al cual conectamos nuestro integrado(en mi caso sn75176) y asi utomaticamente el CCS lo configure antes de enviar una trama y luego de terminado su envio...

Código: [Seleccionar]
ENABLE=pin
 The specified pin will be high during transmit.  This may be used to enable 485 transmit.

 
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Detectar fin de transmisión
« Respuesta #13 en: 21 de Septiembre de 2009, 00:12:27 »
Otro problema que tuve usando el SN75176 fue que si conectaba el pin del uC a ambos pines, !RE y DE, tenia problemas para recibir la trama.

Revisando a fondo el datasheet del SN75176 descubrì que lo correcto es conectar permanentemente !RE a GND y controlar sòlo el pin DE desde el uC.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Detectar fin de transmisión
« Respuesta #14 en: 21 de Septiembre de 2009, 02:54:49 »
San Bruno, ¿porqué no lo dijiste antes?  :D

Eres grande, tengo que probar eso.