Проблемы с настройкой UART на AVR Atmega88-PA

Я хочу настроить UART на ATmega88-PA. Сначала я пытался установить прерывание в регистре 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 байта. Кто-нибудь может мне помочь?

РЕДАКТИРОВАТЬ: кажется, что когда я отправляю данные с моего Bluetooth на Samsung Galaxy S3, данные идеальны ... Я понятия не имею, почему на последовательном мониторе, а также при отправке данных с использованием того же Bluetooth на ноутбук я получил много мусора вместе с данными. Если это поможет вам ответить на мой вопрос, будет здорово.

РЕДАКТИРОВАТЬ: извините, забудьте последнее редактирование, он отправляет только char, я меняю char, а также мусор. Когда я отправляю строку, она не читается.

РЕДАКТИРОВАТЬ: Как я писал ниже в сообщении embedded_guy, я решаю проблему, вставляя _delay_ms(1) после отправки каждого байта. и это работает прямо сейчас. я верю заявлению

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

не выполняет свою работу. Надеюсь, это поможет другим.


person Marian-Emanuel Ionascu    schedule 09.06.2014    source источник
comment
Вы получили данные мусора до или после вашего «#»?   -  person embedded_guy    schedule 09.06.2014
comment
Как я заметил, это после #, я также отправляю эти данные через Bluetooth на свой компьютер, потому что это лучше для чтения, чем монитор. Итак, я получаю #, а затем мусор из модуля Bluetooth, и то же самое в последовательном мониторе.   -  person Marian-Emanuel Ionascu    schedule 09.06.2014
comment
Ваш код выглядит так, как будто вы пытались реализовать примеры кода из таблицы данных. затем взломал код. Многие из закомментированных строк кода необходимы и не должны быть закомментированы.   -  person user3629249    schedule 10.06.2014
comment
в листе данных указаны требования к чтению буфера ввода-вывода после передачи байта и указано завершение передачи. Я не вижу этого в вашем коде.   -  person user3629249    schedule 10.06.2014
comment
в функции прерывания UART Rx в вашем коде необходимо манипулировать регистром состояния, чтобы сбросить флаги состояния UART   -  person user3629249    schedule 10.06.2014
comment
@ user3629249: я не говорю о получении, и я не уверен в вашем комментарии. Флаг состояния сбрасывается автоматически при чтении, насколько я знаю, из-за использования прерывания. я прав? первый комментарий посмотрю еще раз в спецификациях.   -  person Marian-Emanuel Ionascu    schedule 10.06.2014
comment
Не вижу неопровержимых доказательств, но я бы определенно объявил ReceivedByte volatile.   -  person Travis Griggs    schedule 10.06.2014
comment
@TravisGriggs Мне нужно только отправить данные, получение есть только для полной реализации. Я также пытался отключить это и тот же результат.   -  person Marian-Emanuel Ionascu    schedule 10.06.2014


Ответы (3)


Я не знаю, сработает ли это для вас, но я действительно вижу только пару вещей, которые могут быть проблемой.

Во-первых, во всех примерах установки предварительного масштаба BAUD, которые мне удалось найти, использовались две инструкции с верхним и нижним регистрами UBRR0. Если вы уже просмотрели свой код и проверили этот регистр, чтобы убедиться, что он правильно настроен, то проблема не в этом. В противном случае я бы рекомендовал установить его таким образом для значения, которое вы установили в своем коде:

UBRR0H = 12;
UBRR0L = 0;

Еще я вижу, что вы никогда не устанавливаете UCSR0C. Вы закомментировали его, и я ожидаю, что он будет работать правильно с настройками по умолчанию (условие сброса), но на всякий случай всегда полезно указать явно.

Наконец, вы можете взглянуть на эту страницу Simple Serial Communications< /а>.

РЕДАКТИРОВАНИЕ
Основываясь на вашем последнем редактировании, я бы исключил Bluetooth из картины. Я бы порекомендовал подключить логический анализатор к передающему контакту UART вашего микроконтроллера и посмотреть, соответствуют ли данные, выходящие из atmega, тем, что вы ожидали. Если эти данные в порядке, я бы начал искать, почему bluetooth не работает, как я ожидал.

person embedded_guy    schedule 09.06.2014
comment
Пробовал разными способами, в том числе и этим. Также у меня был установлен UCSR0C, я сообщаю об этом, потому что это конфигурация регистра по умолчанию. Спасибо за ссылку. - person Marian-Emanuel Ionascu; 10.06.2014
comment
Спасибо за повтор. Нет, проблема не в блютуз. Вчера на моем ноутбуке отключился блютуз. Пробовал переустанавливать драйвера, а ответа нет :)). Так что я использую Samsung Galaxy, как я уже сказал. Потратив много времени, я поставил _delay_ms(1) после отправки каждого байта. И волшебным образом теперь все работает. Как я считаю, заявление: в то время как ((UCSR0A & (1 ‹‹ UDRE0)) == 0) {}; не работает должным образом, и данные были повреждены после отправки сим-байтов - person Marian-Emanuel Ionascu; 11.06.2014
comment
Что касается Bluetooth для ноутбука, вчера я много раз перезапускал ноутбук, переустанавливал все драйвера, которые мог найти в Интернете, и ничего. Сегодня я открываю ноутбук, и Bluetooth работает ... Я считаю, что Microsoft должна изменить некоторых инженеров. - person Marian-Emanuel Ionascu; 11.06.2014
comment
@Manu Вы можете легко проверить выходные данные микроконтроллера с помощью осциллографа или логического анализатора. Тогда вы точно будете знать, работает ли ваш код так, как задумано. После этого вы можете приступить к устранению неполадок Bluetooth и драйверов устройств. Держите систему простой для начала. Мне кажется, что вы отлаживали функциональный код и проблема кроется в чем-то другом... но вы всегда можете проверить часть вашей системы. - person embedded_guy; 11.06.2014
comment
правильно, это просто какая-то отладка. У меня работал USART и вдруг перестал работать. Поэтому я начал с модульных тестов. - person Marian-Emanuel Ionascu; 11.06.2014

попробуйте использовать F_CPU с тактовой частотой не менее 2 МГц

person mbkfa93    schedule 08.01.2015
comment
Постарайтесь быть более описательным. Вы можете как-то объяснить свой ответ. - person Bhavik Shah; 08.01.2015
comment
Раньше у меня были некоторые проблемы с UART, когда я использовал #define F_CPU 1000000UL, в моем коде не было ничего плохого, но все было исправлено, когда я изменил эту строку на #define F_CPU 2000000UL. - person mbkfa93; 08.01.2015

сделайте свой ReceivedByte изменчивым, попробуйте так:

volatile unsigned char ReceivedByte;
person Tabish Saifullah    schedule 16.06.2014