Serial port 读取数据前已清除UDR寄存器

Serial port 读取数据前已清除UDR寄存器,serial-port,avr,interrupt-handling,atmega,avr-studio4,Serial Port,Avr,Interrupt Handling,Atmega,Avr Studio4,我正在尝试使用ATmega128模拟uart。我在AVR STUDIO 4中编写了这段代码 端口B0用于开关,因此当按下它时,它连接到5v dc,并向uart1发送“a”。在其他情况下,它会接地。通过中断接收数据。 使用调试器,当UDR1中有数据并且设置了RXC1时,程序跳转到ISR,然后立即清除UDR寄存器,并且不检索任何内容。有人能告诉我为什么会这样吗 这是代码 volatile unsigned char rxdata; void uart_init(void) { UCSR1A

我正在尝试使用ATmega128模拟uart。我在AVR STUDIO 4中编写了这段代码

端口B0用于开关,因此当按下它时,它连接到5v dc,并向uart1发送“a”。在其他情况下,它会接地。通过中断接收数据。 使用调试器,当UDR1中有数据并且设置了RXC1时,程序跳转到ISR,然后立即清除UDR寄存器,并且不检索任何内容。有人能告诉我为什么会这样吗

这是代码

volatile unsigned char rxdata;

void uart_init(void)
{
    UCSR1A = 0x00;
    UCSR1B |= (1<<RXCIE1)|(1<<RXEN1)|(1<<TXEN1);    //0b10011000;
    UCSR1C |= (1<<7)|(1<<UCSZ11)|(UCSZ10);  //0b10000110;
    UBRR1H = 0;
    UBRR1L = 103; //9600 baud rate
}

ISR(USART1_RX_vect)
{
    rxdata = UDR1;
    PORTC = rxdata;
}

void putch(char data)
{
    while(!(UCSR1A & 0x20));
    UDR1 = data;
}

我有过一次。在我的例子中,在代码中对标志求值之前设置断点会清除它,因为AVR Studio“读取”标志(因为我打开了标志寄存器)。在读取标志的行之后设置断点会有所帮助。在您的情况下,在第PORTC=rxdata行设置断点

为了获得更好的调试感觉,我在ISR的开头将标志读入变量中,并在此之后设置断点


这件事已经过去好几年了,我甚至不确定是否真的是这样。所以,也许你可以验证一下;)

我查看了AVR Studio 4帮助部分。关于与UART功能相关的已知模拟器问题,它指出:

UART/USART UDR寄存器只能从应用程序中修改。无法通过刺激文件或修改I/O视图等进行输入


Tx是否物理连接到Rx,以便您发送和接收“a”on按钮?除此之外,代码在第一眼看到时看起来很好。读取UDR之前不应清除UDR(实际上一个字节从双缓冲区中退出队列)。Tx未连接到Rx…我没有在硬件中执行此操作。我只在调试模式下检查了它。。。为了设置中断,我在UDR寄存器中设置了数据,并启用了RXC标志。当我在proteus中进行模拟时,将Tx与Rx物理连接似乎是可行的。您实际上想从何处接收数据?从AVR(TX)发送数据不会固有地触发接收中断(RX),因为没有任何东西从其他地方发送到AVR。这就是为什么将RX和TX线路连接在一起工作的原因,因为AVR随后将发送到自身。我正在尝试将其连接到PC超级终端,尽管做了很多努力,但它仍然无法工作。我一直在尝试通过修改UDR寄存器和RXC位进行调试。我想知道这是否与引导保险丝和IVSEL有关。。
void port_init(void)
{
    DDRC = 0xFF;        
}

int main(void)
{
    port_init();
    uart_init();    
    sei();

    while(1)
    {
        if (PINB & 0x01){
            putch('a');         
        }
    }
}