реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> UART
Enot555
сообщение Apr 25 2008, 23:53
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 25-04-08
Пользователь №: 37 100



Доброго времени суток!
Подскажите, пожалуйста, как вывести контроллер (ATmega8) из режима передачи?
При организации прерываний по USART_DR_Empty и USART_Transmit_Complete после окончания передачи устанавливаются флаги UDRE и TXE и, поскольку UDRE имеет приоритет по прерываниям, то до TXE дело никогда не доходит. Как сбросить UDRE без записи в него новых данных (которые он воспринимает как данные для передачи следующего бита и так далее...)
Go to the top of the page
 
+Quote Post
ae_
сообщение Apr 26 2008, 00:22
Сообщение #2


Участник
***

Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



UDRE не нужно сбрасывать, UDRE=1 сразу после сброса и означает, что UART готов передавать данные. Надо просто запрещать прерывания UDRIE=0, когда больше нечего передавать.
Go to the top of the page
 
+Quote Post
Enot555
сообщение Apr 26 2008, 01:06
Сообщение #3





Группа: Новичок
Сообщений: 5
Регистрация: 25-04-08
Пользователь №: 37 100



[quote name='ae_' date='Apr 26 2008, 03:22' post='403016']
UDRE не нужно сбрасывать, UDRE=1 сразу после сброса и означает, что UART готов передавать данные. Надо просто запрещать прерывания UDRIE=0, когда больше нечего передавать.



спасибо, понял


[quote name='ae_' date='Apr 26 2008, 03:22' post='403016']
UDRE не нужно сбрасывать, UDRE=1 сразу после сброса и означает, что UART готов передавать данные. Надо просто запрещать прерывания UDRIE=0, когда больше нечего передав

Хотя нет, попробовал на практике и не понял, ведь когда осуществляется прерывание по UDRIE, еще идет передача битов последнего байта. Как тогда контролировать окончание передачи, по последнему биту сдвигового регистра? Если так, то какой его (регистра) адрес (не нашел ни в одном описании)?.

Сообщение отредактировал Enot555 - Apr 26 2008, 01:08
Go to the top of the page
 
+Quote Post
tazik
сообщение Apr 26 2008, 06:08
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



Цитата
Хотя нет, попробовал на практике и не понял, ведь когда осуществляется прерывание по UDRIE, еще идет передача битов последнего байта.


Совершенно верно

Цитата
Как тогда контролировать окончание передачи, по последнему биту сдвигового регистра? Если так, то какой его (регистра) адрес (не нашел ни в одном описании)?.


Если Вы хотите "контролировать окончание передачи, по последнему биту сдвигового регистра", то используйте прерывание по TXC:UART Transmit complete.

This flag is
especially useful in half-duplex communications interfaces, where a transmitting application
must enter receive mode and free the communications bus immediately after
completing the transmission.

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

Адреса внутреннего сдвигового регистра ни в одном описании Вы не найдете. Зачем оно нужно, если есть флаг TXC.

Похоже, что в Вашем случае линии TXD и RXD физически разделены (т.е. прием и передача по 2 разным проводам). Тогда лучше использовать прерывание UDRE: UART Data register empty.

Либо UDRE, либо TXC - сразу оба использовать не нужно (в общем случае)

Сообщение отредактировал tazik - Apr 26 2008, 06:11
Go to the top of the page
 
+Quote Post
Enot555
сообщение Apr 26 2008, 11:18
Сообщение #5





Группа: Новичок
Сообщений: 5
Регистрация: 25-04-08
Пользователь №: 37 100



Либо UDRE, либо TXC - сразу оба использовать не нужно (в общем случае)

Спасибо, с использованием прерывания TXCIE побайтную передачу организовал.
Но все же мучает вопрос, как (можно ли) организовать передачу массива с использованием прерывания UDRIE, и после окончания передачи всего массива выключить передатчик. Ведь когда осуществляется прерывание по UDRIE, еще идет передача битов из сдвигового регистра, и если выключить передатчик из подпрограммы обработки прерывания, передача последнего байта завершена не будет.
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Apr 26 2008, 11:53
Сообщение #6


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



ДляATmega128
Код
ISR(USART1_UDRE_vect)
/*************************************************************************
Function: UART Data Register Empty interrupt
Purpose:  called when the UART is ready to transmit the next byte
**************************************************************************/
/* signal handler for uart data buffer empty interrupt */
{

    if(uart_txd_Tail != uart_txd_Head)
    {
        UDR1 = uart_txd_buffer[uart_txd_Tail];
    
        /* calculate and store new buffer index */
        uart_txd_Tail++;
        uart_txd_Tail &= UART_TXD_BUFFER_MASK;
    }
    else
    {
        /* tx buffer empty, disable UDRE interrupt */
        UCSR1B &= ~_BV(UDRIE1);
    }

}


Работа с кольцевым буфером. Посмотрите avrlib, я модифицировал код оттуда.
Для работы с кольцевым буфером надо несколько функций:
Код
int uart_rputc(const uint8_t symbol)
/* Запись символа в кольцевой буфер */
/* Возвращаемое значение:    */
/* >= 0 - OK,                */
/* < 0  - error, buffer FULL */
{
    if((uart_txd_Tail - uart_txd_Head - 1) != 0)
    {
        uart_txd_buffer[uart_txd_Head] = symbol;
        uart_txd_Head++;
        uart_txd_Head &= UART_TXD_BUFFER_MASK;        
        
        UCSR1B |= _BV(UDRIE1);

        return symbol;
    }
    return EXIT_FAILUREN;        /* buffer is full */    

}

и
Код
uint8_t uart_rwrite(const uint8_t *buf, const uint8_t datalength)
/* Запись блока данных в кольцевой буфер */
/* Возвращаемое значение:             */
/* >= 0 - число записанных символов */
{
    register uint8_t res = 0, count;
    
    for(count = datalength; count != 0; ++buf, --count){
        if(uart_rputc(*buf) >= 0)
            ++res;
    }
    return(res);
}

UART работает на 115200.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
tazik
сообщение Apr 26 2008, 18:31
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



Цитата(Enot555 @ Apr 26 2008, 19:18) *
Ведь когда осуществляется прерывание по UDRIE, еще идет передача битов из сдвигового регистра, и если выключить передатчик из подпрограммы обработки прерывания, передача последнего байта завершена не будет.


В принципе, mdmitry уже дал исчерпывающий ответ...

А как вы предполагаете выключать передатчик? Сбросом бита TXEN в UART Control register?
В документации по этому поводу написано:
Bit 3 – TXEN: Transmitter Enable
This bit enables the UART transmitter when set (one). When disabling the transmitter
while transmitting a character, the transmitter is not disabled before the character in the
shift register plus any following character in UDR has been completely transmitted.

В общем, даже если Вы запретите работу передатчика. Он все-таки завершит передачу данных из промежуточного регистра и следующего символа в регистре UDR (если он есть) и только после этого выключится.

Так что можете смело выключать передатчик - данные не потеряются

Сообщение отредактировал tazik - Apr 26 2008, 18:36
Go to the top of the page
 
+Quote Post
Enot555
сообщение Apr 26 2008, 19:27
Сообщение #8





Группа: Новичок
Сообщений: 5
Регистрация: 25-04-08
Пользователь №: 37 100



Цитата
Так что можете смело выключать передатчик - данные не потеряются


Спасибо, впредь буду внимательнее читать Datasheet
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 21:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01395 секунд с 7
ELECTRONIX ©2004-2016