OSDev
http://osdev.su/

Прерывание по завершению передачи UART в STM32
http://osdev.su/viewtopic.php?f=18&t=4112
Страница 1 из 1

Автор:  JackKatch [ 08 фев 2025, 14:36 ]
Заголовок сообщения:  Прерывание по завершению передачи UART в STM32

Уже давненько была задача реализовать приёмопередатчик на STM32 (вроде удлинителя RS485, опустим подробности).
Сама по себе задача простая, принял от хоста посылку, передал в устройство. Ни чего "военного".

С архитектурой STM32 до этого дела не имел, опыт был с 8-ми битными микроконтроллерами SiLabs
(кстати очень мне понравились они организационно, т.е. документация и среда разработки удобная для меня,
есть примеры работы со всеми устройствами на борту).

Вот так, не ожидая неприятностей, приступил к работе. В протоколе обмена есть такая особенность,
иногда выполняется запрос в один байт, на который абонент отвечает очень быстро. То есть, необходимо
как можно быстрее, после передачи, переключить приёмопередатчик RS485. Раньше я считал,
что прерывание микроконтроллера по завершению передачи происходит в середине стопового бита.
(Именно так у SiLabs и Dallas).

Поэтому, нужно выждать паузу, равную половине бита для текущей скорости обмена, после чего
выполнять переключение приёмопередатчика. Иначе стоповый бит будет обрезан, что приведёт к
ошибке передачи. Запустил устройство, вижу постоянные сбои связи. Ни каких аппаратных средств не было
(вроде осциллографа и т.д.). Подробностей уже не помню, экспериментально установил, что увеличение
паузы перед переключением приёмопередатчика снижает частоту сбоев связи. В конце-концов, нашёл
достаточно большое значение паузы, при котором наблюдал стабильный обмен в течении часа.

Выводы следующие.
Либо из-за моего слабого знакомства с STM32, я где то ошибся в программе,
либо у STM32 прерывание "плавает" т.е. происходит не точно в середине стопового бита.

(Небольшое отступление от темы. Если бы я не наталкивался раньше на аппаратные ошибки в микросхемах,
то однозначно считал бы это своей ошибкой. Так бывает чаще всего. Но у STM32 документ с аппаратными ошибками
чуть ли не толще мануала. Ну шучу конечно, просто он объёмный. Вот например АЦП AD7730 обычный в DIP
корпусе работает "нормально", а мало потребляющий с буквой L и почему то только в планарном корпусе,
в одном из диапазонов работы шумит. Программа одна и та же, переключил диапазон, всё нормально и там и там.
Вернулся на другой диапазон, у L-ки шум, у обычной норма.)

Внимание вопрос, когда происходит прерывание по завершению передачи по UART в STM32?
Наблюдал ли кто нибудь подобный эффект? (возможно просто партия была с дефектом)

Если кому то "скучно" или просто сильно любопытный, могу выложить весь проект с иcходным кодом. Там ни чего секретного нет.

Из разряда догадок. Возможно причина в раздельном тактировании периферии у STM32. Читал когда то статью,
о преобразователях интерфейса различных производителей. Там говорилось (пишу по памяти), что частота
дискретизации у разных производителей отличалась. У большинства 8 - 16 дискрет на бит передачи,
у SiLabs 128 - 256 дискрет на бит передачи. Возможно в этом причина неточности.

Автор:  SII [ 10 фев 2025, 02:02 ]
Заголовок сообщения:  Re: Прерывание по завершению передачи UART в STM32

Первым пунктом -- придирки :) Нет архитектуры STM32, это -- обозначение целой кучи разных микроконтроллеров, основанных на процессорных ядрах архитектур ARMv7-M (большинство), ARMv6-M (некоторые самые мелкие ранние) и ARMv8-M (некоторые недавно появившиеся). Но точно те же ядра используются и в великом множестве микроконтроллеров других фирм (NXP, Microchip etc etc -- включая наш Миландр).

По периферии: для большинства периферийных контроллеров у STM32 есть две совершенно разных реализации. Скажем, обычные GPIO -- один тип у семейства STM32F1 (самого раннего из выпущенных) и другой тип у всех остальных; USB Device -- две разных реализации, и т.д. (плюс в пределах каждой реализации могут быть не очень большие различия для разных семейств микроконтроллеров -- скажем, различаться количество поддерживаемых конечных точек USB при общей одинаковости контроллера в остальных аспектах). UART не исключение -- их, кажется, два варианта, поэтому для начала надо знать, с каким семейством МК работаете.

Ну и по самой задаче я недопонял. Что делает STM32? Сидит, ждёт поступления некоего байта, получив который, должен немедленно ответить? Или наоборот, посылает байт и должен как можно быстрей перейти на приём?

Автор:  JackKatch [ 10 фев 2025, 09:25 ]
Заголовок сообщения:  Re: Прерывание по завершению передачи UART в STM32

Микроконтроллер STM32F030C8. Устройство можно назвать "прозрачным удлинителем линии". Есть прибор, который по кабельному каналу RS485 опрашивает "интеллектуальный датчик". У устройства одна задача, принимать данные из одного канала и передавать в другой. То есть прибор отправляет запрос (один или несколько байт), микроконтроллер принимает данные из одного UART и сразу же передаёт в другой UART. Ну естественно переключает приёмопередатчики. "Интеллектуальный датчик" принимает запрос, думает и отправляет ответ. Иногда приходит запрос в один байт и "интеллектуальный датчик" не думает, а сразу же (если не ошибаюсь в прерывании по приёму) отправляет ответ. Микроконтроллер принимает ответ и передаёт в прибор. (Ну накрутил я, надеюсь понятно). Ещё раз, есть прибор, "интеллектуальный датчик", они соединены кабелем (RS485), в "середине длинны кабеля" устройство на STM32. Устройство просто транслирует всё что принимает из одного канала в другой.

Автор:  SII [ 11 фев 2025, 01:23 ]
Заголовок сообщения:  Re: Прерывание по завершению передачи UART в STM32

1) Переключение приёмопередатчиков -- линиями RTS? (у местных UARTов есть режим RS-485, где RTS используется как раз для этой цели).

2) UART должен тактироваться достаточно высокой частотой, иначе он тормознуто меняет свои биты состояния, а соответственно, тормознуто выставляет запросы прерываний.

3) А приоритеты прерываний правильно стоят? У M-профиля ARM они же перевёрнутые: 0 -- высший приоритет, FF -- низший.

4) Хотя я, решая такую задачу, прерывания бы не использовал: чисто программный опрос в непрерывном цикле, ведь у проца всё равно никакой другой работы нет. Соответственно, обнаружив, что последний байт ушёл, сразу бы запрещал передатчик и разрешал приёмник.

Автор:  JackKatch [ 11 фев 2025, 09:59 ]
Заголовок сообщения:  Re: Прерывание по завершению передачи UART в STM32

Я посмотрю и отвечу точно. По памяти 1) скорее всего нет, мне дали готовую схему, где провода переключения уже куда то приходили. 2) UART тактируется от источника 48МГц , вспоминаю STM-мовский конфигуратор, там куча делителей каких то. Посмотрю точнее. 3) Про приоритеты вообще не помню, возможно я их не трогал. 4) Прерывания задействованы. Если правильно помню, взял из какого то своего рабочего примера. Две очереди, по прерыванию помещаю принятое в очередь, а в основном цикле если очередь не пуста, то передаю.

Автор:  JackKatch [ 11 фев 2025, 11:50 ]
Заголовок сообщения:  Re: Прерывание по завершению передачи UART в STM32

Посмотрел. Всё от 48МГц работает, управление первым приёмопередатчиком как раз на аппаратную ногу, но я аппаратное управление не использовал. Второй почему то управляется двумя сигналами т.е. DE RE не объединены. Приоритеты прерывания не трогал, по сбросу вроде наивысший приоритет. В STM-ом конфигураторе ещё какие то прерывания включены (запрос на системное обслуживание и ещё что то). Не использовать прерывания, наверное, неплохая идея в данном случае. Ну заработался уже не подумал. Чем больше вспоминаю этот проект, тем больше сомнения. Почему я грешил на момент прерывания в STM? Сомневаюсь я, что момент прерывания мог смещаться в меньшую сторону (что бы обрезать стоповый бит). Наверное проблема в совпадении нескольких ошибок, какие то гонки может быть. Непонятная ошибка, "плавающий" дефект самое плохое дело.

Автор:  SII [ 11 фев 2025, 20:36 ]
Заголовок сообщения:  Re: Прерывание по завершению передачи UART в STM32

К слову, лично я никогда не использую стандартные библиотеки от производителей, всегда своё пишу, в т.ч. достаточно сложное, вроде SD/MMC и USB. Предпочитаю иметь дело со своими ошибками: их искать и отлаживать проще :)

Ну а сдвиг прерывания в раннюю сторону... Вообще, при передаче прерывание выдаётся (точней, битик устанавливается), если склероз не изменяет, когда передаваемый символ попал из буфера данных в FIFO или в сдвиговый регистр передатчика -- т.е. в момент, когда в буфер можно класть следующий символ. Соответственно, это прерывание может произойти раньше, чем окончится фактическая передача, а значит, переключаться на приём в обработчике именно этого прерывания нельзя -- надо дождаться окончания фактической передачи.

Автор:  JackKatch [ 12 фев 2025, 10:13 ]
Заголовок сообщения:  Re: Прерывание по завершению передачи UART в STM32

Хорошая идея, вполне возможно, что так и есть. Да, если нужно решить какой то вопрос, всегда нужен оппонент. Спасибо за идею. Самостоятельно можно по кругу долго ходить.

Смутно припоминаю, что в STM32 есть двойной буфер у передатчика. Возможно действительно прерывание устанавливают, когда первый буфер готов принять очередной байт. Вероятно правильная стратегия использовать аппаратные сигналы управления приёмопередатчиком. Не уверен, что в ближайшее время будет возможность это проверить, но желание есть.

Микроконтроллеры мне всегда нравились именно этим, что всё полностью я делал сам. Но похоже такая практика "вымирает". Мне это школу напоминает, пришел кто то в вязанной шапке с бубончиком, на следующий день вся школа в таких шапках. Открываешь какую нибудь вакансию, а там, C++, FreeRTOS, ещё много умных слов. Я про себя добавляю: "Умение играть на баяне будет преимуществом".

Автор:  SII [ 13 фев 2025, 00:48 ]
Заголовок сообщения:  Re: Прерывание по завершению передачи UART в STM32

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

А баян -- это хорошо, ага. Я когда-то немного умел (как ща немного умею на пианино) :)

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/