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 есть две совершенно разных реализации. Скажем, обычные 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/ |