UART只能单向工作(ATmega328p)

时间:2015-01-26 21:16:58

标签: avr uart

我有一个由ATmega328P驱动的Arduino Uno。我想放弃它的库并在 lower 级别上做所有事情以用于学习目的。但是我无法让uart正常工作,它现在只在发送到设备时才有效。接收返回奇怪的垃圾,temrinal无法打印。

#define BAUDRATE (((F_CPU / (BAUD * 16UL))) - 1)
void init_uart()
{
    UBRR0H = BAUDRATE >> 8; // set high baud
    UBRR0L = BAUDRATE; //set low baud
    UCSR0B = _BV(TXEN0) | _BV(RXEN0); //enable duplex
    UCSR0C = _BV(UCSZ00) | _BV(UCSZ01) | _BV(USBS0); //8-N-1
}

void putchar_uart(char c, FILE* stream)
{
    loop_until_bit_is_set(UCSR0A, UDRE0);   //wait till prev char is read
    UDR0 = c;
}

char getchar_uart(FILE* stream)
{
    loop_until_bit_is_set(UCSR0A, RXC0);    //wait if there is data
    return UDR0;
}

//^ actually is in a seperate file which gets linked

int main()
{
    DDRD |= PIN_LED;
    PORTD |= PIN_LED;

    stdout = &mystdout;
    stdin = &mystdin;

    char buf[0xFF];

    init_uart();
    while (1)
    {
        char c = getchar_uart(NULL);
        if (c == 'a')
        {
            PIND = PIN_LED;
            printf("%s\n", "Hallo");
        }
    }
}

我正在运行Ubuntu 14.04 LTS并使用minicom进行通信。设置为:115200 8N1(当然使用正确的串行设备。)

它编译为:

avr-gcc -Wall -Os -mmcu=atmega328p -DF_CPU=16000000UL -DBAUD=115200 -std=c99 -L/home/joel/avr-libs/lib -I/home/joel/avr-libs/inc -o firmware.o main.c  -luart

那么我怎么知道单向运作?因为在键入'a'时只能切换。但是响应是无效的字符。十六进制:

c8 e1 ec ec ef 8a

2 个答案:

答案 0 :(得分:1)

当Chris建议打印出Arduino使用的配置寄存器时,我解决了这个问题,我注意到它使用双模式。我无法使用minicom进行配置,或者我错过了。也许默认使用这种模式。无论如何它现在有效。

我还了解到avr-libc提供了一个名为util / setbaud.h的头文件,它可以自动计算正确的波特率。在UBRRL_VALUE和UBRRH_VALUE字段中。

答案 1 :(得分:1)

通过设置USBS位,您将命令第二个停止位。

这似乎导致您的计算机错误地认为MSB(最后一个数据位)在未使接收到的数据与0x80进行“或”时设置。 < / p>

虽然这会导致帧错误,但可能不是错误的MSB的原因。你自己关于切换到2x模式的答案(因此更准确地近似波特率)对解决方案来说更关键,不过你也应该纠正这个问题。