Не так давно я уже писал заметку про новый микроконтроллер MIK32 AMUR от отечественного производителя АО "Микрон" и отладочную плату NUKE MIK32 на его базе. В одном из наших изделий мы планируем применить этот МК для измерения расхода жидкости и выдачи усредненного параметра в цифровом виде. В связи с чем появилась необходимость проверить как работает АЦП в составе этой микросхемы. Микроконтроллер MIK32 "AMUR" укомплектован одним многоканальным аналого-цифровым преобразователем разрядностью 12 бит к входу которого можно подключать до 8 сигналов через встроенный аналоговый коммутатор. В данной статье я приведу пример кода для работы этим АЦП и опишу выявленные проблемы и особенности.

Сборка примера
Ссылка на репозиторий с примером кода для опроса АЦП и выдачей усредненного результата на UART0.
Репозиторий содержит оригинальный пример от поизводителя доработанный для поддержки платы NUKE MIK32 V0.3 от этого же производителя. На этой плате требуется снять перемычки с разъема COM13 и соединить двумя патчами сигналы RX/TX от FTDI с противоположными сигналами порта UART0 на MIK32, то есть FT_TX соединить с P0.5, а FT_RX с P0.6 (см. картинку на КДПВ). После чего порт UART0 микроконтроллера будет доступен как /dev/ttyUSB0 при покдлючении отладочной платы к USB порту. Параметры порта: 9600, 8N1.
В исходном коде добавлено определение макро MIK32V2 которое участвует в инициализации АЦП внутри библиотеки HAL. Без него АЦП на данной плате работает неверно. Для сборки под другие платы будьте внимательны, проверяйте версию микроконтроллера и устанавливайте соответствующие макро в коде, в Makefile-е или в коммандной строке через флаг
-DMIK32V2
.Сборка примера осуществляется командой
make
. Перед сборкой необходимо подправить Makefile и указать в нем путь к компилятору GCC с поддержкой архитектуры RV32IMC. Так же необходимо указать пути к репозиториям содержащие библиотеки mik32-hal и mik32-shared от производителя.Прошивка осуществляется командой
make upload
. Перед прошивкой небходимо установить пакет поддержки openocd (имеется абсолютно во всех Linux и *BSD дистрибутивах), а так же скрипт для программирования mik32-uploader.
Проблемы и особенности АЦП на MIK32
Проблема с коммутацией каналов. Микроконтроллер MIK32 AMUR содержит один блок аналого-цифрового преобразователя к которому можно подключить до 8 источников сигнала через встроенный коммутатор аналоговых каналов. Это означает, что в каждый конкретный момент времени производится только одно измерение. Чтобы измерять сигналы различных каналов необходимо динамически переключать (перекоммутировать каналы). Переключение каналов осуществляется записью соответствующего битового значения в регистр коммутации. Проблема состоит в том, что коммутация производится не сразу, и не перед конверсией (единичным измерением), а только по его завершению. Это накладывает определенные сложности на алгоритм захвата данных: коммутацию каналов нужно выполнять либо во время конверсии, что не удобно если программа работает по прерываниям, либо проводить одну лишнюю конверсию для переключения канала перед запуском серии измерений с выбранного канала.
Проблема большой ошибки смещения нуля (offset error). На моём устройстве ошибка смещения составляет около 170 отсчетов АЦП, что составляет более 5% его динамического диапазона. Ошибка смещения примерно одинакова по всем каналам. В спецификации этот параметр не указан.
В руководстве на микросхему сказано, что входное напряжение на АЦП не должно быть менее 15 мВ, однако АЦП отзывается уже при 1 мВ на его входе. Оценка линейности работы АЦП мной не производилась, но есть основания полагать, что эти 15 мВ (то есть еще 51 осчет АЦП) так же можно вычесть из динамического диапазон��. Таким образом, динамический диапазон сужается до 3875 отсчетов или 71,7 dB (в спецификации указан 71,9 dB).
Опорное (референсное) напряжение на АЦП у MIK32 установлено в 1,2 В и согласно спецификации не может превышать 1,3 В. Это может создать некоторое неудобство разработчикам привыкшим к тому, что блоки АЦП во многих импортных микроконтроллерах имеют опорное напряжение 2,5 В, либо опорное для них может быть произвольно задано в пределах напряжения питания микросхемы. Не смотря на то, что у ЦАП и АЦП в микроконтроллере MIK32 имеется отдельный вход для подачи опорного напряжения, попытка подать более 1,3 В (и установка соответствующих значений в регистрах) ни к чему хорошему не приводит, АЦП все так же достигает максимального значения при напряжении около 1,3 В.
Пульсации и дрейф АЦП. При длительном замере постоянного напряжения на входе АЦП было установлено, что показания АЦП дрейфуют вокруг одной точки с различным периодом, от 5 до 25 секунд. Размах ошибки составляет до 24 отсчетов АЦП, стадартное отклонение составляет 3,85 LSB. Установка фильтрующего конденсатора высокой емкости на входе АЦП не устраняет дрейф и не уменьшает ошибку. Это означает, что три младших бита АЦП можно считать незначащими и таким образом эффективная разрядность АЦП не превышает 9 бит.
Расчёт эффективного числа бит (ENOB)
Для расчета ENOB на вход АЦП было подано постоянное напряжение в средней точке его динамического диапазона (0,6 В) и снято 120 тыс измерений с частотой 1000 Гц. Далее по формулам было вычислено стандартное отклонение, соотношенеи SNR и ENOB. Расчетное ENOB составило 8,94 бит. В спецификации указан ENOB = 11.94 бит (10.5 min) и я склонен ей верить. Чем вызван такой разброс измерений в моё случае еще предстоит выяснить, надеюсь зоркий глаз пользователя Хабр подскаже где находится ошибка в моих расчетах. Таблица с расчётами в формате .ODS (LibreOffice Calc) находится в репозитории.
Тестирование проводилось на плате NUKE MIK32 v0.3, № партии: MK32-ПП 31052024-500, серийный номер не указан. Плата не содержит импульсных преобразователей напряжения.

Заключение
В целом встроенный АЦП в микроконтроллере MIK32 годен для применения в приборах невысокой точности, в частности для домашней автоматизации, и позволяет сэкономить на установке внешнешней микросхемы АЦП. Программирование АЦП, за исключением нюанса с переключением каналов, мало чем отличается от других одноклассников.
Update
Уже после написание этой статьи было установлено, что если не переключать каналы АЦП, а проводить замер сигнала с одного и того же канала непрерывно, то ошибка уменьшается в несколько раз, до 1-2 мВ. В случае с непрерывной коммутацией каналов ошибка составляет 3-5 мВ на этом же стенде, с этим же питанием и этими же проводами и потенциометром в качестве задатчика входного напряжения. Вероятно аналоговый коммутатор внутри МК осуществляет перенос заряда при переключении каналов, чтобы нивелировать этот эффект в код требуется вставлять холостые циклы опроса АЦП после каждого переключения. Измеренный ENOB при отсутствии переключения каналов дает 9,53 бита.
