Autor Tema: Fallo al leer con USART por software.  (Leído 2872 veces)

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

Desconectado wannaky

  • PIC12
  • **
  • Mensajes: 92
Fallo al leer con USART por software.
« en: 05 de Noviembre de 2011, 15:37:23 »
Buenas, estoy liado con un proyecto y necesito utilizar 2 USART en un 16F877, una la propia por HW y otra por SW aprovechando la interrupción externa.
Con la propia por HW comunico con un PC, y con la otra por SW comunico con otro PIC 16F877.

Envío tramas de datos de distintas longitudes, y introduzco el carácter 'Z' como final de trama, de forma que hasta que no se detecta que el carácter recibido es una 'Z', no se activa el flag correspondiente de que el string está completo...

Os comento lo que me pasa:

Este es el código que se ejecuta cuando llega un string por el puerto serie por HW... y funciona correctamente

Código: [Seleccionar]
#int_RDA // Recepción de datos del PC
void RDA_isr()
{
   dato_rx=fgetc(PUERTO_PC); //Leo el dato recibido

   if(dato_rx=='Z')  //miro si el dato recibido es una 'Z' de final de trama
   {
      cadena_rx[incremento_cadena]=dato_rx;   //Almaceno el dato en un string
      flag_pc=1;     //Activo flag indicando que la trama está completa
      incremento_cadena=0;
   }
   else
   {
      cadena_rx[incremento_cadena]=dato_rx;  //Almaceno el dato en el string
      incremento_cadena++;  //Incremento el indice del string
   }
}

y este es el que se ejecuta cuando llega un string por el puerto serie por SW... NO FUNCIONA CORRECTAMENTE!!!  :5] :5] :5]  no detecta el final de trama...

Código: [Seleccionar]
#int_EXT //recepción de datos del PIC
void ext_isr()
{
   if (kbhit(PUERTO_RF))
   {
      dato_rx=fgetc(PUERTO_RF);

      if(dato_rx=='Z')  //mira si el dato recibido es una 'Z' de final de trama
      {
         cadena_rx[incremento_cadena]=dato_rx;
         flag_rf=1;
         incremento_cadena=0;
      }
      else
      {
         cadena_rx[incremento_cadena]=dato_rx;
         incremento_cadena++;
      }
   }
}

como podéis ver, los dos códigos son casi iguales, pero el de la USART por software no funciona, y el otro si...

He probado a recibir con este código en el que le fijo el número de datos que quiero recibir, y si que funciona...

Código: [Seleccionar]
#int_EXT //Recepción de datos del PIC
void ext_isr()
{
   if (kbhit(PUERTO_RF))
   {
      dato_rx=fgetc(PUERTO_RF);
      cadena_rx[incremento_cadena]=dato_rx;
      incremento_cadena++;
      if(incremento_cadena==6)
      {
         flag_rf=1;
         incremento_cadena=0;
      }
   }
}
pero no me interesa tener que fijar el número de datos que espero recibir.

Mi duda es la siguiente: una vez configuradas las dos USART, no tendrían que funcionar igual?!?!?!?! la lectura no se hace igual?!?!?! :huh: :huh: :huh:

esta es la configuración de los puertos RS-232 que tengo...

Código: [Seleccionar]
#use fast_io(B)
#use fast_io(C)                    

#use RS232 (baud=9600, bits=8, parity=N, xmit=PIN_C6, rcv=PIN_C7,STREAM=PUERTO_PC)
#use RS232 (baud=9600, xmit=PIN_B1, rcv=PIN_B0,STREAM=PUERTO_RF )


a ver si me podéis echar una mano y me aclaro con esto...

Gracias y un saludo...
« Última modificación: 05 de Noviembre de 2011, 17:05:56 por wannaky »

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Fallo al leer con USART por software.
« Respuesta #1 en: 05 de Noviembre de 2011, 18:50:12 »
A que velocidad trabaja el PIC, o que cristal utilizas??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Fallo al leer con USART por software.
« Respuesta #2 en: 05 de Noviembre de 2011, 19:14:50 »
porque no haces la prueba haciendo un echo con tu puerto por software, para saber que estas recibiendo y ver en que dato se queda
"Nada es imposible, no si puedes imaginarlo"

Desconectado wannaky

  • PIC12
  • **
  • Mensajes: 92
Re: Fallo al leer con USART por software.
« Respuesta #3 en: 06 de Noviembre de 2011, 07:37:49 »
A que velocidad trabaja el PIC, o que cristal utilizas??

esta es la configuración que tengo...
Código: [Seleccionar]
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
#use delay(clock=4000000)
#include "lcd.c"

#use fast_io(B)
#use fast_io(C)                   

#use RS232 (baud=9600, bits=8, parity=N, xmit=PIN_C6, rcv=PIN_C7,STREAM=PUERTO_PC)
#use RS232 (baud=9600, xmit=PIN_B1, rcv=PIN_B0,STREAM=PUERTO_RF )

lo que me extraña es que si le pongo que reciba 6 caracteres antes de activar el flag, funciona correctamente, y me muestra exactamente el string que le envío, pero si le digo que reciba hasta encontrar una 'Z', no me lo hace bien... y lo único que cambio es la condición del if(...)

digo yo: es posible que la forma de leer por la USART por SW sea distinta que por la USART por HW ?!?!?! :huh: :huh: :huh:  esque es lo único que se me ocurre

saludos

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Fallo al leer con USART por software.
« Respuesta #4 en: 06 de Noviembre de 2011, 15:12:43 »
Cuando hice rutinas en assembler para leer un puerto por software, use un cristal de 4 Mhz y no entendia porque me fallaba.
El problema es que ese oscilador (debe ser un cristal) es muy dificil que pueda crear los timing apropiados para la comunicacion.
Al no poder crear los timings correctos, se producen tiempos de bits mas largos o mas cortos que los que necesitas para establecer una comunicacion correcta.
Cuando se hace una comunicacion por software, se intenta muestrear el bit a la mitad de su tiempo de existencia, por lo tanto si ese bit se dezplaza, estamos desincronizando la comunicacion.

Si pruebas a bajar la comunicacion a 4800 BPS, probablemente podras certificar esto que digo, porque deberia funcionarte bien.
No olvides que el if agrega tiempo y la comparacion tambien.

En mi caso la mejor solucion de compromiso que tuve es cambiar el cristal por uno de 3.6864 Mhz, que es el recomendado por la hoja de datos de Microchip para obtener el minimo error aceptable de bit.
Para darte una idea, con ese cristal luego llegue a comunicar por software a 38400 bps. :mrgreen: :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Fallo al leer con USART por software.
« Respuesta #5 en: 06 de Noviembre de 2011, 15:34:22 »
y si en lugar de leer byte por byte lees las cadena completa usando fgets(). solo tienes que enviar en tu cadena tu salto de linea y retorno de carro
"Nada es imposible, no si puedes imaginarlo"

Desconectado wannaky

  • PIC12
  • **
  • Mensajes: 92
Re: Fallo al leer con USART por software.
« Respuesta #6 en: 06 de Noviembre de 2011, 19:56:36 »
Ok MGLSOFT, con 9600bps, no se enteraba bien de lo que recibía, he probado de bajar la velocidad a 1200bps y ahora si que recibo bien los datos. Lo que no pensaba yo es que 9600bps fuese una velocidad tan alta para que el pic....  :shock: :shock: :shock: le tendré que echar un ojo mas a fondo al datasheet...

rivale, el problema que tengo si utilizo fgets(), es que la información que envío desde un PC no tiene salto de linea ni retorno de carro, entre los PIC's si que los incluyo, pero del PC al PIC no...

mañana seguiré con ello, pero ahora a dormir que ya es tarde aquí...  :( :( :(

gracias y un saludo...

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Fallo al leer con USART por software.
« Respuesta #7 en: 06 de Noviembre de 2011, 20:18:29 »
Ok MGLSOFT, con 9600bps, no se enteraba bien de lo que recibía, he probado de bajar la velocidad a 1200bps y ahora si que recibo bien los datos. Lo que no pensaba yo es que 9600bps fuese una velocidad tan alta para que el pic....  :shock: :shock: :shock: le tendré que echar un ojo mas a fondo al datasheet...



  No es que sea una velocidad alta. Lo que ocurre ya te lo comentó muy bien MGLSOFT.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Fallo al leer con USART por software.
« Respuesta #8 en: 06 de Noviembre de 2011, 21:39:23 »
ademas de eso si hay una interrupcion en medio de la transferencia por software esta hace un timing mayor, por lo cual tambien se desincroniza

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Fallo al leer con USART por software.
« Respuesta #9 en: 06 de Noviembre de 2011, 21:50:15 »
con que envias tus datos desde la pc, porque no puedes poner el salto de linea?
"Nada es imposible, no si puedes imaginarlo"

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Fallo al leer con USART por software.
« Respuesta #10 en: 06 de Noviembre de 2011, 21:52:16 »
Para que veas de que hablaba, y de la perfección que tiene ese cristal, aquí te pego la tabla de cristales y su comportamiento segun las diferentes velocidades.
Según la norma en RS232, no debería haber mas de 1,5 a 2 % de error de tiempo de bit.
Compara el cristal de 3,6864 para que veas la diferencia frente a los demás...

« Última modificación: 06 de Noviembre de 2011, 21:54:47 por MGLSOFT »
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado wannaky

  • PIC12
  • **
  • Mensajes: 92
Re: Fallo al leer con USART por software.
« Respuesta #11 en: 07 de Noviembre de 2011, 09:58:51 »
con que envias tus datos desde la pc, porque no puedes poner el salto de linea?
A ver... se trata de visualizar a distancia la temperatura,tensión y corriente de unos panales solares que estan instalados en una planta.
En cada panel (o conjunto de paneles) tengo una placa que hace las lecturas y las envía de forma inalámbrica (por XBEE) a un controladora, que es la que está conectada a un PC por RS-232.

Pensé que la forma mas sencilla era hacer una aplicación en PHP la cual solicitase la información periodicamente a la placa controladora, pero en PHP no sé enviar ni recibir por un COM, de forma que utilizo un scrip programado en python que encontré (no lo he hecho yo...), y lo que hago es enviarle la cadena que quiero transmitir por el COM, pero  solo envío los caracteres, sin saltos de linea ni retornos de carro. Total, que ese es el motivo por el que digo que no puedo poner saltos del lieas... :x :x :x   ... a grandes problemas, grandes soluciones... jejejeejee...

MGLSOFT muy buena esa info, la verdad es que no la había visto... gracias, esta tarde probaré a ver que tal... ;-) ;-)

saludos, y os comento los avances...