Перейти к содержанию
    

Окончание передачи UART

Может, кому-то будет полезно...

 

Делал RS485 на ATMega128. Нужно было отлавливать момент окончания передачи символа - есть соответствующий бит TXC. Так вот, оказалось, что этот бит устанавливается почему-то ДО окончания передачи последнего символа (одновременно с TXE), хотя по datasheet должен по окончании. Когда по этому биту делал переключение драйвера на приём, последний символ не передавался. Пришлось делать программную задержку в виде пустого цикла.

 

Интересно, это был глюк только у меня или везде так. И также интересно, как у других ATMeg. Если кто-то сталкивался - поделитесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у меня на 64 меге все ок. По биту освобождения буфера передачи (окончания передачи) (отличается от готовности передатчика к приему следующего байта) я отключаю передатчик 485.

На глюк не похоже. Либо ошибка в программе, либо непонимание описания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может, кому-то будет полезно...

Интересно, это был глюк только у меня или везде так. И также интересно, как у других ATMeg. Если кто-то сталкивался - поделитесь.

Полезно не будет :-)

На 128, 32 - все нормально. Ищите ошибку у себя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пример передачи символа из DS не привязан к конкретной реализации интерфейса, сам налетел на эти грабли с RS485. Смотри предыдущие сообщения ( биты окончания передачи и освобождения буфера) и все будет нормально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TXE - это что за бит? Наверное, нужно читать - UDRE?

Проблема с определением окончания передачи у меня возникала только на больших скоростях (2 Mбод). При прерываниях по UDRE за время запихивания очередного (последного в последовательности на передачу) байта иногда оказывался переданным байт из сдвигового регистра - и бит TXC оказывался установленным. Сброс ТXC после записи в UDR исправляет ситуацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может, кому-то будет полезно...

 

Делал RS485 на ATMega128. Нужно было отлавливать момент окончания передачи символа - есть соответствующий бит TXC. Так вот, оказалось, что этот бит устанавливается почему-то ДО окончания передачи последнего символа (одновременно с TXE), хотя по datasheet должен по окончании. Когда по этому биту делал переключение драйвера на приём, последний символ не передавался. Пришлось делать программную задержку в виде пустого цикла.

 

Интересно, это был глюк только у меня или везде так. И также интересно, как у других ATMeg. Если кто-то сталкивался - поделитесь.

 

 

...работаю с 128 и таких проблем не было, поищете ошибку у себя

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. прошу прощения, UDRE, а не TXC...

 

2. если подскажете, буду благодарен если укажете на ошибку (сам что-то не нашёл...), хоть из ситуации и вышел, но считаю что "криво", хочется всё-таки чтобы было красивее... вот выдержка из исходника:

 

 

// ждать окончания передачи...

while((UCSR0A & (1<<TXC0)) == 0); - вот это и не даёт нужного эффекта

 

 

 

 

 

 

// очистить регистр признака приёма символов

while (UCSR0A & (1<<RXC0)) symbol = UDR0;

 

// временная задержка - подобрано - это взамен ожидания окончания передачи.

for(i=0;i<3500;i++);

 

// разрешить прерывания по приёму символов

UCSR0B = UCSR0B | (1<<RXCIE0);

 

// запретить передачу в драйвере RS-485

PORTE = PORTE & ~(1<<TxEN); - TxEN - это ножка порта E, что управляяет

драйвером 485

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Выдержка из исходника - обработчик прерывания по UDRE? Обработчика прерывания по TXC - нет? TXC сбрасывается аппаратно по обработке прерывания по TXC. Если обработчика этого прерывания нет, то бит TXC нужно сбрасывать программно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. прошу прощения, UDRE, а не TXC...

2. если подскажете, буду благодарен если укажете на ошибку (сам что-то не нашёл...)

 

Использование прерывания несколько удобнее и понятнее (по крайней мере для меня)

#pragma vector=USART0_TXC_vect
__interrupt void USART0_transmit_complete(void)
{
  usart0_status_timer = 2;
  usart0_status = Usart0WaitReceiving;
}


фрагмент процесса обслуживания порта:

switch (usart0_status)
.....
  case Usart0Transmitting:    
    if (!usart0_status_timer)
    {
      usart0_status = Usart0Unconfigured;
    }
    break;

  case Usart0WaitReceiving:
    if (usart0_status_timer == 0)
    {
      ClearRxBuffer0();
      SetReceiveDirection0();
      usart0_status = Usart0Waiting;
    }
    break;
  }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. прошу прощения, UDRE, а не TXC...

 

2. если подскажете, буду благодарен если укажете на ошибку (сам что-то не нашёл...)

Ошыбку искать впадлу, скажу в обчем:

УДРЕ устанавливается, когда регистр УДР на запись освобождается. При переносе из УДР в сдвиговый регистр УАРТа, например.

ТХС устанавливается, когда из сдвигового регистра ушол хвост стоп-бита.

 

485 драйверить надо так:

Засылаем строку в УАРТ. По УДРЕ набиваем УДР до блевоты. И контролируем загрузку последнего символа. ТХС игнорируем, т.е. запрещщяем. Загрузили последний символъ. Прерывания по УДРЕ запрещаем, сбрасываем ТХС, разрешаем прерывания по ТХС. Имеем в виду, что сейчас у нас один символ в сдвиговом регистре, второй - в УДР. Значить на втором ТХС калитку закрываем на приём.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Имеем в виду, что сейчас у нас один символ в сдвиговом регистре, второй - в УДР. Значить на втором ТХС калитку закрываем на приём.

Цитата из DS на m128: USART Control and Status Register A Bit 6 – TXCn: USART Transmit Complete

 

This flag bit is set when the entire frame in the Transmit Shift Register has been shifted

out and there are no new data currently present in the transmit buffer (UDRn).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ошыбку искать впадлу, скажу в обчем:

Имеем в виду, что сейчас у нас один символ в сдвиговом регистре, второй - в УДР. Значить на втором ТХС калитку закрываем на приём.

 

Палыч правильно сказал - прерывания по TXC не будет пока в UDR будут данные....

т.е прерывание по TXC будет только одно - по выдаче на TX стопового бита последнего передаваемого байта..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 bgc - в принципе если вам будет интересно , то я тут где то выкладывал проэктик как раз такого плана, поищите по форуму - то что он рабочий - проверял не я один и не один день, и всё работало как надо.

Если не найдёте, могу выслать - мне не жалко..

да , проверял на меге 8-й и 168-й, и 16-й..

Изменено пользователем Kuzmi4

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Палыч правильно сказал - прерывания по TXC не будет пока в UDR будут данные....

т.е прерывание по TXC будет только одно - по выдаче на TX стопового бита последнего передаваемого байта..

Да, имана так. Тормознул. В программках имана так и закладывал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делал на м640 и на 8515. Использовал все признаки и прерывания. Использовал все сигналы интерфейса. Также ни одной ошибки или неточности не находил!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...