Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola!!
Estoy escribiendo el código para que un Atmega8 me envía un paquete de datos por puerto serie, utilizando el USART. Se compone de:
byte de inicio => 0xFE
byte de ID => 0x01
byte de comando => 0x1
byte de datos => 0x00
byte de fin => 0xFF
No está muy depurada la estructura del datagrama, se aceptan sugerencias pero en principio va así, para ir probando si funciona. La idea es que algunos bytes se conviertan en bits.
El caso es que todos los bytes me llegan correctamente al ordenador de destino menos los 0x00 del byte de datos y no sé si será por culpa del Atmega8 o por el software del PC, pero el caso es los bytes de 0 me los ignora y ya he probado a leer la entrada del PC de todas las maneras que me permite el lenguaje (C#).
Para enviar el dato desde el USART, una vez configurado pongo
out UDR, aux ; aux vale 0x00
¿Alguien sabe por qué puede ser?
Muchas gracias!!!!
Conociendo los Atmel, lo primero que te debo prenguntar es: que reloj usas (interno o externo), que frecuencia, que baudrate, y que pongas el código si es posible.
Por mis conocimientos, dudo que el problema sea exactamente de código (ojo con el UDR y con sobreescribirlo). Más bien parece el clásico ejemplo de uso del reloj RC interno sin calibrar, que tiene una precisión muy mala. Pero puedo equivocarme, ojo.
A mi me suena mas a problema en el lado PC ya que los caracteres ASCII por debajo del 32 (espacio en blanco) suelen ser problematicos dependiendo del tipo de variables que uses.
Para comprobarlo yo que tu ponia un "contador" de bytes a ver si recibes 4 o 5 veces (enviando el paquete que indicas)
Si te salen 4 = error de transmisión.
Si te salen 5 = error de conversión de datos en PC.
furri.
Por cierto, y para 'arreglar' lo maleducado que soy, explico un poquito más sobre el tema que he expuesto de 'calibración' del reloj RC interno.
Los AVR (excepto los Xmega) tienen una tolerancia del reloj RC interno muy grande (del orden del 2 a 5%). Eso hace que con facilidad haya problemas de 'sincronización' en las comunicaciones serie (USART). Para ello, la fábrica pone un valor de calibración junto a los bytes (fijos en ROM OTP) del integrado, que se puede leer con el AVRStudio. Se puede encontrar en la opción 'Advanced' de la ventana de programación.
Si se coge el valor (es único para cada micro, supongamos el valor hexa 0x85) para la frecuencia de trabajo de entre las posibles, 'calibrarlo' es tan fácil como añadir la línea OSCCAL=0x85; en el código (en C) del programa. Así seguro que tenemos una frecuencia de oscilación mejor del 1%, y muchos de los problemas de comunicaciones desaparecerán.
Eso no quita que furri no tenga muchísima razón...
Hola!!
Mil gracias por las respuestas.
Tengo mucha prisa, asi que si necesitais más datos, a ver si mañana puedo escribir más.
El micro es un Atmega8 va a 2MHz internos que se configuran con los fuses (no se la palabra en español) que pone el AVRStudio4 al configurarlo para dicha frecuencia. Lleva un temporizador con un reloj externo de 32 KHz (recordemos que el reloj externo del temp va conectado a los mismos pines que en el caso de usar un reloj externo para el micro, pero no es el caso)
El código que utilizo para inicializar el USART es:
/ Activamos funciones USART /
//Ponemos UBRR a 12 (UBRRL a 12) para Bitrate a 9600 y Clock de 2MHz
ldi aux2,0
ldi aux,12
out UBRRH, aux2
out UBRRL, aux
//Activamos TXEN Y RXEN en UCSRB
ldi aux, 0x18
out UCSRB, aux
//Ponemos 1 bit de Stop, 8 de datos y sin paridad
ldi aux,0x86 ;(10100110)
out UCSRC,aux
Lo que me da mala espina de esto es que se utilice el mismo registro para calibrar el bitrate como para meter la forma del datagrama (registro UBRRH y UCSRC apuntan a la misma dirección de memoria, se activa uno u otro por el bit 7, creo que se llama USREL o algo asi)
Ahora la situación:
Como os comentaba, al madar cualquier dato diferente del 0x00, todo va como la seda, pero los 0x00 los interpreta como nada (en código ASCII el 0x00 es el carácter NULO).
Lo he probado con un software propio, que lee bytes, me escribe el dato que envío (1, 4, 255, ...) pero el 0 lo ignora; por otra parte probé con el hyperterminal; me representa los caracteres ASCII correspondientes al byte recibido.... una vez más el 0 no, aunque tiene lógica al ser el carácter nulo....
El tema es que el micro transmite mediante una tarjeta de RF a otra de RF que va conectada al PC y si pongo un programa que lo único que haga sea enviar 0xFF (por ejemplo), el led de las tarjetas transceptoras se enciende como que están enviando datos (CORRECTO); y lo más gracioso es que si le pongo a enviar 0x00 todo el rato, los led se encienden tambien, como si enviasen datos... PERO NO ESCRIBE NADA EN LA PANTALLA!!!!
No sé, yo por ahora voto más por un tema del software del PC que del micro, pero como nunca he usado este micro.... pues no sé.
Lo que probaré en breve será a enviar 0x00 desde el PC y que me responda... a ver que me responde.
Gracias por vuestra ayuda y saludos!!!!!!
Lo siento si no me he explicado bien, decidmelo y mañana intentaré escribir con más detalle.