我正在研究基于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
答案 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)
永远不会得到满足。