АЦП Arduino

АЦП (аналого-цифровой преобразователь) предназначен для преобразования аналогового сигнала в цифровой, например Arduino Nano содержит 8 аналоговых входов (А0 — А7), а Arduino Uno 6 входов (А0 — А5). В качестве опорного напряжения можно выбрать внутренней опорное напряжение 1.1 В, а так же внешнее и в качестве опорного источника может быть напряжение питания микроконтроллера 5 В.

Напряжение поданное на вход АЦП  (10 бит) должно  находится в границах заданного диапазона, то есть от 0 В до напряжения опорного источника. Напряжение поданное на вход АЦП будет оцифровано и представлено в виде цифрового значения в диапазоне от 0 до 1023 ( 10 бит — 1024 значения).

При работе с Arduino IDE используется стандартная функция analogRead(), которая позволяет считывает значение с указанного аналогового входа. Считывание значение с аналогового входа занимает примерно 100 микросекунд (0.0001 сек), то есть максимальная частота считывания приблизительно 10000 раз в секунду.

Пример использования:

unsigned long time;
int u;
 
void setup(){
  Serial.begin(9600);
  pinMode(A0,INPUT);
}
 
void loop(){
  time = micros();
  u = analogRead(A0);
  time = micros() - time;
  Serial.print(u);
  Serial.print(" ");
  Serial.println(time);
  delay(1000);
}

Как видно в скетче помимо измерения напряжения поданного на аналоговый вход А0, добавлена возможность определить время измерения (мкс). Открыв монитор порта можно увидеть, что напряжение 5В поданное на вход АЦП преобразовано в число int 1023, которое отображается в первом столбе числового ряда, во втором столбе указано время измерения в мкс.

Функция analogRead() достаточно медлительна и не функциональна, для увеличения функциональных возможностей аналогового входа необходимо настроить регистр ADMUX (регистр настройки мультиплексора АЦП) и регистр ADCSRA (Регистр статуса и контроля А).

Регистр ADMUX управляет выбором опорного напряжения, а также входа мультиплексора.

Регистр ADMUX:

7 6 5 4 3 2 1 0
REFS1 REFS0 ADLAR MUX3 MUX2 MUX1 MUX0

Биты REFS1 (7) и REFS0 (6) устанавливают какой источник опорного напряжения будет выбран:

  • 00 — опорное напряжение на входе AREF
  • 01 — Uпит. микроконтроллера
  • 10 — резерв
  • 11 — внутренний ИОН 1.1 В

Бит ADLAR (5) регистра ADMUX позволяет выравнивать результат преобразования по левому краю при записи в него 1, это необходимо если требуется получить 8-битовый результат.

Биты MUX3 — MUX0 (3 — 0) — управляют мультиплексором:

  • 0000 A0
  • 0001 A1
  • 0010 A2
  • 0011 A3
  • 0100 A4
  • 0101 A5
  • 0110 A6
  • 0111 A7

Пример:

ADMUX = 0b01000000; // ИОН — напряжение питания микроконтроллера, вход А0

Регистр ADCSRA:

7 6 5 4 3 2 1 0
ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0

Бит ADEN (7) регистра ADCSRA включает или выключает АЦП (1-включен).

Бит ADSC (6) регистра ADCSRA запускает преобразование если в него записать 1 (для многоразового режима запуск первого преобразования).

Бит ADATE (5) регистра ADCSRA позволяет запускать преобразование по прерыванию от переферийных устройств микроконтроллера если установить в 1.

Бит ADIF (4) регистра ADCSRA — флаг прерывания от АЦП.

Бит ADIE (3) регистра ADCSRA — разрешает прерывания от АЦП если установлен в 1.

Биты ADPS2 — ADPS0 (2 — 0) регистра ADCSRA выбирают режим работы предделителя тактовой частоты:

  • 000 — CLK/2
  • 001 — CLK/2
  • 010 — CLK/4
  • 011 — CLK/8
  • 100 — CLK/16
  • 101 — CLK/32
  • 110 — CLK/64
  • 111 — CLK/128

ADCL и ADCH — регистры с результатом преобразования АЦП.

Пример использования:

unsigned long time;
int u,i;
 
void setup(){
  Serial.begin(9600);
  ADMUX  = 0b01000000; // 0B0100000 10 bit A0 
  ADCSRA = 0b11110011;// CLK/8
}
 
void loop(){
  time = micros();
  while(i<10){
    i++;
    do{
      ADCSRA |= (1 << ADSC);
    } 
    while((ADCSRA & (1 << ADIF)) == 0);
    u = (ADCL|ADCH << 8);
  }
  i=0;
  time = micros() - time;
  Serial.print(u);
  Serial.print(" ");
  Serial.println(time);
  delay(1000);
}

В скетч дополнительно добавлен цикл while который позволяет сделать сразу 10 измерений напряжения поданного на вход А0, как видно на скриншоте время десяти измерений примерно равно 70 мкс, то есть на одно измерение уходит 7 мкс вместо 100 мкс при использовании функции analogRead(). При этом следует отметить измерение велось в режиме 10 бит. В 8-битном режиме измерения скорость измерения будет еще выше.

Пример использования при измерений в 8-и битном режиме:

unsigned long time;
int u,i;
 
void setup(){
  Serial.begin(9600);
  ADMUX  = 0b01100000; // 0B0110000 8 bit A0 
  ADCSRA = 0b11110011;// CLK/8
}
 
void loop(){
  time = micros();
  while(i<10){
    i++;
    while ((ADCSRA & 0x10)==0);
    ADCSRA|=0x10;
    u = ADCH;
  }
  i=0;
  time = micros() - time;
  Serial.print(u);
  Serial.print(" ");
  Serial.println(time);
  delay(1000);
}

Точность 8 битного результата конечно ниже 10-и битного, теперь АЦП преобразовывает напряжение в цифровое значение byte от 0 до 255, со скоростью 64 мкс при 10 измерениях, то есть на одно измерение уходит примерно 6,4 мкс.

Добавить комментарий

Войти с помощью: