PIC - как точно отследить отправку последнего байта посылки в UART

May 12, 2004 Last reply: 22 years ago 7 Replies

Hi Rifkat, hope you are having a nice day!


12 Май 04, Rifkat Abdulin wrote to Ruslan Mohniuc:

RA> В прерываниях это как раз не хочется делать - они растягиваются ;-) RA> Я при работе с одним портом UART обычно просто смотрю на TRMT - жду, RA> пока он освободится, и лишь потом иду дальше. Hо это опять задержка - RA> фонового режима не получается.



RA> С таймерами и 3.5 байта - это я делаю.



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



WBR, AVB


Hi Rifkat !

Совсем недавно 12 May 04 14:22, Rifkat Abdulin писал к Ruslan Mohniuc:

RM>> Попробуй не трогать разрешения приема-передачи, пользуйся только RA> разрешениями RM>> прерываний (т.е. RCIE, TXIE). Может, этого будет достаточно?

RA> чтобы снова разрешить TXIE, нужно засечь момент окончания пред. RA> посылки ;-)

Hе понял. Тогда огласи всю задачу, пожалуйста. У тебя передается один пакет, после него сразу передается второй пакет? Тогда зачем переключаться на прием? Или у тебя передается пакет, после чего происходит переключение на прием?

RM>> Hу а переход на прием делай как-нибудь иначе: либо через таймер RA> (как у меня), либо контролируя TRMT (зациклившись или периодически, RA> зависит от требования к точности).

RA> В прерываниях это как раз не хочется делать - они растягиваются ;-) Да, некузяво.

RA> Я при работе с одним портом UART обычно просто смотрю на TRMT - жду, RA> пока он освободится, и лишь потом иду дальше. Hо это опять задержка - RA> фонового режима не получается.

RA> С таймерами и 3.5 байта - это я делаю.

RA> насчет TXREG - как ты его проверяешь на пустоту, не используя TXIF? RA> Я просто не подумал "просто" глянуть на его содержимое (если он это RA> позволяет) ? Да нет там никакой "пустоты". Какое значение ты в него влепил, то и есть. Hикуда я не гляжу. Я думал, в том куске программы все отображено. Словами: когда мне остается втолкнуть в TXREG последний байт передаваемого пакета (этот момент определяю по установке флага TXIF, означающего освобождение TXREG), то я его вталкиваю, устанавливаю таймер на два байта и запрещаю прерывания по передаче. В момент срабатывания таймера последний бит последнего (из этих двух) байта закончил передаваться наружу (из PIC). Все, процесс передачи полностью завершен, об этом моменте сигнализирует прерывание от таймера.

Еще я слышал о методе подслушивания: слушаешь свою же передачу и принимаешь байты. Когда принял свой последний байт- то и передача завершена. Я такого не реализовывал, но при множестве портов это хороший вариант (не нужно выделять по таймеру на канал). То есть по передаче прерывний нет вообще, только по приему: прерывание по приему возникает в момент окончания передачи байта. Да и не обязательно каждый байт так подслушивать, вполне достаточно последний ушедший в TSR. Вместо прерывания по таймеру имеем прерывание по приему :)

WBRgrds Ruslan

Hello Rifkat!

Wednesday May 12 2004 14:22, you wrote to Ruslan Mohniuc:

RA> From: Rifkat Abdulin snipped-for-privacy@kgpa.ru RA> Subject: Re: PIC - как точно отследить отправку последнего байта RA> посылки в UART (485

RM>> Попробуй не трогать разрешения приема-передачи, пользуйся только RA> разрешениями RM>> прерываний (т.е. RCIE, TXIE). Может, этого будет достаточно?

RA> чтобы снова разрешить TXIE, нужно засечь момент окончания пред. RA> посылки ;-)

Hе уверен, что это прокатит с пиками (не работал), но для 51 я использую такой трюк: перед передачей последнего байта переключаю uart в 9-битовый режим, последний бит предварительно устанавливается в '1'. Получается как-бы два стоповых бита и по последнему прерыванию можно выключать драйвер 485.

Вот выдрал кусок из обработчика прерывания uart:

=== Cut ===

// передача if (TI) { TI = 0;

switch (sio.n) { case 0 : // данных нет, окончание передачи sio_tx_dis(); // запретить передачу SM0 = 0; // возвращаем UART в режим 1 (8-bit) REN = 1; // разрешить прием sio.stio = NET_ST_OK; goto L3; // завершение команды и переход к приему адреса

case 1 : // младший байт CRC c = Lo(crc); SM0 = 1; // для последнего байта переключаем UART в режим 3 (9-bit); // прерывание после вывода последнего байта прийдет на один // битовый интервал позже, TB8==1 при этом будет играть роль // дополнительного стоп-бита; все это позволяет по последнему // прерыванию сразу переключать драйвер интерфейса с передачи // на прием; break;

case 2 : // старший байт CRC c = Hi(crc); break;

default: // данные c = sbf[sio.ix++]; crc_add (c); }

SBUF = c; sio.n--; }

=== Cut ===

RA> Rifkat < Team /Grave\ >

Best regards, Sergey.

RA>> В прерываниях это как раз не хочется делать - они растягиваются ;-) RA>> Я при работе с одним портом UART обычно просто смотрю на TRMT - жду, RA>> пока он освободится, и лишь потом иду дальше. Hо это опять задержка - RA>> фонового режима не получается.

RA>> С таймерами и 3.5 байта - это я делаю.

AV> Тогда я чего-то не понимаю. Что мешает после помещения последнего байта в TXREG AV> запрететить TXIE и запустить таймер на AV> длительность одного байта, в прерывании от таймера на всякий случай проверить AV> TMRT и выключить передатчик? Если так AV> важен фоновый режим, то это весьма неплохое решение. это понятно.

Не хочется лишний раз трогать флаги разрешения/запрещения прерываний - для надежности работы проца их статус (разр)все время подтверждается в main loop. Проц и так сильно загружен параллельной обработкой информации - кроме того, с ним в связке висят и такие "недетерминированные" устройства, как GSM-модемы.

RM>>> Попробуй не трогать разрешения приема-передачи, пользуйся только RA>> разрешениями RM>>> прерываний (т.е. RCIE, TXIE). Может, этого будет достаточно?

RA>> чтобы снова разрешить TXIE, нужно засечь момент окончания пред. RA>> посылки ;-)

RM> Или у тебя передается пакет, после чего происходит переключение на прием? ага

RM> когда мне остается втолкнуть в TXREG последний байт передаваемого пакета (этот RM> момент определяю по установке флага TXIF, означающего освобождение TXREG), то я RM> его вталкиваю, устанавливаю таймер на два байта и запрещаю прерывания по RM> передаче. В момент срабатывания таймера последний бит последнего (из этих двух) RM> байта закончил передаваться наружу (из PIC). Все, процесс передачи полностью RM> завершен, об этом моменте сигнализирует прерывание от таймера.

это понятно. "Нормальные герои всегда идут в обход" ;-) Проблема в том, что очень не хочется трогать TXIE и пр. разрешения прерываний - для надежности работы проца их статус (ВКЛ) все время подтверждается в main loop.

RM> Еще я слышал о методе подслушивания: слушаешь свою же передачу и принимаешь RM> байты. Когда принял свой последний байт- то и передача завершена. Я такого не RM> реализовывал, но при множестве портов это хороший вариант (не нужно выделять по RM> таймеру на канал). То есть по передаче прерывний нет вообще, только по приему: RM> прерывание по приему возникает в момент окончания передачи байта. RM> Да и не обязательно каждый байт так подслушивать, вполне достаточно последний RM> ушедший в TSR. Вместо прерывания по таймеру имеем прерывание по приему :)

это тоже понятно - в крайнем случае придется делать

RM> WBRgrds RM> Ruslan

SS> Hе уверен, что это прокатит с пиками (не работал), но для 51 я использую SS> такой трюк: перед передачей последнего байта переключаю uart в 9- битовый SS> режим, последний бит предварительно устанавливается в '1'. Получается как-бы SS> два стоповых бита и по последнему прерыванию можно выключать драйвер 485.

SS> Вот выдрал кусок из обработчика прерывания uart:

SS> case 1 : // младший байт CRC SS> c = Lo(crc); SS> SM0 = 1; SS> // для последнего байта переключаем UART в режим 3 (9-bit); SS> // прерывание после вывода последнего байта прийдет Вот здесь и проблема - нет в пиках прерывания по выводу байта - только по загрузке в буфер передатчика ;-)

Здраствуйте Ruslan,

*12.05.04* *22:26:02* Вы писали в *RU.EMBEDDED* сообщение к *Rifkat Abdulin* о *"PIC - как точно отследить отправку последнего байта посылки в UART "*.

RM> Еще я слышал о методе подслушивания: слушаешь свою же передачу и RM> принимаешь байты.

Если в линии пойдут коллизии, вся эта схема накроется, но можно тестировать линию на наличие коллизий.

С уважением, Den

Hi Den !

Совсем недавно 13 May 04 13:56, Den Y. Borisov писал к Ruslan Mohniuc:

RM>> Еще я слышал о методе подслушивания: слушаешь свою же передачу и RM>> принимаешь байты.

DB> Если в линии пойдут коллизии, вся эта схема накроется, но можно DB> тестировать линию на наличие коллизий.

В этом есть как хорошие, так и плохие стороны:

Хорошие стороны: передатчик может предсказать, что пакет не будет доставлен, в момент окончания передачи или даже раньше (если весь пакет подслушивался). Если этот передатчик является ведущим, то он тут же может повторить запрос, сэкономив время ( иначе бы ждал ответа). В общем случае, появляется возможность отслеживать возникновение коллизий во время передачи (чем-то мне это CAN напоминает :)

Плохие стороны: все остальное :). А насчет накроется, так можно и предусмотреть выход из передачи и по таймауту какому-нибудь.

WBRgrds Ruslan

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required