С хорошим микроконтроллером и время летит быстро или осциллограф выходного дня

в 13:26, , рубрики: adc, cortex-m4, diy или сделай сам, microcontroller, stm32, программирование микроконтроллеров, схемотехника

Некоторое время назад автор этих строк взялся разрабатывать компактный регистратор одно-полярного аналогового сигнала в пределах 3 вольт с максимально возможной скоростью считывания и минимально возможными затратами и размерами. В список минимально возможных затрат я вписал также и свою головную боль и выбрал хорошо знакомый мне STM32F303. Это, напомню, Cortex-M4 на 72 мегагерца от известной компании, со встроенными 12 разрядными, довольно шустрыми, аналого-цифровыми преобразователями (АЦП или ADC, кому как нравится) и с CAN интерфейсом на борту.

Таких небольших регистраторов требовалось несколько десятков. А наличие у микроконтроллера корпуса о 48-ми ногах вселяло надежду на то, что получится назвать этот считыватель компактным. Интерфейс CAN, с которым у меня уже тогда были хорошие отношения, давал мне возможность объединить весь этот джаз в достаточно удобной манере.

Скорость, с которой, в конце концов, все это заработало, оказалась вполне подходящей, чтобы заявить о работоспособности выбранного подхода. Удалось добиться пол микросекундного шага дискретизации. Головной боли и ассемблера избежать не удалось, но кто об этом сейчас вспоминает?

Однако, некоторый осадок остался. Осталась мысль, что, в отношении быстродействия, выжато было не все.

И вот, совсем недавно появляется серия STM32G4 с тактовой частотой до 170 мегагерц с вариантом в маленьком корпусе, и с почти такими же шустрыми АЦП на борту в количестве пяти штук. Надо было что-то делать.

Над душой теперь никто не стоял и можно было не беспокоиться о сроках и планах.

Действительно, если об этом не думать, то можно получить удовольствие даже от работы. Но, честно говоря, о времени думать пришлось. Думать долго о времени малом (а что, поэтично).

Напрашивалась мысль, что надо начать немного с другого конца. То есть, надо исходить из минимально возможного времени выборки АЦП, которое, если исходить из описания, занимает 2.5 такта и составляет на 40 МГц (160 МГц / 4) 62.5 наносекунды. Тогда сам собой напрашивается шаг дискретизации в 100 наносекунд. Число круглое и, главное, довольно маленькое и красивое, почему бы и не попробовать?

К тому же, появилась в продаже и была куплена подходящая для экспериментов плата NUCLEO-G474RE, к которой разумно было добавить дополнительную макетную плату с двумя двухрядными разъемами, чтобы припаивать всякие провода и детали к макетной плате и не портить основную. Вот как это выглядит в готовом виде.

С хорошим микроконтроллером и время летит быстро или осциллограф выходного дня - 1

Там, снизу, есть несколько проводков и резистор с конденсатором, уж поверьте мне на слово.

Теперь надо подать подходящий электрический сигнал сразу на все четыре АЦП, затем запускать их друг за другом с постоянным шагом (сначала, при отладке, не очень коротким). Почему четыре? В соответствии с описанием, на одно преобразование каждый АЦП тратит 15 тактов или 0.025*15=375 наносекунд (почти 400). Поэтому при шаге 100 потребуется конвейер из четырех АЦП.

В качестве входного сигнала использовалась RC цепь, на которую подавалось напряжение просто от ножки контроллера. Этой ножкой я назначил управлять таймер TIM5 в режиме одиночных импульсов.

Минимальная схема соединений выглядела как показано на рисунке ниже.

С хорошим микроконтроллером и время летит быстро или осциллограф выходного дня - 2

Были задействованы ADC1-ADC4. Разрядность можно было снизить для некоторого повышения быстродействия, но 12 разрядов перевесили, поскольку не хотелось терять в точности измерений. Для запуска каждого АЦП в нужном порядке и с требуемым шагом используются три таймера (TIM2, TIM3, TIM4) и еще один таймер (TIM1) служит для синхронизации вышеуказанных трех. На рисунке 2 ниже показаны сигналы, вокруг которых все строится.

С хорошим микроконтроллером и время летит быстро или осциллограф выходного дня - 3

Зеленые стрелки показывают фронты импульсов, по которым происходит запуск соответствующих преобразователей ADC1-ADC4.

Чтобы получить задуманные 100 наносекунд пришлось снизить тактовую частоту до 160 мегагерц, чтобы все там делилось нацело как следует. Сначала шаг был установлен значительно медленнее, 4 микросекунды, чтобы спокойно проверить работу таймеров, используя прерывания, выходные порты и осциллограф. Затем по прерываниям был отлажен и заработал прямой доступ к памяти. В конечном счете только одно прерывание обрабатывается — это прерывание окончания работы от четвертого (последнего) канала прямого доступа к памяти. На рисунке ниже показаны соединения участвующих в процессе аппаратных блоков, а также четыре выходных буфера памяти.

С хорошим микроконтроллером и время летит быстро или осциллограф выходного дня - 4

Из четырех буферов памяти (на рисунке — справа) отсчеты собираются программно в один буфер результата.

В этом контроллере, в отличие от STM32F303, есть блок коммутации запросов (DMAMUX), который позволяет перенаправлять огромное количество запросов от периферийных устройств всего на 16 каналов DMA1 и на 16 каналов DMA2. В справочном руководстве (Reference manual) выходные запросы DMAMUX отсчитываются от 0, а входы каналов DMA блоков отсчитываются от 1. Не стал менять, оставил как в первоисточнике.

В качестве генератора одиночного импульса используется таймер TIM5. В нем предусмотрен удобный режим одиночного импульса. Удобство заключается в возможности установки времени до начала импульса и установки длительности самого импульса. Этот импульс получился таким как показано ниже на картинке, любезно предоставленной осциллографом, взятым напрокат.

С хорошим микроконтроллером и время летит быстро или осциллограф выходного дня - 5

Из осциллограммы видно, что подъем импульса длится 10 микросекунд, значит он должен вместить порядка 100 отсчетов.

Проект делался в IAR 8.4 вручную (то есть, без Куба и Шара), но, надеюсь, будет понятен самым разным конфессиям. Его можно посмотреть здесь.

Вот картинка содержимого отдельного буфера ADC1 и собранного из четырех источников буфера результата в районе начала входного импульса.

С хорошим микроконтроллером и время летит быстро или осциллограф выходного дня - 6

А вот содержимое этих буферов в районе пика импульса (там, где значение доходит до 2508).

С хорошим микроконтроллером и время летит быстро или осциллограф выходного дня - 7

Как видим, на участок от начала импульса до его вершины потрачен 196-95=101 отсчет.

Значит частота дискретизации составляет 10 мегагерц. Заработало на такой скорости не сразу.

Для того, чтобы добиться этого пришлось останавливать процессор пред началом работы прямого доступа к памяти (DMA1). Хорошо, что у Cortex-M4 есть специальная ассемблерная инструкция WFI (Ждать прерывания). Если этого не сделать то процессор будет мешаться под ногами у DMA и занимать шину обращениями в память, которые вполне могут подождать.

Если увеличить шаг отсчетов до 200 наносекунд, то они перестанут толкаться и заживут мирно и счастливо.

Если вовлечь в работу компаратор COMP4 и соединить его положительный вход (порт PB0) с входным сигналом, а затем использовать ЦАП (DAC1) и соединить его выход (CH1) с отрицательным входом компаратора (внутри контроллера), то получим пороговое устройство с регулируемым порогом. Прерывания от срабатывания компаратора позволят запускать общий тактовый таймер TIM1 и получить ждущий режим, как в осциллографе.

Автор: kerosinimus

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js