Перейти к содержанию

Аналого-цифровой преобразователь (АЦП)

Аналого-цифровой преобразователь (АЦП) измеряет напряжение и выдаёт его в виде числа: код N-разрядного АЦП — это доля входного напряжения от опорного, умноженная на 2^N. Точность измерения зависит не только от разрядности, но и от опорного напряжения, сопротивления источника, времени выборки и шумов платы.

Обновлено Редакция GAW

Аналого-цифровой преобразователь (АЦП) превращает напряжение в число. Он делает две вещи: берёт значения сигнала в отдельные моменты времени (дискретизация) и округляет каждое значение до ближайшей из 2N ступенек (квантование), где N — разрядность. АЦП есть почти в каждом микроконтроллере: 10-разрядный в ATmega328P на Arduino Uno, 12-разрядный в STM32.

Коротко

Квантование и формула кода

N-разрядный АЦП делит диапазон от нуля до опорного напряжения VREF на 2N равных шагов. Шаг называют LSB (least significant bit, младший разряд):

1 LSB=VREF2N1\ \text{LSB} = \frac{V_{REF}}{2^N}

Код результата для однополярного входа (DS40002061B, разд. 24.7):

ADC=VIN⋅2NVREF\text{ADC} = \frac{V_{IN} \cdot 2^N}{V_{REF}}

Код 0 соответствует нулю, а наибольший код 2N − 1 — опорному напряжению минус 1 LSB. Обратный пересчёт: VIN = код · VREF / 2N.

Передаточная характеристика идеального трёхразрядного АЦППо горизонтали — входное напряжение от нуля до опорного, разбитое на восемь шагов по 1 LSB; по вертикали — коды от 000 до 111. Ступенька кода k начинается на (k − 0,5) LSB и кончается на (k + 0,5) LSB, поэтому ошибка квантования не превышает половины LSB. Последний код 111 соответствует опорному напряжению минус 1 LSB.00000101001110010111011101 LSBVREFVINкодкод 011: ±½ LSB
АЦПVREF1 LSB
ATmega328P, 10 бит5 В (AVCC)4,88 мВ
ATmega328P, 10 бит1,1 В (внутренний источник)1,07 мВ
STM32, 12 бит3,3 В805,6 мкВ
16 бит2,5 В38,1 мкВ

Все входные напряжения в пределах одной ступеньки дают один код, поэтому даже идеальный АЦП ошибается на величину до ±½ LSB — это ошибка квантования (DS40002061B, разд. 24.6.3). Первый переход с кода 0 на 1 у идеального АЦП происходит на ½ LSB, а не на одном LSB: так ошибка распределяется симметрично.

Пример. Arduino Uno, опора 5 В: analogRead() вернула 512. Напряжение на входе 512 · 5 / 1024 = 2,500 В, а настоящее значение лежит в пределах 2,500 ± 0,0024 В только из-за квантования — без учёта остальных погрешностей.

Как работает АЦП последовательного приближения

В микроконтроллерах почти всегда стоит АЦП последовательного приближения (SAR, successive approximation register) — так устроены и АЦП ATmega328P, и АЦП STM32. На структурной схеме ATmega328P (DS40002061B, рис. 24-1) видны все его части: устройство выборки-хранения, компаратор, 10-разрядный ЦАП и логика преобразования.

Структура АЦП последовательного приближенияВходное напряжение через устройство выборки-хранения подаётся на неинвертирующий вход компаратора, на инвертирующий — выход ЦАП. Выход компаратора идёт в регистр последовательного приближения, который управляет ЦАП и по окончании выдаёт код результата. ЦАП питается от опорного напряжения.VINУВХвыборка+−компараторРегистр SARбит за битомКодN битЦАПN битVDACVREF

Преобразование идёт так:

  1. Выборка. Ключ подключает вход к конденсатору выборки-хранения, тот заряжается до входного напряжения, затем ключ размыкается — дальше АЦП работает с «замороженным» значением.
  2. Поиск двоичным делением. Логика ставит старший бит ЦАП в 1: на выходе ЦАП VREF/2. Если входное напряжение больше — бит остаётся, если меньше — сбрасывается. Затем так же проверяется следующий бит, и так до младшего.
  3. Результат. Через N сравнений в регистре SAR записан код, при котором напряжение ЦАП ближе всего к входному.

На каждый разряд нужен один такт, поэтому время преобразования растёт с разрядностью линейно. У ATmega328P обычное преобразование занимает 13 тактов АЦП, выборка происходит через 1,5 такта после старта, а первое преобразование после включения — 25 тактов: аналоговая часть инициализируется (DS40002061B, разд. 24.4). У STM32F0 время преобразования равно времени выборки плюс 12,5 такта (RM0091, разд. 13.3.7).

Кроме SAR, встречаются сигма-дельта АЦП — они получают высокую разрядность на медленных сигналах за счёт многократной выборки и цифровой фильтрации (тот же принцип, что у передискретизации ниже), — и параллельные (flash) АЦП, где на каждую ступеньку свой компаратор: они самые быстрые, но разрядность у них небольшая.

Тактовая частота и скорость

ATmega328P. Для полной 10-разрядной точности тактовая частота АЦП должна быть 50–200 кГц; её получают из частоты процессора делителем на 2…128 (биты ADPS в ADCSRA). Выше 200 кГц АЦП работает быстрее, но точность падает: абсолютная погрешность растёт с 2 LSB на 200 кГц до 4,5 LSB на 1 МГц (DS40002061B, разд. 24.4 и табл. 29-15).

Тактовая частота АЦПВремя преобразования (13 тактов)Измерений в секунду
125 кГц (Arduino, 16 МГц / 128)104 мксоколо 9600
200 кГц65 мксоколо 15 400
1 МГц13 мксоколо 76 900

Ядро Arduino в init() выбирает делитель так, чтобы частота АЦП попала в 50–200 кГц: на 16 МГц это 128, то есть 125 кГц (cores/arduino/wiring.c). analogRead() записывает в ADMUX опору и канал, ставит бит ADSC и ждёт, пока он сбросится (wiring_analog.c).

STM32F0. АЦП 12-разрядный, разрядность можно уменьшить до 10, 8 или 6 бит ради скорости; при 12 битах преобразование занимает 1,0 мкс (RM0091, разд. 13.2). Время выборки выбирается полем SMP: 1,5; 7,5; 13,5; 28,5; 41,5; 55,5; 71,5 или 239,5 такта. Пример из RM0091: на 14 МГц при выборке 1,5 такта tCONV = 1,5 + 12,5 = 14 тактов = 1 мкс; с выборкой 239,5 такта — 252 такта, 18 мкс.

Входная цепь: сопротивление источника и время выборки

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

Входная цепь АЦП: что заряжает источникИсточник сигнала с выходным сопротивлением RAIN подключён к выводу микроконтроллера; у вывода может стоять внешний конденсатор CAIN на общий провод. Внутри микросхемы от вывода через последовательное сопротивление RS/H и ключ выборки сигнал заряжает конденсатор выборки-хранения CS/H.~источникRAINCAINмикроконтроллерADCnRS/H1…100 кОмключ выборкиCS/H14 пФк АЦП

ATmega328P. Конденсатор выборки CS/H — 14 пФ, последовательное сопротивление внутри — 1…100 кОм (DS40002061B, рис. 24-8). Даташит рекомендует источники с выходным сопротивлением около 10 кОм и меньше: тогда время выборки «можно не учитывать». От источника с большим сопротивлением лучше подавать медленно меняющиеся сигналы — каждый раз нужно перезаряжать конденсатор меньше.

STM32. AN2834 описывает то же явление формулой: конденсатор CADC заряжается через сумму сопротивлений ключа и источника, постоянная времени tc = (RADC + RAIN) · CADC. Если время выборки меньше времени заряда до ½ LSB, результат занижен. Чем больше RAIN, тем длиннее нужно время выборки — минимальные значения для разных серий приведены в таблицах AN2834 и в даташитах.

Три способа справиться с высокоомным источником:

  • увеличить время выборки (у STM32 — поле SMP);
  • поставить у вывода конденсатор CAIN намного больше конденсатора выборки (AN2834 разбирает такую входную цепь): он отдаёт заряд в момент выборки, а между измерениями подзаряжается от источника. Это работает для медленных сигналов;
  • буферизовать сигнал повторителем на операционном усилителе с низким выходным сопротивлением.

Опорное напряжение

Код — это отношение входного напряжения к опорному, поэтому погрешность опоры целиком переходит в результат. У ATmega328P опору выбирают битами REFS в ADMUX: AVCC, внутренний источник 1,1 В или внешнее напряжение на выводе AREF (DS40002061B, разд. 24.2).

  • AVCC. Удобно, если измеряемый сигнал пропорционален питанию (потенциометр, делитель с термистором): колебания питания тогда сокращаются. Для абсолютных измерений точность ограничена точностью стабилизатора. AVCC не должно отличаться от VCC больше чем на ±0,3 В; даташит рекомендует подключать его через фильтр 10 мкГн + 100 нФ (рис. 24-9).
  • Внутренний источник 1,1 В стабилен, но его значение у конкретного экземпляра лежит между 1,0 и 1,2 В (DS40002061B, разд. 29.5) — до ±9 % без калибровки. После включения ему нужно 40–70 мкс на запуск.
  • Внешняя опора на AREF — прецизионный источник опорного напряжения, когда нужна абсолютная точность. Если на AREF подано внешнее напряжение, внутренние опоры выбирать нельзя: они замкнутся на внешний источник.

Измерение напряжения питания без делителя. Вход мультиплексора АЦП ATmega328P можно переключить на внутренний источник 1,1 В, а опорой выбрать AVCC. Тогда код = 1,1 · 1024 / VCC, и VCC = 1,1 · 1024 / код. Точность определяется разбросом 1,0–1,2 В, поэтому для точных измерений значение источника для конкретного экземпляра один раз измеряют и записывают в EEPROM.

Дискретизация и наложение спектров

Частота выборки должна быть больше удвоенной наибольшей частоты сигнала (частота Найквиста — половина частоты выборки). Составляющие выше неё не исчезают, а «отражаются» в полосу сигнала и становятся неотличимы от него. Даташит ATmega328P прямо требует убирать такие составляющие фильтром нижних частот до АЦП (разд. 24.6.1).

AN2834 советует простой RC-фильтр с частотой среза fC чуть выше полосы полезного сигнала и частоту выборки в 2–5 раз выше fC. Частоту среза RC-цепочки считает калькулятор RC-фильтра: fC = 1/(2πRC).

Погрешности АЦП

Реальный АЦП отличается от идеального не только квантованием. Даташит ATmega328P определяет погрешности так (разд. 24.6.3):

ПогрешностьЧто этоATmega328P, VREF = 4 В, 200 кГц
Смещение (offset)Отклонение первого перехода 0→1 от идеальных ½ LSB2 LSB
Ошибка усиления (gain)После учёта смещения — отклонение последнего перехода от идеального (1½ LSB ниже максимума)2 LSB
Интегральная нелинейность (INL)После учёта смещения и усиления — наибольшее отклонение перехода от идеальной прямой0,5 LSB
Дифференциальная нелинейность (DNL)Наибольшее отклонение ширины ступеньки от 1 LSB0,25 LSB
КвантованиеШирина ступеньки 1 LSB±0,5 LSB
Абсолютная точностьВсё вместе, без калибровки2 LSB

Значения в правом столбце — из табл. 29-15 даташита. Смещение и ошибку усиления можно убрать калибровкой по двум известным напряжениям — нелинейность и шум калибровкой не исправить. AN2834 приводит пример смещения: при VREF = 3,3 В у 12-разрядного АЦП 1 LSB = 805,6 мкВ; если код 1 появляется на 550 мкВ вместо идеальных 402,8 мкВ, смещение равно 141,2 мкВ, или 0,17 LSB. У STM32F0 есть встроенная самокалибровка, которая убирает смещение: её запускают битом ADCAL до начала преобразований, пока АЦП выключен (ADEN = 0), и коэффициент сохраняется до отключения питания АЦП (RM0091, разд. 13.3.2).

Шум и передискретизация

Ошибка квантования ведёт себя как шум с действующим значением q/√12, где q = 1 LSB. Для синусоиды на полную шкалу отсюда получается предельное отношение сигнал/шум идеального N-разрядного АЦП (AN4629):

SNR=6,02⋅N+1,76 дБ\text{SNR} = 6{,}02 \cdot N + 1{,}76\ \text{дБ}
Разрядность8 бит10 бит12 бит16 бит
SNR идеального АЦП49,9 дБ62,0 дБ74,0 дБ98,1 дБ

Шум квантования распределён по всей полосе до половины частоты выборки. Если измерять чаще, чем нужно, и затем усреднять (цифровой фильтр), часть шума отсекается: по AN4629 отношение сигнал/шум растёт на 10·lg(OSR) дБ, где OSR — коэффициент передискретизации. Каждое учетверение числа измерений даёт 10·lg 4 ≈ 6 дБ — примерно один разряд. Отсюда правило: чтобы получить n дополнительных бит, складывают 4n измерений и сдвигают сумму на n разрядов вправо. Метод работает, только если на входе есть шум хотя бы около 1 LSB, не связанный с частотой выборки; на идеально «тихом» входе все измерения одинаковы, и усреднение ничего не даёт.

Многие STM32 умеют суммировать до 1024 измерений аппаратно (AN2834). У ATmega328P для снижения шума есть режим сна ADC Noise Reduction: ядро и порты останавливаются на время преобразования (DS40002061B, разд. 24.6).

Пример: напряжение аккумулятора 12 В

Нужно измерять аккумулятор до 15 В при опоре 5 В. Делитель должен уменьшать напряжение втрое: R1 = 20 кОм, R2 = 10 кОм.

Делитель для измерения напряжения аккумулятораПлюс аккумулятора 12 В через резистор 20 кОм подключён к выводу ADC0 микроконтроллера, от вывода на общий провод — резистор 10 кОм и параллельно ему конденсатор 100 нФ.+12 В (до 15 В)R120 кОмR210 кОмC1100 нФADC0 (A0)опора 5 В
  • Коэффициент: 10 / (20 + 10) = 1/3; на 15 В на входе ровно 5 В. Пересчитать делитель под другие напряжения поможет калькулятор делителя.
  • Сопротивление источника для АЦП — параллельное соединение R1 и R2: 20 · 10 / 30 = 6,7 кОм, меньше рекомендованных 10 кОм.
  • Ток через делитель на 12 В: 12 В / 30 кОм = 0,4 мА — разряжать аккумулятор будет постоянно; если это много, делитель берут больше и обязательно ставят конденсатор.
  • Конденсатор C1 100 нФ вместе с делителем — фильтр с частотой среза 1/(2π · 6,7 кОм · 100 нФ) ≈ 240 Гц: убирает помехи и отдаёт заряд при выборке.
  • Разрешение: 1 LSB на входе — 4,88 мВ, на аккумуляторе — втрое больше, 14,6 мВ.

Если analogRead() вернула 820, на входе 820 · 5 / 1024 = 4,004 В, а на аккумуляторе 4,004 · 3 = 12,01 В. Резисторы с допуском 1 % и неточность опоры 5 В дают погрешность заметно больше квантования, поэтому коэффициент лучше один раз откалибровать по мультиметру.

// Arduino: battery voltage through a 20k/10k divider on A0, AVCC = 5 V reference
const float VREF = 5.0;      // measure the real 5 V rail and put it here
const float RATIO = 3.0;     // (R1 + R2) / R2

void setup() { Serial.begin(115200); }

void loop() {
  long sum = 0;
  for (int i = 0; i < 16; i++) sum += analogRead(A0);  // average 16 readings
  float vPin = (sum / 16.0) * VREF / 1024.0;
  Serial.println(vPin * RATIO, 2);
  delay(500);
}

АЦП ATmega328P на регистрах

Тот же замер без функций Arduino: опора AVCC, канал ADC0, делитель 128, одиночное преобразование (регистры — DS40002061B, разд. 24.9).

#include <avr/io.h>

void adc_init(void) {
  ADMUX = (1 << REFS0);                                 // AVCC reference, channel ADC0
  ADCSRA = (1 << ADEN)                                  // enable the ADC
         | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);  // 16 MHz / 128 = 125 kHz
}

uint16_t adc_read(uint8_t channel) {
  ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);  // select the channel, keep the reference
  ADCSRA |= (1 << ADSC);                      // start a conversion
  while (ADCSRA & (1 << ADSC)) {}             // ADSC clears when the result is ready
  return ADC;                                 // ADCL is read first, then ADCH
}

После смены опоры первое преобразование лучше отбросить: опорному напряжению нужно время, чтобы установиться. Если читать результат по байтам, сначала читают ADCL, потом ADCH — иначе регистр результата блокируется до чтения ADCH (DS40002061B, разд. 24.2). Компилятор avr-gcc при чтении 16-битного ADC соблюдает этот порядок сам.

Типичные ошибки

  • Деление на 1023 вместо 1024. Даташит определяет результат через 1024; наибольший код соответствует VREF − 1 LSB.
  • Высокоомный источник без конденсатора или буфера. Делитель на 1 МОм, датчик с большим выходным сопротивлением — результат занижен и зависит от того, какой канал измерялся до этого.
  • Нет фильтра на входе. Помехи от импульсных источников и ШИМ попадают в результат, в том числе через наложение спектров.
  • Опора «плавает». При опоре AVCC любое падение питания под нагрузкой меняет все результаты. Для абсолютных измерений нужна стабильная опора.
  • Переключаются цифровые выводы того же порта. Даташит ATmega328P предупреждает: выводы ADC[3:0], работающие как цифровые выходы, не должны переключаться во время преобразования (разд. 24.6.2).
  • Ожидание всех 10 бит от шумной платы. Если результат «гуляет» на 3–5 единиц, это шум, а не дефект АЦП: помогают разводка, фильтрация, режим ADC Noise Reduction и усреднение.

Частые вопросы

Почему код АЦП делят на 1024, а не на 1023?

Так определяет результат даташит: для ATmega328P код равен VIN · 1024 / VREF, а наибольший код 1023 соответствует опорному напряжению минус 1 LSB, а не самому опорному. Поэтому V = код · VREF / 1024. Деление на 1023 даёт ошибку меньше одного LSB, но смещает всю шкалу.

Сколько разрядов у АЦП Arduino Uno и как быстро он работает?

У ATmega328P 10-разрядный АЦП последовательного приближения. Ядро Arduino на 16 МГц ставит делитель 128, то есть тактовую частоту АЦП 125 кГц; обычное преобразование занимает 13 тактов — 104 мкс, около 9600 измерений в секунду. Полную точность даташит гарантирует при тактовой частоте АЦП 50–200 кГц.

Какое сопротивление источника допустимо на входе АЦП?

Для ATmega328P даташит рекомендует источники с выходным сопротивлением около 10 кОм и меньше: тогда конденсатор выборки 14 пФ успевает зарядиться за время выборки. Источник с большим сопротивлением, например делитель на сотни килоом, нужно буферизовать повторителем на ОУ или поставить у вывода конденсатор, который отдаст заряд в момент выборки. У STM32 время выборки настраивается, и его выбирают по сопротивлению источника.

Как получить больше разрядов, чем есть у АЦП?

Передискретизацией: если шум на входе больше 1 LSB и не связан с частотой выборки, сумма 4^n измерений, сдвинутая на n разрядов вправо, даёт n дополнительных бит. По AN4629 выигрыш в отношении сигнал/шум равен 10·lg(OSR) дБ, то есть около 6 дБ — один разряд — на каждое учетверение числа измерений.

Можно ли подать на вход АЦП напряжение больше опорного?

Измерять — нет: всё, что выше VREF, даст наибольший код. Повредить вход может только напряжение за пределами абсолютных максимальных значений: для ATmega328P это от −0,5 В до VCC + 0,5 В на любом выводе, кроме RESET. Чтобы измерять большие напряжения, ставят делитель.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B) — разд. 24 (АЦП: структура, тактирование, входная цепь, определения погрешностей, формула результата), 29.5 (опорное напряжение 1,1 В), табл. 29-15 (характеристики АЦП)
  2. STMicroelectronics. RM0091: STM32F0x1/STM32F0x2/STM32F0x8 reference manual, Rev 10 — разд. 13.2 (возможности АЦП), 13.3.2 (калибровка), 13.3.7 (время выборки и время преобразования)
  3. STMicroelectronics. AN2834: How to optimize the ADC accuracy in the STM32 MCUs, Rev 10 — LSB и пример ошибки смещения, сопротивление источника и время заряда конденсатора выборки, RC-фильтр, аппаратное усреднение
  4. STMicroelectronics. AN4629: ADC hardware oversampling for microcontrollers of the STM32 L0 and L4 series (DocID027261 Rev 1) — шум квантования q/√12, SNR = 6,02N + 1,76 дБ, выигрыш от передискретизации 10·lg(OSR)
  5. Arduino. ArduinoCore-avr, коммит 11b9130: cores/arduino/wiring.c, wiring_analog.c — делитель тактовой частоты АЦП и функция analogRead()

Нашли ошибку?