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

stm32f103 Странность DMA при передаче по UART2

Всем доброго дня!

 

Проблема такая: есть 8 байт, которые надо отправить по UART2. Использую DMA1 канал 7. Так вот, когда возникает прерывание DMA о полной передаче пакета то реально осциллом вижу что в этот момент передатчик UART2 выплюнул реально не 8 байт а 6. А 2 оставшихся потом досылаются. Т.е, допустим, у меня RS-485 с микрухой, где пеерключение приемника и передатчика заведено на один пин, и если управлять этим пином по запуску ДМА и вышеуказанному прерыванию то приемная сторона в моем случае недосчитается 2-х последних байт. Что, собственно, в железе и происходит.

Еррату читал, ничего похожего не нашел.

 

Кто нибудь с таким явлением сталкивался?

 

Пока вставил костыль - после прерывания ДМА вставил задержку на 3мс на отключение передатчика и включения приемника. Работает. Но на душе не спокойно.

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

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


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

DMA отправил байты в сдвиговый регистр передатчика (а там еще один буферный регистр есть) - вот и отчитался, что всю свою работу он сделал.

Далее нужно следить уже за флагом TC USART.

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


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

вижу что в этот момент передатчик UART2 выплюнул реально не 8 байт а 6. А 2 оставшихся потом досылаются.
Все верно. В UART есть буферный регистр передачи (transmission holding register) и регистр, в котором собственно и происходит сдвиг битов в процессе передачи (shift register). Вот там ваши два байта и лежат (организована двойная буферизация). Задача DMA - донести байты до UART. Оно свою задачу выполнило, о чем и рапортует прерыванием. Все указанные вами байты будут отправлены и ничего не потеряется. Для отключения передатчика RS-485 вам надо в прерывании DMA включать прерывание окончания передачи (transmission complete, TC) UARTа, а уже в нем выключать передатчик RS-485. Не ленитесь читать документацию, там очень подробно расписано и про сдвигатель, и про буферизацию, и про DMA, и про то, какие флаги когда выставляются.

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


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

Всем спс за коментарии.

исходя из задачи работы с RS-485 вижу что проще с DMA не связываться, а отправлять байты используя только прерывание TXE UART, декрементируя счетчик исходящих байтов. Когда будет 0 то включать приемник. Согласен, что можно в ДМА включить прерывание TXE, в котором потом переключать драйвер на приемник. Но вариант выше как то выглядит более "классическим" со всеми вытекающими.

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


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

а отправлять байты используя только прерывание TXE UART, декрементируя счетчик исходящих байтов. Когда будет 0 то включать приемник.
Получите то же яйцо что и сейчас, только в профиль. Прерывание TXE выставляется по освобождению буферного регистра. То есть досчитав до нуля вы будете точно так же иметь один байт в буфере и один в сдвигателе. Вам надо включать приемник в прерывании TC, transmit complete.

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


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

исходя из задачи работы с RS-485 вижу что проще с DMA не связываться, а отправлять байты используя только прерывание TXE UART, декрементируя счетчик исходящих байтов. Когда будет 0 то включать приемник. Согласен, что можно в ДМА включить прерывание TXE, в котором потом переключать драйвер на приемник. Но вариант выше как то выглядит более "классическим" со всеми вытекающими.

Откройте-же наконец-то мануал на UART. Вам тут люди уж какое сообщение втирают про флаг TC, а вы всё на DMA залипли....

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


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

А ведь в некоторых USART есть поддержка RS-485, правда сам не пользовался.

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


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

Самое нужное для поддержки RS-485 у STM32 - это бит TC. Это единственный существенный плюс STM-ного UART по сранению с NXP-ным.

Всё остальное - мелочи, без которых легко обойтись.

 

PS: Кроме прочего - не нужно забывать делать некоторую задержку при переключении RX->TX перед началом передачи.

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


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

......Когда будет 0 то включать приемник...

 

Вам уже сказали, что это не правильно. Почему так же объяснили. Надо ещё добавить, что если у Вас поверх 485 идёт модбас -

то тогда необходимо, согласно протоколу, выдерживать тайм аут до и после передачи. И его необходимо соблюдать ОБЯЗАТЕЛЬНО!!!

 

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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