简体   繁体   English

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

[英]Having trouble setting up the UART on an AVR Atmega88-PA

I want to set up the UART on a ATmega88-PA. 我想在ATmega88-PA上设置UART。 First I was trying to set an interrupt on UDRE register but this was not working, so for the transmission I use normal polling. 首先,我试图在UDRE寄存器上设置一个中断,但此操作不起作用,因此对于传输,我使用常规轮询。 Because the code was not working I started again from 0 with a basic program. 由于代码无法正常工作,我从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;
}

And the code is working but when I open an arduino serial monitor and connect my module to that, I receive my poor # but alog with some garbage. 代码可以正常工作,但是当我打开一个arduino串行监视器并将模块连接到该监视器时,我收到了可怜的#消息,但出现了一些垃圾。 Not all the time but mostly, the garbage is 1 or 2 byte. 并非总是如此,但大多数情况下,垃圾是1或2个字节。 Can someone help me? 有人能帮我吗?

EDIT: It seams that when I send from my bleutooth data to a Samsung galaxy S3 the data is perfect...I do not have any clue why on serial monitor, and also when sending data using the same bluetooth to laptop I got a lot of garbage along with the data. 编辑:它接缝了,当我从蓝牙数据发送到三星银河S3时,数据是完美的...我不知道为什么在串行显示器上有任何线索,而且当使用相同的蓝牙向笔记本电脑发送数据时,我得到了很多与数据一起丢弃。 If this helps you answearing my qestion, will be great. 如果这可以帮助您满足我的要求,那就太好了。

EDIT: sorry forget the last edit, it is send only a char ok, I change the char and also garbage is there. 编辑:对不起,忘记最后一次编辑,它只发送一个字符,我更改了字符,并且也存在垃圾。 When I send a string is unreadable. 当我发送一个字符串是不可读的。

EDIT : As I commneted on the post below of embedded_guy , I solve the problem inserting a _delay_ms(1) after sending each byte. 编辑:正如我在embedded_guy下面的文章中所提到的,我解决了在发送每个字节后插入_delay_ms(1)的问题。 and it is working right now. 现在正在工作。 I believe the statement 我相信声明

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

is not doing its job. 没有做它的工作。 Hope this will help others. 希望这对其他人有帮助。

I don't know if this will work for you, but I really only see a couple of things that could be an issue. 我不知道这是否对您有用,但我确实只看到了可能会成为问题的几件事。

First, all of the examples of setting the BAUD prescale that I could find used two instructions with the high and low registers of UBRR0 . 首先,我可以找到的所有设置BAUD预分频比的示例都使用了两条指令,分别具有UBRR0高低寄存器。 If you have already stepped through your code and examined that register to ensure that it is correctly configured, then that is not the issue. 如果您已经单步执行代码并检查了该寄存器以确保配置正确,那么这不是问题。 Otherwise, I would recommend setting it like this for the value you have it set to in your code: 否则,建议将这样设置为在代码中设置的值:

UBRR0H = 12;
UBRR0L = 0;

The other thing I see is that you are never setting UCSR0C . 我看到的另一件事是您从未设置UCSR0C You have it commented out and I would expect it to operate correctly with its default (reset condition) settings, but it is always good to be explicit just in case. 您已将其注释掉,我希望它可以使用其默认设置(重置条件)正确运行,但是以防万一,最好是明确的。

Finally, you may want to take a look at this page on Simple Serial Communications . 最后,您可能需要在Simple Serial Communications上查看此页面。

EDIT 编辑
Based on your most recent edit, I would take the bluetooth out of the picture. 根据您最近的编辑,我将把蓝牙从图片中删除。 I would recommend connecting a logic analyzer to the UART transmit pin of your microcontroller and see if the data coming out of the atmega is what you expected. 我建议将逻辑分析仪连接到微控制器的UART发送引脚,看看从atmega输出的数据是否符合您的期望。 If that data is good, I would begin looking at why the bluetooth is not working as I anticipated. 如果数据良好,我将开始研究为什么蓝牙无法正常工作。

尝试使用至少2MHz的F_CPU

使您的ReceivedByte易失,像这样尝试:

volatile unsigned char ReceivedByte;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM