Halfback 0 30 июня, 2014 Опубликовано 30 июня, 2014 (изменено) · Жалоба Всем доброго дня! Проблема такая: есть 8 байт, которые надо отправить по UART2. Использую DMA1 канал 7. Так вот, когда возникает прерывание DMA о полной передаче пакета то реально осциллом вижу что в этот момент передатчик UART2 выплюнул реально не 8 байт а 6. А 2 оставшихся потом досылаются. Т.е, допустим, у меня RS-485 с микрухой, где пеерключение приемника и передатчика заведено на один пин, и если управлять этим пином по запуску ДМА и вышеуказанному прерыванию то приемная сторона в моем случае недосчитается 2-х последних байт. Что, собственно, в железе и происходит. Еррату читал, ничего похожего не нашел. Кто нибудь с таким явлением сталкивался? Пока вставил костыль - после прерывания ДМА вставил задержку на 3мс на отключение передатчика и включения приемника. Работает. Но на душе не спокойно. Изменено 30 июня, 2014 пользователем Halfback Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 30 июня, 2014 Опубликовано 30 июня, 2014 · Жалоба DMA отправил байты в сдвиговый регистр передатчика (а там еще один буферный регистр есть) - вот и отчитался, что всю свою работу он сделал. Далее нужно следить уже за флагом TC USART. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 30 июня, 2014 Опубликовано 30 июня, 2014 · Жалоба вижу что в этот момент передатчик UART2 выплюнул реально не 8 байт а 6. А 2 оставшихся потом досылаются.Все верно. В UART есть буферный регистр передачи (transmission holding register) и регистр, в котором собственно и происходит сдвиг битов в процессе передачи (shift register). Вот там ваши два байта и лежат (организована двойная буферизация). Задача DMA - донести байты до UART. Оно свою задачу выполнило, о чем и рапортует прерыванием. Все указанные вами байты будут отправлены и ничего не потеряется. Для отключения передатчика RS-485 вам надо в прерывании DMA включать прерывание окончания передачи (transmission complete, TC) UARTа, а уже в нем выключать передатчик RS-485. Не ленитесь читать документацию, там очень подробно расписано и про сдвигатель, и про буферизацию, и про DMA, и про то, какие флаги когда выставляются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Halfback 0 30 июня, 2014 Опубликовано 30 июня, 2014 · Жалоба Всем спс за коментарии. исходя из задачи работы с RS-485 вижу что проще с DMA не связываться, а отправлять байты используя только прерывание TXE UART, декрементируя счетчик исходящих байтов. Когда будет 0 то включать приемник. Согласен, что можно в ДМА включить прерывание TXE, в котором потом переключать драйвер на приемник. Но вариант выше как то выглядит более "классическим" со всеми вытекающими. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 30 июня, 2014 Опубликовано 30 июня, 2014 · Жалоба а отправлять байты используя только прерывание TXE UART, декрементируя счетчик исходящих байтов. Когда будет 0 то включать приемник.Получите то же яйцо что и сейчас, только в профиль. Прерывание TXE выставляется по освобождению буферного регистра. То есть досчитав до нуля вы будете точно так же иметь один байт в буфере и один в сдвигателе. Вам надо включать приемник в прерывании TC, transmit complete. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 30 июня, 2014 Опубликовано 30 июня, 2014 · Жалоба исходя из задачи работы с RS-485 вижу что проще с DMA не связываться, а отправлять байты используя только прерывание TXE UART, декрементируя счетчик исходящих байтов. Когда будет 0 то включать приемник. Согласен, что можно в ДМА включить прерывание TXE, в котором потом переключать драйвер на приемник. Но вариант выше как то выглядит более "классическим" со всеми вытекающими. Откройте-же наконец-то мануал на UART. Вам тут люди уж какое сообщение втирают про флаг TC, а вы всё на DMA залипли.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 30 июня, 2014 Опубликовано 30 июня, 2014 · Жалоба А ведь в некоторых USART есть поддержка RS-485, правда сам не пользовался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 30 июня, 2014 Опубликовано 30 июня, 2014 · Жалоба Самое нужное для поддержки RS-485 у STM32 - это бит TC. Это единственный существенный плюс STM-ного UART по сранению с NXP-ным. Всё остальное - мелочи, без которых легко обойтись. PS: Кроме прочего - не нужно забывать делать некоторую задержку при переключении RX->TX перед началом передачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 30 июня, 2014 Опубликовано 30 июня, 2014 · Жалоба ......Когда будет 0 то включать приемник... Вам уже сказали, что это не правильно. Почему так же объяснили. Надо ещё добавить, что если у Вас поверх 485 идёт модбас - то тогда необходимо, согласно протоколу, выдерживать тайм аут до и после передачи. И его необходимо соблюдать ОБЯЗАТЕЛЬНО!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться