¿Se cuantifica la velocidad de transmisión en serie del ATMEGA328P?

4

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

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

Si configuro la velocidad en baudios en 9,600, la salida en serie es de 10,220 baudios. (¿Esto es porque no estoy usando un cristal o debido a la cuantificación?)

Si aumente F_CPU o disminuyo USART_BAUDRATE, gradualmente, la salida en serie de baudios 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 algún tipo de cuantificación que afecte a los baudios de salida?

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

    
pregunta fadedbee

3 respuestas

7

Como ya se mencionó, esta cuantización es fundamental para la arquitectura, que solo puede dividir el reloj de origen por un entero.

Sin embargo, su problema es bastante evitable. El ATmega UART puede operar en dos modos; uno donde necesita un reloj a 16 veces la velocidad en baudios, y otro donde el reloj solo necesita ser 8 veces.

Está utilizando el modo 16x, lo que significa que necesita un divisor entero de 62.5 KHz (1 MHz / 16) que producirá 9600 baudios. Eso sería alrededor de 6.5 que, no es utilizable. Si en lugar de dividir por 6, obtienes un 10417 baudios teórico que está más lejos de los 9600 de lo deseable.

Sin embargo, si en cambio usa el modo 8x, ahora puede dividir 125 KHz a 9600, algo que el número entero 13 se aproxima mucho para producir 9615 baudios.

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

    
respondido por el Chris Stratton
12

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

Esta es la fórmula de la hoja de datos:

ElregistroUBRRtiene16bitsdeancho(UBRRL+UBRRH),porloquesolopuedellevara65536posiblesconfiguracionesdebaudios.

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

    
respondido por el filo
2

Si posee un analizador lógico preciso, es posible que desee calibrar la frecuencia del reloj interno a través de OSCCAL (Registro de calibración del oscilador) para obtener mayor precisión. De todos modos, casi siempre se necesita un oscilador de cristal en una comunicación asíncrona limpia.

    
respondido por el DrPepe

Lea otras preguntas en las etiquetas