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

Hi Rifkat !

Совсем недавно 12 May 04 10:05, Rifkat Abdulin писал к All:

RA> Столкнулся со сложностью - надо точно отследить "улет" последнего RA> байта посылки (485). Прерывание (TXIF) не дает такой инфо. TRMT не RA> дает прерываний :-() работает в фоновом режиме - запустил передачу и RA> забыл, пока счетчик байт не обнулится (конвейер в обработчике RA> прерываний). Проблема возникла с необходимостью закрыть передачу (TXEN RA> в 0) - чтобы постоянно не "тарахтели" TXIF и переключить 485 на прием.

из 18-х использовал 18f452 и 18f1320 (с одним портом)

Я обычно просто запрещаю прерывания по пустоте TXREG (сброс бита TXIE), этого хватает. И пусть себе TXIF устанавливается сколько хочет. Разрешение начала передачи очередного байта проверяю как (TXIF & TXIE). Вот кусочек программы обработки прерывания для приема-передачи. Думаю, особых проблем с расшифровкой не будет.

TMR0 используется для определения момента окончания передачи и разных вспомогательных функций (отслеживание таймаутов). tmr0sost- переменная, указывающая режим использования TMR0 (там у меня MODBUS-овский тайминг с его помощью выдерживается и контролируется), используется при обработке прерывания от TMR0. com1buf- это буфер байтов порта com1nbyte- счетчик байтов com1_n_tx_bytes- общее количество передаваемых байт (длина передаваемого пакета)

=== Cut ===

/*-----------------11.03.03 14:50------------------- прерывание по RCIF --------------------------------------------------*/ while ( (RCIE == 1) && (RCIF == 1) ) { /*-----------------15.04.04 10:23------------------- выгребаем все принятые байты (из RCREG и из FIFO ) --------------------------------------------------*/ // ***** принят новый байт *********

if ( com1nbyte >= COM1_LEN_BUF ) com1nbyte = 0; com1buf[com1nbyte] = RCREG;

if ((tmr0sost == 2) ||(tmr0sost == 3) ) { com1nbyte++; //идет прием пакета tmr0sost = 3; // грузим в TMR0 межбайтовый интервал load_tmr0_const (del_interbyte); } else { //продолжается ожидание межпакетного интервала com1nbyte = 0; // грузим в TMR0 межпакетный интервал load_tmr0_const (del_interpkt); } }

/*-----------------11.03.03 14:50------------------- прерывание по TXIF --------------------------------------------------*/ while ( (TXIF == 1) && (TXIE == 1) ) { // есть что передавать /*-----------------15.04.04 10:27------------------- заталкиваем байты до заполнения TXREG (т. е. и в TXREG, и в TSR) --------------------------------------------------*/ // **** окончена передача байта *******

TXREG = com1buf[com1nbyte]; com1nbyte++; if ( com1nbyte >= com1_n_tx_bytes) { //в буфер передатчика передан последний передаваемый байт // => до окончания его передачи осталось время = 2 байта // т.е byte-> TXREG -> TSR ->

// грузим в TMR0 интервал 2байта load_tmr0_const (del_2bytes); TXIE = 0; tmr0sost = 9; } else { // 1.5+2 = 3.5 байта //разрешенный таймаут в линии равен 1.5 байта тишины //(межбайтовый интервал внутри пакета) // грузим в TMR0 интервал 3.5 байта load_tmr0_const (del_3p5bytes); } } === Cut ===

RA> Я работаю с 2мя UART (8720). В одном после отправки последнего байта я RA> по прерыванию (TXIF)анализирую в обработчике TRMT на "пустоту" - как RA> только он освободился, TXEN в 0. Hо во втором UART это не проходит - RA> после записи в TXREG последнего байта (в обработчике RA> прерываний)посылки TXIF поднимается, по выходу из обработчика проц RA> из-за TXIF=1 снова в него впадает, но TRMT еще не успевает обнулиться RA> (показать занятость) - в рез. режется последний байт (TXEN в 0). Попробуй не трогать разрешения приема-передачи, пользуйся только разрешениями прерываний (т.е. RCIE, TXIE). Может, этого будет достаточно? То есть после засовывания в TXREG последнего байта запрещаешь прерывание (TXIE=0). USART себе спокойненько все допередает, прерывания не будет. Чтобы не обрабатывать лишний раз TXIF при попадании в прерывание по другой причине, контролируй пару флагов: TXIF и TXIE.

Hу а переход на прием делай как-нибудь иначе: либо через таймер (как у меня), либо контролируя TRMT (зациклившись или периодически, зависит от требования к точности). И еще. TRMT устанавливается не в конце, а в середине последнего стопового бита. Так что если по-честному, лучше еще пол-бита подождать перед выключением передатчика.

RA> Обработка этого UARTа производится на выходе из обработчика RA> прерываний, первого - на входе. Все по high priority. Мне приходится RA> увеличивать принудительно счетчик байтов на 1. Hеужели достаточно RA> разного кол-ва команд после загрузки в TXREG, чтобы это повлияло на RA> установку TRMT в 0? Все испытывалось на 9600. У меня 9600 хорошо (в смысле без сбоев) работает на единственном уровне прерываний при скорости 9600 и кварце 500 КГц (PIC18F1320). Сказывается наличие буфера FIFO у приемника и буфера TSR у передатчика :)

WBRgrds Ruslan

Reply to
Ruslan Mohniuc
Loading thread data ...

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

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

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

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

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

насчет TXREG - как ты его проверяешь на пустоту, не используя TXIF? Я просто не подумал "просто" глянуть на его содержимое (если он это позволяет)

Reply to
Rifkat Abdulin

Hello Rifkat.

12 Май 04 10:05, you wrote to All:

Можно узнать что делаеш

Siuchin

Reply to
Siuchin Sasha

SS> Можно узнать что делаеш

Уже сделал - запускаю в производство. Система передачи инфо по GSM/GPRS (в развитии)АСУТП. Каждый блок имеет

485й (Modbus), GSM-модем,24 дискретных изол. входа (до 52В), 8 дискр. изол. выхода (60В/400мА), 8 АЦП (в пике). Может работать как Slave - цепляется к АРМ (авт. раб. место), так и как Master (к нему вешаются датчики и пр.) - на объекте контроля. Можно и 2 АРМа вязать. + тревожные сообщ. от указанных дискретов - SMS, "сиренка". В-общем - "павлино-утко-еж" ;-)
Reply to
Rifkat Abdulin

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.