Atmega 2560 USART未在终端上给出正确的值

时间:2013-11-05 00:18:12

标签: serial-port avr serial-communication atmega usart

我正在研究基于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

1 个答案:

答案 0 :(得分: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个数据位和一个停止位,请使用以下内容:

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)永远不会得到满足。