Тест точности ЦАП и АЦП на STM32F100

Задумал одну схемку, активно использующую АЦП и ЦАП. Планирую использовать преобразователи, имеющиеся в STM32. И вот задумался, насколько они там точные. В даташите, конечно, есть данные про точность, но понять по ним, насколько результат будет точным на практике, не так просто. Значит будем проверять на практике.
Как проверить точность ЦАП? Выдавать все значения подряд, замеряя напряжение на выходе, очевидно. А как проверить точность АЦП? Подавать плавно меняющееся напряжение, записывая значение с выхода. Ага, значит можно это совместить, построить конвейер число — ЦАП — аналог — АЦП — число.

Для проверки берем STM32VLDiscovery. ЦАП1 находится на ножке PA4. АЦП1.3 — на ножке PA3. Отлично, замыкаем их джампером. На USART1 вешаем переходник на USB, чтобы скидывать результат через виртуальный COM-порт на комп для анализа.

Из разных статей сообщества надёргиваем код для работы с USART, ADC, DAC, собираем страшненькую прошивку Франкенштейна. Алгоритм работы этого монстрика следующий. Для всех чисел от 0 до 4095 устанавливаем ЦАП. Ждем 2 мс. Делаем 10 замеров АЦП, с паузами 2 мс. Отправляем результаты в порт. Паузы в измерениях сделал для того, чтобы уменьшить результат наводок от бытовой электросети. 10 измерений по 2 мс как раз получается один период от 50 Гц. Но судя по всему, эти предосторожности оказались лишними.

Данные отправляются в порт в текстовом виде:

0864 {0863 0863 0863 0863 0863 0863 0863 0863 0863 0863} 0863
0865 {0864 0864 0864 0864 0864 0864 0864 0864 0864 0864} 0864
0866 {0865 0865 0865 0865 0865 0865 0865 0865 0865 0865} 0865
0867 {0867 0866 0866 0866 0866 0866 0866 0866 0866 0866} 0866

Первое число — значение ЦАП.
В фигурных скобках — значения АЦП, 10 штук.
Последнее — среднее значение.

Для визуализации результатов набросал прожку на Дельфи 7, которая строит график, по горизонтали вход ЦАП, по вертикали — выход АЦП. Масштаб один к одному. В идеале должна получаться диагональная линия.

Для начала пробовал разные значения делителя частоты для АЦП. При максимальной скорости (RCC_PCLK2_Div2) отклонение от идеала оказалось весьма значительным. На RCC_PCLK2_Div8 — значительно лучше.
Сверху вниз: — Div2, Div4, Div6, Div8.

Серая линия — «идеал», красные точки — результат измерения, зелёные — среднее. Горизонталь — вход, вертикаль — выход.
Полный график (графики большие! смотрите чтобы монитор не разорвало!)

В середине графика виден «дребезг» перехода через середину диапазона:

Пока что результат не очень. Оно и понятно, вход АЦП имеет слишком низкое сопротивление, по сравнению с сопротивлением выхода ЦАП. Но в STM32 можно включить выходной буфер на выходе ЦАП. Попробуем с ним.

Ага, ситуация несколько улучшилась, на всех тактовых скоростях точность улучшилась, отклонения от линии идеала стало меньше. Но, как впрочем и предупреждал даташит, у выходного буфера диапазон выдаваемых напряжений несколько урезан. Нормально выдавать заданное напряжение ЦАП со включенным буфером может примерно со значения 85, что соответствует 70 мВ. Это даже меньше обещанных даташитом 200 мВ. Аналогичная ситуация и в верхах.

Но в целом картина далека от идеала. Полный график.
Видны непонятно откуда взявшиеся нелинейности. Но повторные проходы теста дают почти 100% повторяющийся результат, т.е. значения можно откалибровать по заранее построенной таблице, при необходимости.

Настало время последнего параметра, влияющего на точность, время выборки (sampling time) АЦП в тактах. До этого он стоял на минимуме, 1.5 такта. Его можно выбирать из 8 вариантов, вплоть до 239.5 тактов. В даташите есть таблица, определяющая максимальный импеданс входного сигнала, позволяющий получить хорошую точность при выбранном времени выборки.

Посмотрим, что получится, если увеличить время до 13.5 циклов. Делитель 2, буфер отключен:

Полный график.
О! Почти идеально. Не считая некоторых отклонений на 3-4 единицы, которые вполне убираются усреднением нескольких выборок, результат мало отличается от идеала. Если же взять по максимум, 239.5 циклов, то исчезают и эти выбросы. График.
Повтор теста несколько десятков раз даёт весьма стабильный результат, отклонения не больше чем на единицу. К концу диапазона результат отличается от идеала на 3 единицы, но, учитывая абсолютную линейность, это легко скомпенсировать, откалибровавшись буквально по одной точке. График, только средние значения. Делитель 2, буфер отключен, 13.5 тактов на выборку. Несколько десятков проходов.

Посмотрим, как повлияет на результат включение буфера ЦАП.

Полный график.
Не считая уже знакомого урезания диапазона, слегка изменился наклон графика. Но он по прежнему линеен и легко калибруется.

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

Ещё важно учитывать то, что в этом тесте также компенсировались возможные изменения опорного напряжения, так как и ЦАП и АЦП используют одно и то же напряжение Vref. При реальных измерениях нестабильность ИОН внесет дополнительную погрешность.
Также я не проверял преобразователи на температурную стабильность.

В приложении проект для IAR, проект графопостроителя для Delphi 7, архив с графиками.
  • +3
  • 07 октября 2011, 05:32
  • ACE
  • 3

Комментарии (30)

RSS свернуть / развернуть
Франкенштейн — распространенное ошибочное именование чудовища, созданного Франкенштейном.
+1
Ну дык. И коня тащемта назвали троянским, хотя делали его отнюдь не они.
А как оно на самом деле называлось, кстати?
0
Оно было безымянным))
0
Зануда! :)
Поменял «прошивку-франкештейна», на «прошивку Франкенштейна» :)
0
Гыгы, так гораздо лучше))
0
По моему время измерения у АЦП постоянно 12,5 циклов. А 1,5, 13,5, 239,5 — это время выборки (Sample time). То есть время, которое АЦП ждет перед измерением пока напряжение на входе установится.
0
  • avatar
  • OlegG
  • 07 октября 2011, 09:19
Ага, так и есть :)
The total conversion time is calculated as follows:
Tconv = Sampling time + 12.5 cycles
Example:
With an ADCCLK = 12 MHz and a sampling time of 1.5 cycles:
Tconv = 1.5 + 12.5 = 14 cycles = 1.17 µs
0
Да, не совсем корректно перевел на русский этот термин. Подправил статью, спасибо за уточнение.
0
Интересненько. Надо полагать, что в STM8 ситуация похожая.
0
А смысл делать замеры с паузами?
Не пробовал делать эксперимент при разных температурах? И какой референс?
0
  • avatar
  • Puff
  • 07 октября 2011, 14:24
Про замеры с паузами есть в статье, можно и без них. Про разные температуры тоже писал что нет, не пробовал. Референс стандартный для Дискавери, равен питанию 3.3В, как я понимаю.
0
А можно ссылку? Или эта статья имеется в виду?
0
Да, в этой. Паузы — попытка скомпенсировать возможные наводки от электросети. Как оказалось, в этом не было необходимости.
0
Так смысл компенсации — копить сэмплы непрерывно в течении периода гармонической помехи. Чем больше сэмплов тем лучше. Идеально continuous conversion.
0
Я для экспериментов втыкал на АЦП выход с обычного переменного резистора (СП-19 вроде или как-то так). Дак вот при максимальном размере паузы показания в младших разрядах почти не изменялись. А при минимальном — младшие разряды все время «бежали». Так что есть выбор методики повышения точности — делать несколько замеров и усреднять или увеличить паузу между замерами.
0
Да, пожалуй. Но это при реальных измерениях. Тут же я визуализирую все значения, а не только среднее. Таким образом на графике виден «разлет» измерений. Если бы делал непрерывный опрос — было бы сложно это визуализировать. Да и даже десяток выборок в течении периода помехи вполне неплохо компенсирует искажения, как показали тесты.
0
Дельфи? Типа эксель или OpenOffice Calc уже не в моде? И хотелось бы посмотреть не графики Out(in), а, например, например отклонение (Out(in) — in). Наглядней будет.
0
Ну, это кому как удобнее. :) Я, например, когда по работе мерял параметры аккумов (там тоже строились графики), сочинил консольное приложение, которое писало значения в csv-файл. А потом открывал его в Excel, расчитывал внутреннее сопротивление, после чего строил график в Advanced Grapher.
0
Мода? Я не гламурная блондинка, я программер. На Дельфи мне накатать такую прогу — полчаса. А ОпенОфис я в глаза не видел. В Экселе такие графики (один пиксел — одно измерение) тоже, насколько я знаю, не сделать. Так что каждый работает удобными ему инструментами.
Переделайте прошивку на вывод в формате CSV (всего то пробелы и скобки на запятые поменять) и обрабатывайте в любимой программе, дело пары минут!
0
Иксель, говорите?!
Ха! Это ж не инструмент! Это так себе… программа для офисных работничков и клерков, где думать глубоко не надо, где только мышой нужно тыкать по тому что видишь на экране.

Не, пацаны, для проведения авторитетных исследовательских работ нужен «уважаемый» инструмент, а не программа, которая предназначена для «розовых кофточек».

У меня, вот к примеру, на полевых испытаниях данные бывают по миллиону точек. И что, какой нахрен Кисель! Естественно я юзаю gnuplot. Вот это, я понимаю, — это Инструмент с большой буквы! А данные для него готовлю в виде обычных текстовых файлов. Естественно своей прогой. Получается очень быстро быстро и гибко. А самое главное — весь процесс контролируешь сам!

Так что все нормально, если ТС заюзал Делфи. Я его прекрасно понимаю, хотя сам юзаю gcc. Сам-то всегда сделаешь лучше и так как это надо ТЕБЕ. А не только в пределах возможности Икселя.
-1
Эксель конечно сосет когда данных оч много. Но в нем можно быстро сделать много полезных вещей вплоть до посторения спектра. Лично я и мои коллеги, и наши заказчики используем во многих применениях. Даже одним из требований заказчика к софту была генерация отчетов в формате экселя. Его знают и используют много людей и не все блондинки) Заказчик может залезть в отчет и перекорячить данные на свой вкус или проверить правильность. Можно накрутить доп фичи на VBA. Инструмент конечно непрофессиональный в плане мат статистики и пр. В общем считаю эксель хорошим универсальным средством упрощающим жизнь. И нафиг лезть писать своё ПО, если можно быстро налабать в нем. Просто надо уметь им пользоваться.
+1
Лучший инструмент тот, который знаешь. Если автор знает дельфи и не знает эксель, то в дельфи он задачу за полчаса решит, а в экселе тока искать нужный раздел справки полчаса будет.
+1
уважаемый! пожалуйста, ограничьте линух-экстремизм личным блогом. очень прошу.
+1
А, блин! Забыл поблагодарить ТС.
Спасибо! Полезная работа.
0
Отличная статья, и очень кстати) Спасибо!
0
  • avatar
  • basil
  • 08 октября 2011, 08:24
На ATMega АЦП измерял с большими ошибками.Решилась проблема после вставкой пары нопов между командой переключения мультиплексора АЦП и командой запуска преобразования.

При высокоомных источниках сигналов на вход АЦП вешаю емкость минимум в сто раз больше емкости АЦП. У меги в описании есть схема на которой показана емкость АЦП (если не ошибаюсь 10пФ).
0
  • avatar
  • mux
  • 19 сентября 2012, 07:27
а можно код подсмотреть?)
для работы с ацп надобно — никак не могу разобраться — как сделать фиксированное количество преобразований (ну что бы там сделало 1000 преобразований ацп, затем остановился, подождал сколько, потом снова запустился) а вы господин автор похоже как раз решили данную задачу)
0
Код автора приаттачен к статье. Смотрите маленькими буковками между статьей и комментариями. По моему автор в цикле запускает преобразования. Если Вас это не устраивает, можно подумать о запуске по таймеру и сбору данных с помощью прерываний и/или DMA.
0
OlegG собственно уже ответил.
Мой код чисто для теста, потому там всё в цикле, для простоты. Если нужно автоматически — создаётся буфер в 1000 измерений, запускается с DMA (пример кода нагуглить не сложно), после получения всей тысячи измерений — срабатывает прерывание. После паузы — запускается вручную заново. Хотя, наверное можно и по таймеру перезапускать, не изучал.
0
www.youtube.com/watch?v=qGR2FLp-eXg вот тут тест линейности с мультиметром. Отличие установленного напряжения от того что показывает мультиметр — это линейность DAC. Отличие измеренного от того что паказывает мультиметр — линейность ADC. Контроллер stm32f100c4t6. У меня получилась разница в 2 сотых на 30 вольтах. То есть лучше тысячной. Здесь считаем, что мультиметр абсолютно линеен, что может быть и неверно.
0
  • avatar
  • OlegG
  • 26 февраля 2013, 12:46
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.