4 votos

¿Está cuantificada la velocidad en baudios serie del ATMEGA328P?

Estoy usando un ATMEGA328p, funcionando desde su oscilador interno (dividido por 8 = 1MHz).

He medido (aproximadamente) la salida del oscilador, utilizando mi analizador lógico Salae, como que van desde 960KHz a 1000KHz, por lo que no es horrible. Hice esto usando el fusible "Salida de reloj en PORTB0".

Si configuro la velocidad en baudios a 9.600, la salida serie es a 10.220 baudios. (¿Esto se debe a que no estoy usando un cristal, o a la cuantificación?)

Si aumento F_CPU o disminuyo USART_BAUDRATE, gradualmente, el baudio serie de salida no disminuye, hasta que salta a 8.800 baudios.

#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 

int main(void) {
        // serial port setup
        UCSR0B |= (1 << RXEN0) | (1 << TXEN0);
        UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);
        UBRR0H = (BAUD_PRESCALE >> 8);
        UBRR0L = BAUD_PRESCALE;
        ...

¿Hay alguna forma de cuantificación que afecte a los baudios de salida?

P.D. Estoy usando GCC en Linux para compilar código, y no estoy usando código/IDE de Arduino.

12voto

filo Puntos 1

Es un sistema totalmente digital. Debe funcionar por pasos discretos.

Esta es la fórmula de la hoja de datos: enter image description here

El registro UBRR tiene 16 bits de ancho (UBRRL + UBRRH), por lo que sólo puede dar lugar a 65536 posibles configuraciones de baudios.

Consulte también la sección "24.11. Ejemplos de configuración de la velocidad en baudios" y la tabla 24-4 de la hoja de datos.

7voto

Andrew Walker Puntos 9038

Como ya se ha mencionado, esta cuantización es fundamental para la arquitectura, que sólo puede dividir el reloj fuente por un número entero.

Sin embargo, su problema es bastante evitable. La UART ATmega puede funcionar en dos modos; uno en el que necesita un reloj a 16x la velocidad en baudios, y otro en el que el reloj sólo necesita ser 8x.

Estás utilizando el modo 16x, lo que significa que necesitas un divisor entero de 62,5 KHz (1 MHz / 16) que dará 9600 baudios. Eso sería alrededor de 6,5 que, no es utilizable. Si en vez de eso divides por 6, obtienes unos 10417 baudios teóricos que están más lejos de 9600 de lo deseable.

Sin embargo, si en lugar de eso utilizas el modo 8x, ahora puedes dividir 125 KHz entre 9600, algo a lo que el entero 13 se aproxima mucho para dar 9615 baudios.

Así que la solución real a tu problema es operar la UART en modo "doublespeed" y usar 8 en lugar de 16 en la fórmula para calcular el divisor. Como la división real es el valor programado más uno, escribirías 12 en los registros del divisor.

2voto

chinkchink Puntos 371

Si dispone de un analizador lógico preciso, puede calibrar la frecuencia del reloj interno mediante OSCCAL (Registro de calibración del oscilador) para obtener mayor precisión. De todos modos, un oscilador de cristal es casi siempre necesario en una comunicación asíncrona limpia.

1 votos

Aunque puede haber un ligero error de reloj aquí, la cuestión específica sobre la que se pregunta no tiene nada que ver con la calibración, sino que es más bien fundamental para la división de reloj entero. En realidad, las ATmegas normalmente funcionan bien para la comunicación serie asíncrona utilizando el oscilador interno sin ninguna medida de calibración adicional - el problema real aquí es que el chip ha sido mal configurado de una manera que produciría una tasa de baudios bastante errónea incluso con un reloj fuente perfecto.

0 votos

@ChrisStratton De acuerdo, he leído tu respuesta y parece que tiene sentido. Es un problema de programación. Tenía la intención de publicar esto como un comentario, pero no tengo suficiente reputación .

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X