1

我正在研究基于 atmega2560 的 MultiWii Pro 板的串行通信。我正在使用 avr-gcc 来编译和 avrdude 来编程。

这是我的问题。我试图让 atmega2560 向终端发送一些东西(十六进制值)。但是,无论分配给 UDR2 的值如何,也无论我分配给 UBRR2L 和 UBRR2H 的值如何,如果我将终端波特率设置为 9600,则终端输出始终为 0xff,如果我将终端波特率设置为 115200,则终端输出始终为 0xff。

这是我的代码

#define F_CPU 8000000UL
#define BAUDRATE 19200        //The baudrate to use
#define BAUD_PRESCALLER ((F_CPU / (BAUDRATE * 16UL))-1)

static void InitializeUART()
{
    UBRR2L = (uint8_t)(BAUD_PRESCALLER);                               
    UBRR2H = (uint8_t)(BAUD_PRESCALLER>>8);
    UCSR2B |= (1<<RXEN2) | (1<<TXEN2);          //RX TX  Enable
    UCSR2C |= (1<<USBS2)|(1<<UCSZ21)|(1<<UCSZ20);
}

还有我的发送功能

void USART2Write(char data)
{
    while( !(UCSR2A & (1<<UDRE2)));

    UCSR2B &= ~(1<<TXB82); //in the case if there are more than 8 bits of data
    if(data & 0x100)
    {
        UCSR2B |= (1 << TXB82);    
    }

    UDR2 = data;
}

就我而言,我的代码的波特率是 19200。终端波特率也是 19200。无论我分配给 UDR2 什么,输出将始终为 0x15。

这是我的保险丝设置

Low     High    Extended
0xFF    0xD8    0xFD
4

1 回答 1

3
UCSR2C |= (1<<USBS2)|(1<<UCSZ21)|(1<<UCSZ20);

USBS2 设置 2 个停止位。这是故意的吗?

void USART2Write(char data){
    while( !(UCSR2A & (1<<UDRE2)));

    UCSR2B &= ~(1<<TXB82); //in the case if there are more than 8 bits of data
    if(data & 0x100) {
        UCSR2B |= (1 << TXB82);    
    }

    UDR2 = data;
}

如果真的要使用 9 个数据位,则必须设置 UCSZ22、UCSZ21 和 UCSZ20。你只设置 UCSZ21 和 UCSZ20

UCSR2C |= (1<<USBS2) | (1<<UCSZ21) | (1<<UCSZ20);

所以我猜USBS2确实不是你想要的。也许你很困惑,因为标志 UCSZ22 在 UCSR2B 寄存器中。

因此,假设您需要 9 个数据位和 1 个停止位,请使用以下内容:

static void InitializeUART() {
    UBRR2L = (uint8_t)(BAUD_PRESCALLER);                               
    UBRR2H = (uint8_t)(BAUD_PRESCALLER>>8);
    UCSR2B |= (1 << RXEN2) | (1 << TXEN2) | (1 << UCSZ22);
    UCSR2C |= (1 << UCSZ21) | (1 << UCSZ20);
}

另一件事:您的变量data是类型char,char 通常是 8 位宽。所以条件if(data & 0x100)永远不会满足。

于 2013-11-05T08:03:24.027 回答