Регистр UDR очищается перед чтением данных

Я пытаюсь смоделировать UART, используя ATmega128. Я написал этот код в AVR STUDIO 4.

PORTB0 предназначен для используемого переключателя, поэтому при его нажатии он подключается к 5 В постоянного тока и отправляет «a» на uart1. в других случаях он подключен к земле. прием данных осуществляется по прерыванию. С помощью отладчика, когда в UDR1 есть данные и установлен RXC1, программа переходит к ISR, после чего регистр UDR сразу очищается и ничего не извлекается. Может ли кто-нибудь сказать мне, почему это происходит?

Вот код.

volatile unsigned char rxdata;

void uart_init(void)
{
    UCSR1A = 0x00;
    UCSR1B |= (1<<RXCIE1)|(1<<RXEN1)|(1<<TXEN1);    //0b10011000;
    UCSR1C |= (1<<7)|(1<<UCSZ11)|(UCSZ10);  //0b10000110;
    UBRR1H = 0;
    UBRR1L = 103; //9600 baud rate
}

ISR(USART1_RX_vect)
{
    rxdata = UDR1;
    PORTC = rxdata;
}

void putch(char data)
{
    while(!(UCSR1A & 0x20));
    UDR1 = data;
}

И основная программа

void port_init(void)
{
    DDRC = 0xFF;        
}

int main(void)
{
    port_init();
    uart_init();    
    sei();

    while(1)
    {
        if (PINB & 0x01){
            putch('a');         
        }
    }
}

person avr_rookie    schedule 04.12.2013    source источник
comment
Подключен ли Tx физически к Rx, так что вы отправляете и получаете «а» при нажатии кнопки? Кроме того, на первый взгляд код выглядит нормально. UDR не должен очищаться перед его чтением (фактически один байт удаляется из очереди из двойного буфера).   -  person Rev    schedule 04.12.2013
comment
Tx не подключен к Rx... Я не делал этого аппаратно. Я проверял только в режиме отладки... Чтобы установить прерывание, я установил данные в регистре UDR и включил флаг RXC.   -  person avr_rookie    schedule 05.12.2013
comment
Когда я делал симуляцию в proteus, физическое соединение Tx с Rx, кажется, работает.   -  person avr_rookie    schedule 05.12.2013
comment
От чего вы на самом деле пытаетесь получить данные? Отправка данных из AVR (TX) по своей сути не вызовет прерывания приема (RX), так как ничего не отправляется в AVR откуда-то еще. Вот почему соединение линий RX и TX работает вместе, так как AVR затем отправляет сам себе.   -  person skyrift    schedule 07.12.2013
comment
Я пытаюсь подключить его к гипертерминалу ПК, и, несмотря на многие усилия, он не работает.   -  person avr_rookie    schedule 09.12.2013


Ответы (2)


У меня было такое однажды. В моем случае установка точки останова до того, как флаг был оценен в коде, очищала его, потому что AVR Studio «читала» флаг (поскольку у меня был открыт регистр флага). Помогла установка точки останова ПОСЛЕ строки, где был прочитан флаг. В вашем случае установите точку останова в строке PORTC = rxdata;

Чтобы получить лучшее ощущение отладки, я прочитал флаг в переменную прямо в начале ISR и сразу после этого установил точку останова.

Прошло несколько лет с тех пор, как это произошло, и я даже не уверен, было ли это на самом деле так. Так что, может быть, вы можете проверить это ;)

person ibschreiber    schedule 04.12.2013

Я просмотрел раздел справки AVR Studio 4. Что касается известных проблем с симулятором в отношении функций UART, в нем говорится:

Регистр UART/USART UDR можно изменить только из приложения. Ввод через файлы стимулов или путем изменения представления ввода-вывода и т. д. невозможен.

person Rev    schedule 05.12.2013
comment
Я пытался выполнить отладку, изменив регистр UDR и биты RXC. Интересно, имеет ли это какое-то отношение к предохранителю BOOTRST и IVSEL.. - person avr_rookie; 06.12.2013