带中断的 Atmega168 USART 发送器

Atmega168 USART transmitter with interrupts

我尝试使用 USART 将数据从我的 Atmega168A-PU 传输到我的计算机。 为此,我编写了以下代码:

#include <avr/io.h>
#include <stdlib.h>

#define F_CPU 8000000UL
#define USART_BAUD 9600
#define UBRR_VALUE (F_CPU/16/USART_BAUD - 1)

void
usart_init(void)
{
    UBRR0H = (unsigned char)(UBRR_VALUE >> 8);
    UBRR0L = (unsigned char)UBRR_VALUE;
    UCSR0B = _BV(TXEN0) | _BV(UDRIE0);
    UCSR0C = _BV(USBS0) | _BV(UCSZ00) | _BV(UCSZ01);
    //UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
}


ISR(USART0_UDRE_vect)
{
    UDR0 = '0';
    UCSR0A |= _BV(TXC0);
}

int main(void)
{
    usart_init();
    while(!(UCSR0A & _BV(UDRE0)));
    UDR0 = '0';
    while(1);
    return 0;
}

我附上了Arduino USB2SERIAL转换器读取我电脑上的值,但是转换器说他收不到数据,我的电脑也收不到数据。

注意:我的 lfuse 是 0xe2(禁用 CLKDIV8),所以我有 8MHz F_CPU。
注意:我也尝试过不使用 UCSR0A |= _BV(TXC0);
注意:我在AVcc和AGnd之间有一个电容。
注:保险丝:(E:F9, H:DF, L:E2)

好吧,问题很简单。正如@KIIV 指出的那样,我忘记了 sei();(也 u/odokemono 指出了这一点)。谢谢。

此外,最好使用 USART_TX_vect 而不是 USART0_UDRE_vect,因为我的接收器已禁用。这是更正后的代码:

#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL
#define USART_BAUD 9600
#define UBRR_VALUE (F_CPU/16/USART_BAUD - 1)

void
usart_init(void)
{
    UBRR0H = (unsigned char)(UBRR_VALUE >> 8);
    UBRR0L = (unsigned char)UBRR_VALUE;
    UCSR0B = _BV(TXEN0) | _BV(TXCIE0);
    UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
    //UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
    sei();
}


ISR(USART_TX_vect)
{
    UDR0 = '0';
    UCSR0A |= _BV(TXC0);
}

int main(void)
{
    usart_init();
    while(!(UCSR0A & _BV(UDRE0)));
    UDR0 = '0';
    while(1);
    return 0;
}

顺便说一下:正如 u/odokemono 指出的那样,我禁用了第二个停止位,因为我的 USB2SERIAL 似乎在没有第二个停止位的情况下工作得更好。