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

时间:2014-06-09 15:42:10

标签: 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串口监视器并将我的模块连接到那个时,我收到了我的可怜的#但是alog带着一些垃圾。不是所有的时间,但主要是,垃圾是1或2字节。有人能帮助我吗?

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

编辑:抱歉忘了上次编辑,它只发送一个char ok,我更改了char,还有垃圾就在那里。当我发送字符串是不可读的。

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

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

没有做好自己的工作。希望这会对其他人有所帮助。

3 个答案:

答案 0 :(得分:0)

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

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

UBRR0H = 12;
UBRR0L = 0;

我看到的另一件事是你永远不会设置UCSR0C。你已将它注释掉了,我希望它可以通过默认(重置条件)设置正确运行,但为了以防万一,最好是明确的。

最后,您可能需要查看Simple Serial Communications上的此页面。

修改
根据你最近的编辑,我会把蓝牙从图片中删除。我建议将逻辑分析仪连接到微控制器的UART发送引脚,看看来自atmega的数据是否符合预期。如果数据是好的,我会开始查看为什么蓝牙无法正常工作。

答案 1 :(得分:0)

尝试使用至少2MHz的F_CPU

答案 2 :(得分:-1)

让你的ReceivedByte易变,请尝试这样:

volatile unsigned char ReceivedByte;