Некоторое время назад автор этих строк взялся разработать компактный регистратор униполярного аналогового сигнала в пределах 3 вольт с максимально возможной скоростью считывания и минимально возможными стоимостью и размерами.
Я тоже включил свою головную боль в список минимально возможных затрат и выбрал хорошо знакомый мне STM32F303. Напомню, это 72-мегагерцовый Cortex-M4 от известной компании, со встроенными 12-битными, достаточно быстрыми аналого-цифровыми преобразователями (АЦП или АЦП, кому как нравится) и CAN-интерфейсом.
на борту.
Потребовалось несколько десятков таких небольших регистраторов.
А наличие 48-ногого корпуса на микроконтроллере давало надежду, что этот ридер можно назвать компактным.
CAN-интерфейс, с которым у меня уже тогда были хорошие отношения, дал мне возможность достаточно удобно объединить весь этот джаз.
Скорость, с которой все это в итоге заработало, оказалась вполне подходящей для того, чтобы заявить об эффективности выбранного подхода.
Нам удалось добиться шага выборки в полмикросекунды.
Головной боли и ассемблера избежать не удалось, но кто сейчас об этом помнит? Однако некоторый осадок остался.
Осталась мысль, что по производительности не всё выжали.
И вот, совсем недавно, появилась серия STM32G4 с тактовой частотой до 170 МГц, с опцией в небольшом корпусе и с практически такими же быстрыми АЦП на борту в количестве пяти штук.
Что-то должно было быть сделано.
Теперь никто не стоял над моей душой и не нужно было волноваться о сроках и планах.
Действительно, если об этом не думать, то можно даже получать удовольствие от своей работы.
Но, если честно, мне пришлось подумать о времени.
Думать долго о малом времени (и что, поэтично).
Напрашивалась мысль, что надо начать немного с другого конца.
То есть надо исходить из минимально возможного времени выборки АЦП, которое, исходя из описания, занимает 2,5 такта и составляет 62,5 наносекунды на частоте 40 МГц (160 МГц/4).
Тогда естественно напрашивается шаг выборки в 100 наносекунд. Цифра круглая, а главное довольно маленькая и красивая, почему бы не попробовать? Кроме того, в продаже появилась и была куплена пригодная для экспериментов плата NUCLEO-G474RE, к которой имело смысл добавить дополнительную макетную плату с двумя двухрядными разъемами, чтобы припаивать к макетной плате всякие провода и детали и не испортить главное.
Вот как это выглядит в готовом виде.
Там внизу несколько проводов и резистор с конденсатором, поверьте мне на слово.
Теперь нужно подать подходящий электрический сигнал сразу на все четыре АЦП, затем запустить их друг за другом с постоянным шагом (вначале, при отладке, не очень коротким).
Почему четыре? Согласно описанию, на одно преобразование каждый АЦП тратит 15 тактов или 0,025*15=375 наносекунд (почти 400).
Следовательно, на шаге 100 потребуется конвейер из четырех АЦП.
Входным сигналом была RC-цепь, на которую подавалось напряжение просто с ножки контроллера.
Эту ногу я назначил для управления таймером TIM5 в режиме одиночных импульсов.
Минимальная схема подключения выглядела как на рисунке ниже.
Были задействованы ADC1-ADC4. Разрядность можно было бы уменьшить, чтобы немного улучшить производительность, но 12 бит перевешивали, потому что мы не хотели терять в точности измерений.
Для запуска каждого АЦП в нужном порядке и с нужным шагом используются три таймера (TIM2, TIM3, TIM4) и еще один таймер (TIM1) используется для синхронизации трех вышеуказанных.
На рисунке 2 ниже показаны сигналы, вокруг которых все построено.
Зелеными стрелками показаны фронты импульсов, запускающих соответствующие преобразователи АЦП1-АЦП4. Чтобы получить намеченные 100 наносекунд, нам пришлось снизить тактовую частоту до 160 мегагерц, чтобы там все разделилось как надо.
Сначала шаг был установлен значительно медленнее, 4 микросекунды, чтобы незаметно проверить работу таймеров с помощью прерываний, выходных портов и осциллографа.
Затем прерывания были отлажены и заработал прямой доступ к памяти.
В конечном итоге обрабатывается только одно прерывание: прерывание конца выполнения из четвертого (последнего) канала DMA. На рисунке ниже показаны соединения аппаратных блоков, участвующих в процессе, а также четыре выходных буфера памяти.
Из четырех буферов памяти (справа на рисунке) выборки программно собираются в один буфер результатов.
Этот контроллер, в отличие от STM32F303, имеет блок коммутации запросов (DMAMUX), который позволяет перенаправлять огромное количество запросов от периферийных устройств всего на 16 каналов DMA1 и 16 каналов DMA2. В Справочнике выходные запросы DMAMUX отсчитываются с 0, а входы каналов блока DMA – с 1. Я не менял, оставил как в первоисточнике.
Таймер TIM5 используется как генератор одиночных импульсов.
Имеет удобный одноимпульсный режим.
Удобство заключается в возможности установить время до начала импульса и установить длительность самого импульса.
Этот импульс получился таким, как показано ниже на картинке, любезно предоставленной арендованным осциллографом.
Из осциллограммы видно, что нарастание импульса длится 10 микросекунд, значит, он должен содержать около 100 отсчетов.
Проект сделан в IAR 8.4 вручную (то есть без Куба и Шарика), но надеюсь будет понятен самым разным конфессиям.
Вы можете посмотреть это Здесь .
Вот изображение содержимого отдельного буфера АЦП1 и буфера результатов, собранного из четырех источников вблизи начала входного импульса.
Но содержимое этих буферов находится в районе пика импульса (где значение достигает 2508).
Как видите, на участке от начала импульса до его вершины было затрачено 196-95=101 отсчет. Это означает, что частота дискретизации составляет 10 мегагерц.
На такой скорости сразу не получилось.
Чтобы добиться этого, нам пришлось остановить процессор перед запуском прямого доступа к памяти (DMA1).
Хорошо, что у Cortex-M4 есть специальная инструкция по сборке.
ВФИ (Дождитесь прерывания).
Если этого не сделать, процессор встанет на пути DMA и займет шину обращениями к памяти, с чем вполне возможно придется подождать.
Если увеличить шаг счета до 200 наносекунд, то они перестанут толкаться и будут жить мирно и счастливо.
Если мы используем компаратор COMP4 и подключим его положительный вход (порт PB0) к входному сигналу, а затем используем ЦАП (DAC1) и подключим его выход (CH1) к отрицательному входу компаратора (внутри контроллера), мы получим пороговое устройство с регулируемым порогом.
Прерывания от работы компаратора позволят запустить общий тактовый таймер TIM1 и получить режим ожидания, как в осциллографе.
Теги: #Программирование микроконтроллеров #stm32 #Сделай сам или Сделай сам #схемотехника #АЦП #cortex-m4 #микроконтроллер
-
Ошибки В Профиле В Опере
19 Oct, 24