Atmega 2560 USART не дает правильное значение на терминале

Я работаю над последовательной связью своей платы MultiWii Pro, основанной на atmega2560. Я использую avr-gcc для компиляции и avrdude для программирования.

Вот моя проблема. Я пытаюсь заставить atmega2560 отправить что-то (шестнадцатеричное значение) на терминал. Однако, независимо от значения, присвоенного UDR2, и независимо от значения, которое я присвоил UBRR2L и UBRR2H, на выходе терминала всегда будет 0xff, если я установил скорость терминала на 9600 бод, и 0xff, если я установил скорость терминала на 115200 бод.

Вот мой код

#define F_CPU 8000000UL
#define BAUDRATE 19200        //The baudrate to use
#define BAUD_PRESCALLER ((F_CPU / (BAUDRATE * 16UL))-1)

static void InitializeUART()
{
    UBRR2L = (uint8_t)(BAUD_PRESCALLER);                               
    UBRR2H = (uint8_t)(BAUD_PRESCALLER>>8);
    UCSR2B |= (1<<RXEN2) | (1<<TXEN2);          //RX TX  Enable
    UCSR2C |= (1<<USBS2)|(1<<UCSZ21)|(1<<UCSZ20);
}

И моя функция отправки

void USART2Write(char data)
{
    while( !(UCSR2A & (1<<UDRE2)));

    UCSR2B &= ~(1<<TXB82); //in the case if there are more than 8 bits of data
    if(data & 0x100)
    {
        UCSR2B |= (1 << TXB82);    
    }

    UDR2 = data;
}

В моем случае скорость передачи моего кода 19200. Скорость передачи терминала также 19200. Независимо от того, что я назначил UDR2, на выходе всегда будет 0x15.

Вот моя настройка предохранителя

Low     High    Extended
0xFF    0xD8    0xFD

person mirage1s7    schedule 05.11.2013    source источник
comment
Я предполагаю, что вы проверили формат кадра (четность, стоп-бит, управление потоком и т. д.) на стороне терминала?   -  person Rev    schedule 05.11.2013
comment
Вот мой формат кадра на стороне терминала: бод: 19200, бит данных: 8, управление потоком: нет, четность: нет, стоповые биты: один. Тем не менее, независимо от моих настроек бита четности и стоповых битов, выходные данные всегда были одинаковыми.   -  person mirage1s7    schedule 05.11.2013
comment
Ну, это не то кадрирование, которое вы настроили (см. Мой ответ). Что произойдет, если вы оставите код и установите бод: 19200, бит данных: 9, управление потоком: нет, четность: нет, стоповые биты: два?   -  person Rev    schedule 05.11.2013
comment
Я попробовал вашу конфигурацию. Выходное значение не изменилось. Поэтому я изменил свой код, чтобы отправить 8 бит данных вместо 9, удалив (1‹‹ UCSZ22), и изменил стоп-бит на 1, удалив (1‹‹USBS2). Я использовал конфигурацию, о которой упоминал выше. Кажется, это не сработало. Кстати, я использую Arduino в качестве интернет-провайдера. Я подаю TX Atmega2560 напрямую на контакт RX на Arduino Uno, может ли это быть возможной причиной проблемы?   -  person mirage1s7    schedule 05.11.2013
comment
Независимо от вашей точной настройки, вы должны стараться сделать ее как можно более простой для ваших первоначальных тестов. Как вы подключаетесь от atmega2560 к терминалу (это терминальная программа на ПК)? Это может быть проблема с логическими уровнями. Может быть, у вас есть выход UART TTL на стороне atmega2560 и напрямую связан с RS232?   -  person Rev    schedule 05.11.2013
comment
Я использую терминал, загруженный в студии atmel. По сути, мой Arduino Uno подключен к ПК с помощью последовательного кабеля. Это кабель mchobby.be/PrestaShop/img/p/68- 142-large.jpg Чтобы протестировать код на моем atmega2560, я подключил tx atmega к Rx arduino uno.   -  person mirage1s7    schedule 05.11.2013
comment
ATmega328 на Arduino UNO имеет только один UART, который связан со встроенным ATmega16U2, обеспечивающим интерфейс USB. Насколько я могу судить (никогда не использовал Arduino), нет запасного UART для подключения. У вас есть atmega2560 на макетной плате?   -  person Rev    schedule 06.11.2013
comment
Если я правильно понимаю, на самой плате Arduino Uno есть RX (pin0) и TX (pin1). Я полагаю, что они подключены к UART Atmega328 на Arduino Uno, что означает, что эти два контакта также подключены к интерфейсу USB на плате. У меня есть atmega2560 на другой плате под названием Multiwii Pro, на которой есть сквозные контакты RX2/TX2.   -  person mirage1s7    schedule 06.11.2013


Ответы (1)


UCSR2C |= (1<<USBS2)|(1<<UCSZ21)|(1<<UCSZ20);

USBS2 устанавливает 2 стоповых бита. Это намеренно?

void USART2Write(char data){
    while( !(UCSR2A & (1<<UDRE2)));

    UCSR2B &= ~(1<<TXB82); //in the case if there are more than 8 bits of data
    if(data & 0x100) {
        UCSR2B |= (1 << TXB82);    
    }

    UDR2 = data;
}

Если вы действительно хотите использовать 9 бит данных, необходимо установить UCSZ22, UCSZ21 и UCSZ20. Вы устанавливаете только UCSZ21 и UCSZ20

UCSR2C |= (1<<USBS2) | (1<<UCSZ21) | (1<<UCSZ20);

так что я думаю, что USBS2 действительно не то, что вам нужно. Возможно, вы были сбиты с толку, потому что флаг UCSZ22 находится в регистре UCSR2B.

Итак, если вам нужны 9 бит данных и один стоповый бит, используйте что-то вроде этого:

static void InitializeUART() {
    UBRR2L = (uint8_t)(BAUD_PRESCALLER);                               
    UBRR2H = (uint8_t)(BAUD_PRESCALLER>>8);
    UCSR2B |= (1 << RXEN2) | (1 << TXEN2) | (1 << UCSZ22);
    UCSR2C |= (1 << UCSZ21) | (1 << UCSZ20);
}

Еще одна вещь: ваша переменная data имеет тип char, а char обычно имеет ширину 8 бит. Таким образом, условие if(data & 0x100) никогда не выполняется.

person Rev    schedule 05.11.2013