c - 在 AVR Atmega88-PA 上设置 UART 时遇到问题

标签 c avr avr-gcc

我想在 ATmega88-PA 上设置 UART。首先,我试图在 UDRE 寄存器上设置一个中断,但这不起作用,所以对于传输,我使用正常轮询。 因为代码不起作用,所以我从 0 开始重新编写一个基本程序。

#define F_CPU 1000000UL
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 8UL))) - 1)

char ReceivedByte = '#';

int main (void)
{
    UCSR0A = (1 << U2X0);

    /* Turn on the transmission and reception circuitry. */
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
    /* Use 8-bit character sizes. */
    //UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);

    /* BAUD prescale */
    UBRR0 = 12;

    /* Load upper 8-bits of the baud rate value into the high byte of the UBRR register. */
    //UBRR0H = (BAUD_PRESCALE >> 8);
    /* Load lower 8-bits of the baud rate value into the low byte of the UBRR register. */
    //UBRR0L = BAUD_PRESCALE;

    UCSR0B |= (1 << RXCIE0);

    sei();
    DDRB |= 0x04;
    PORTB &= ~0x04;

    for (;;)
    {
        /* Do nothing until data have been received and is ready to be read from UDR. */
        //while ((UCSR0A & (1 << RXC0)) == 0) {};
        /* Fetch the received byte value into the variable "ByteReceived". */
        //ReceivedByte = UDR0;

        if(ReceivedByte == '1')
            PORTB |=0x04;
        else
            PORTB &=~0x04;

        /* Do nothing until UDR is ready for more data to be written to it. */
        while ((UCSR0A & (1 << UDRE0)) == 0) {};
        /* Echo back the received byte back to the computer. */
        UDR0 = ReceivedByte;
    }
}

ISR(USART_RX_vect)
{
    ReceivedByte = UDR0;
}

并且代码可以正常工作,但是当我打开一个 arduino 串行监视器并将我的模块连接到它时,我收到了我可怜的 # 但有一些垃圾。并非所有时间,但大多数情况下,垃圾是 1 或 2 个字节。有人可以帮助我吗?

编辑:当我从我的蓝牙数据发送到三星银河 S3 时,数据是完美的......我不知道为什么在串行监视器上,以及在使用相同的蓝牙向笔记本电脑发送数据时我连同数据一起得到了很多垃圾。如果这对你有帮助 回答我的问题,会很棒。

编辑:抱歉忘记了最后的编辑,它只发送一个字符,好的,我更改了字符,那里也有垃圾。当我发送一个字符串是不可读的。

编辑:正如我在 embedded_guy 下面的帖子中提到的,我解决了在发送每个字节后插入 _delay_ms(1) 的问题。它现在正在工作。我相信这个说法

 while ((UCSR0A & (1 << UDRE0)) == 0) {};

没有做好它的工作。希望这会帮助其他人。

最佳答案

我不知道这是否适合你,但我真的只看到一些可能成为问题的事情。

首先,我能找到的所有设置 BAUD 预分频器的示例都使用了两条指令,其中包含 UBRR0 的高寄存器和低寄存器。如果您已经单步执行代码并检查了该寄存器以确保其配置正确,那么这不是问题所在。否则,我建议您将其设置为您在代码中设置的值:

UBRR0H = 12;
UBRR0L = 0;

我看到的另一件事是您从未设置 UCSR0C。您已将其注释掉,我希望它可以使用其默认(重置条件)设置正确运行,但以防万一,明确说明总是好的。

最后,您可能想看看 Simple Serial Communications 上的这个页面.

编辑
根据你最近的编辑,我会把蓝牙从照片中去掉。我建议将逻辑分析仪连接到微 Controller 的 UART 传输引脚,看看来自 atmega 的数据是否符合您的预期。如果该数据良好,我将开始研究为什么蓝牙没有按我预期的那样工作。

关于c - 在 AVR Atmega88-PA 上设置 UART 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24123781/

相关文章:

c - 流媒体服务器的异步套接字

C将字符串拆分为字符串数组

c - 有关 AVR 和串行端口的帮助

c++11 具有 avr __progmem__ 的广义属性

assembly - 为什么 avr-gcc 将 "push r1"指令添加到函数的开头?

c - AVR GCC、汇编 C stub 函数、eor 和所需的常量值

c - 用于在 C 中将符号与变量值连接的预处理器指令

c - 如何将单个字符数字(如 '5')转换为整数

c - avr-gcc 3.4.0 和 avr-gcc 4.3.x 之间的二进制兼容性

c++ - 这是合法的 C++ 代码吗?