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

 
 
> Обьясните разницу в прерываниях UART'a
kurtis
сообщение Dec 25 2008, 14:06
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Вероятно, я недостаточно внимательно читаю документацию, но возникает вопрос в чем разница между Data Register Empty Interrupt и Transmit Compete Interrupt ? Насколько я понял, это 2 прерывания которые возникают при оправке данных, но первое возникает когда данные из регистра данных попадают в сдвиговый регистр для отправки, а второе когда сдвиговый регистр выдал байт в сеть (насколько я понял). Но тогда получается что они выполняют практически одну и туже задачу.
В чем же тогда разница и зачем потребовалось делать именно 2 прерывания, а не одно ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ReAl
сообщение Dec 25 2008, 21:28
Сообщение #2


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



В не совсем явной форме это уже прозвучало, но хочу подчеркнуть - прерывание TXC действительно возникнет только при отправке последнего байта.
Флага прерывания TXC имеет шанс взвестить - на высокой скорости, при нагруженном другими, более приоритетными прерываниями процессоре - UDRE может "опоздать" и взведётся ещё и TXC. Но у UDRE выше приоритет и поэтому сначала вызовется его обработчик.
И вот в нём можно проверить - есть ли ещё байты для передачи и если есть - то сбросить флаг TXC, а если нет - самозапретиться и не трогать флаг TXC, пусть вызовется его обработчик.
Смысл такого действа - под операционной системой сделать (более частое) прерывание UDRE более "лёгким", не обращащимся к сервисам ОС (и, как следствие, имеющим шансы не вызывать не-inline функции и сохранять/восстанавливать только реально необходимые для работы регистры), а обращение к ОС поместить в прерывание TXC.
Приблизительно так:

Код
template<uart_channel_t channel> void
uart_t<channel>::tx_isr()
{
    OS::TISRW isrw;
    tx_event.SignalISR();
}

template<uart_channel_t channel> void
uart_t<channel>::udre_isr()
{
    if( tx_available() ) {
        uint8_t temp = tx_get_byte();
        if( channel == uart_ch0) {
            UDR0 = temp;
            UCSR0A |= (1 << TXC);
        } else {
            UDR1 = temp;
            UCSR1A |= (1 << TXC);
        }
    } else {
        if( channel == uart_ch0)
            UCSR0B &= ~(1 << UDRIE);
        else
            UCSR1B &= ~(1 << UDRIE);
    }
}


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 31st July 2025 - 17:38
Рейтинг@Mail.ru


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