如何将 ATMEGA64a-au USART 速度设置为 115200?

How to set ATMEGA64a-au USART speed to 115200?

如标题所示,我有 ATMEGA64a-au 和 12mhz crystal,我通过这些代码将波特率设置为 9600:

#define F_CPU 12000000UL

#define FOSC 12000000 // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

..

void USART0_Init( unsigned int ubrr )
{
    UBRR0H = (unsigned char) (ubrr >> 8);
    UBRR0L = (unsigned char) ubrr;
    UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
    // Set frame format: 8data, 1stop bit
    UCSR0C = (1 << USBS0) | (3 << UCSZ00);

}

void USART1_Init( unsigned int ubrr )
{
    UBRR1H = (unsigned char) (ubrr >> 8);
    UBRR1L = (unsigned char) ubrr;
    UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);
    // Set frame format: 8data, 1stop bit 
    UCSR1C = (1 << USBS1) | (3 << UCSZ10);
}

..

USART0_Init(MYUBRR);
USART1_Init(MYUBRR);

当我使用该波特率时很好,但我最近遇到了一个 115200bd 设备,我也需要将其更改为那个,但是当我更改此行时:

#define BAUD 115200

A​​VR 微控制器停止通信,我不知道如何修复它。是不是该设备太快了,还是我遗漏了什么?

#define MYUBRR FOSC/16/BAUD-1

首先这个公式有一个问题:它总是向下舍入。您需要将其四舍五入到接近整数,例如(FOSC / 16 + BAUD / 2) / BAUD-1

顺便问一下,为什么是 FOSC 而不是 F_CPU

反正你可以计算公式FOSC/16/BAUD-1时的误差:

MYUBRR = 12000000/16/115200-1 = 5(5.51 向下舍入)

实际 UART 速度将为:

F_CPU / 16 / (MYUBRR + 1) = 12000000 / 16 / (5 + 1) = 125000

比要求高出 8.5%。接收器-发送器波特率差异超过 4.5% 的通信是不可能的。

但您可以设置双速运行模式 (参考数据表第25.3.2节)

可以通过设置 UCSRA 中的位 U2X 来完成。

在这种情况下,UART 时钟将是 CPU 时钟的 1/8,从而允许更高的 UBRR 设置:

// divide by 8, not 16
#define MYUBRR ((FOSC / 8 + BAUD / 2) / BAUD - 1)

...

void USART0_Init( unsigned int ubrr )
{
    // you can just assign the value to UBRR, compiler will handle all the thighs
    UBRR0 = ubrr;
    UCSR0A = (1 << U2X0); // enable 2x mode
    UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
    // Set frame format: 8data, 1stop bit
    UCSR0C = (1 << USBS0) | (3 << UCSZ00);
}

在这种情况下 MYUBRR 值将是:

(12000000 / 8 + 115200 / 2) / 115200 - 1 = 12

实际 UART 速度为

12000000 / 8 / (12 + 1) = 115384,6

误差小于 0.2%