Salida aleatoria al leer la transmisión AVR UART

0

Estoy tratando de aprender a usar la interfaz USART en un Atmega328p. Por ahora, solo trato de enviar bytes de caracteres 'c' cada 500 ms y leerlos en mi computadora usando un convertidor TTL de serie USB PL2303.

Los datos se transmiten, pero no obtengo el resultado que quiero en el lado receptor.

Esto es lo que he programado en mi microcontrolador:

#define BAUDRATE 9600
#define BAUD (((F_CPU / (BAUDRATE * 16UL))) - 1)

void uart_init()
{    
  UBRR0 = BAUD;

  /* 8 data bites, no parity, one stop bit */
  UCSR0C |= _BV(UCSZ01) | _BV(UCSZ00);
  /* Enable UART input and output */
  UCSR0B |= _BV(RXEN0) | _BV(TXEN0);
}


int main()
{
  uart_init();

  for (;;)
  {
    while ((UCSR0A & _BV(UDRE0)) == 0);
    UDR0 = 'c';
    _delay_ms(500);
  }
}

Leí los datos en python usando pyserial:

import serial

with serial.Serial(
        '/dev/ttyUSB0',
        baudrate=9600,
        bytesize=serial.EIGHTBITS,
        parity=serial.PARITY_NONE) as port:
    while True:
        print(port.read())

De alguna manera tengo el resultado correcto. Tengo algunos bytes correctos 'c', pero uno de los dos es '\ xe3':

b'\xe3'
b'c'
b'\xe3'
b'c'
b'\xe3'
b'\xe3'
b'\xe3'
b'c'
b'c'
b'c'
b'\xe3'

Parece que tengo un byte de orden alto aleatorio que aparece de vez en cuando.

No puedo encontrar dónde está mi problema. Verifico el alcance, y los datos enviados son siempre los mismos. Así que creo que tengo algo mal en el lado receptor. Pero no puedo encontrar lo que puede ser. He verificado dos veces la F_CPU, que está a 1Mhz.

    
pregunta Nicolas Appriou

1 respuesta

1

Hay demasiado error en tu reloj de velocidad de transmisión. (1 MHz / 9600 * 16) = 6.51. Esto se redondea a 6, por lo que el error de frecuencia es (6.51 / 6) -1 = 8.5%.

La velocidad en baudios de UART debe tener una precisión superior al 5% para evitar recibir errores. ¿Por qué? El receptor inicia la temporización cuando el bit de inicio se pone bajo, luego muestrea la señal en el medio de cada bit. Si la frecuencia es incorrecta, el punto de muestreo se deslizará progresivamente con relación a la mitad de cada bit. Después de 9 bits con un error del 5%, el punto de muestra está justo dentro del período de bits correcto, pero con un error del 8,5% está en el bit anterior (por lo que el bit de detención se detecta como el bit 7).

ElUARTenelextremodeenvíotambiéntienealgúnerrordetiempo.Siloserroresestánenlamismadirecciónenambosextremos,entoncessecancelaránparcialmenteypodríasalirseconunerror>5%.Perosiestánendireccionesopuestas,entoncesserápeor.Porlotanto,paragarantizarquedossistemasaleatoriospuedancomunicarsesinerror,susvelocidadesdetransmisióndebensermásprecisasque+-2.5%.Otrosefectos,comolatemporizaciónylafluctuacióndelamuestra,elruidoylastasasderotacióndesigualespuedenreduciraúnmáselmargen.

ParaunATmega328queseejecutaa1MHz,puedeestablecerelU2X0bitenUCSR0AyhacerUBRR0=12,luegodebeobtener9615.38Baud,queessolounerrordel0.2%(máscualquiererrorenlafrecuenciadelrelojdelsistema).

Calculadora de velocidad en baudios AVR

    
respondido por el Bruce Abbott

Lea otras preguntas en las etiquetas