Расширенное управление АЦП Arduino. DirectADC

БИБЛИОТЕКА


Библиотека для расширенного (ручного) управления АЦП и компаратором ATmega328/168

  • Функции библиотеки позволяют получить доступ ко всем возможностям и режимам работы с АЦП и компаратором
  • Ничего не урезано и не упрощено, доступен весь описанный в даташите функционал
  • Разработчик – Egor ‘Nich1con’ Zaharov

Поддерживаемые платформы: платы на ATmega328/168 (Arduino Nano, UNO, Pro Mini)

УСТАНОВКА


  • Библиотеку можно найти и установить через менеджер библиотек по названию DirectADC в:
    • Arduino IDE (Инструменты/Управлять библиотеками)
    • Arduino IDE v2 (вкладка «Library Manager»)
    • PlatformIO (PIO Home, вкладка «Libraries»)
  • Про ручную установку читай здесь

ДОКУМЕНТАЦИЯ


void setAnalogMux(ADC_modes mux);           // Аналоговый вход (ADC_A0-ADC_A7)/ термодатчик (ADC_SENSOR)/ 1.1V (ADC_1V1)/ ADC_GND (default: ADC_A0)
void ADC_enable(void);                      // Включить АЦП 
void ADC_disable(void);                     // Выключить АЦП (default)
void ADC_setPrescaler(byte prescl);         // Выбрать делитель частоты АЦП (2, 4, 8, 16, 32, 64, 128) // (default: 2)
void ADC_setReference(ADC_modes ref);       // Выбрать источник опорного напряжения АЦП (ADC_1V1, ADC_AREF, ADC_VCC) // (default: ADC_AREF)
void ADC_autoTriggerEnable(ADC_modes trig); // Включить автозапуск АЦП и выбрать событие (FREE_RUN, ANALOG_COMP, ADC_INT0, TIMER0_COMPA, TIMER0_OVF, TIMER1_COMPB, TIMER1_OVF)
void ADC_autoTriggerDisable(void);          // Выключить автозапуск АЦП // (default)
void ADC_attachInterrupt(void (*isr)());    // Включить прерывание готовности АЦП и выбрать функцию, которая будет при этом выполняться
void ADC_detachInterrupt(void);             // Выключить прерывание готовности АЦП // (default) 
void ADC_startConvert(void);                // Ручной запуск преобразования
unsigned int ADC_read(void);                // Прочитать значение регистров АЦП (Вызов до окончания преобразования вернет неверный результат)
boolean ADC_available(void);                // Проверить готовность преобразования АЦП
unsigned int ADC_readWhenAvailable(void);   // Дождаться окончания текущего преобразования и вернуть результат
void ACOMP_attachInterrupt(void (*isr)(), ADC_modes source);    // Включить прерывание компаратора и выбрать при каком событии оно будет вызвано (FALLING_TRIGGER, RISING_TRIGGER, CHANGE_TRIGGER)
void ACOMP_detachInterrupt(void);           // Выключить прерывание компаратора // (default)
void ACOMP_enable(void);                    // Включить компаратор // (default: Включен)
void ACOMP_disable(void);                   // Принудительно выключить компаратор
boolean ACOMP_read(void);                   // Прочитать значение на выходе компаратора 
void ACOMP_setPositiveInput(ADC_modes in);  // Настроить куда подкл +Вход компаратора (ADC_1V1, ADC_AIN0) (default: ADC_AIN0 - pin 6) 
void ACOMP_setNegativeInput(ADC_modes in);  // Настроить куда подкл -Вход компаратора (ADC_AIN1, ANALOG_MUX) (default: ADC_AIN1 - pin 7)
// делитель 2: 3.04 мкс (частота оцифровки 329 000 кГц)
// делитель 4: 4.72 мкс (частота оцифровки 210 000 кГц)
// делитель 8: 8.04 мкс (частота оцифровки 125 000 кГц)
// делитель 16: 15.12 мкс (частота оцифровки 66 100 кГц)
// делитель 32: 28.04 мкс (частота оцифровки 35 600 кГц)
// делитель 64: 56.04 мкс (частота оцифровки 17 800 кГц)                          
// делитель 128: 112 мкс (частота оцифровки 8 900 Гц)

ПРИМЕРЫ


Остальные примеры смотри в папке examples библиотеки, также примеры можно открыть из Arduino IDE/Файл/Примеры

/* данный скетч инициирует запуск преобразования ацп при снижении напряжения на входе ниже определенного порога */
#include "directADC.h"
void setup() {
  Serial.begin(9600);

  setAnalogMux(ADC_A0); // настроим вход АЦП

  ADC_enable(); // включаем ацп
  ADC_setPrescaler(64); // настраиваем делитель
  ADC_setReference(ADC_VCC); // опорное 5В
  ADC_attachInterrupt(adcReady); // заберем значение ацп как только оно будет готово
  ADC_autoTriggerEnable(ANALOG_COMP); // ацп запустится от срабатывания компаратора (RISING)

  ACOMP_attachInterrupt(ivent, RISING_TRIGGER);
  ACOMP_setPositiveInput(ADC_1V1); //порог срабатывания - 1.1В
  // второй вывод по дефолту висит на pin 7 , поэтому наблюдаемое напряжение повесим на pin 7
}

void ivent() {}; // пустая функция прерывания компаратора

void adcReady() {
  Serial.println(ADC_read());
}
// Внимание! Когда напряжения на входах компаратора будут близки, с высокой вероятностью начнет проявляться дребезг */
void loop() {
}
#include "directADC.h"
void setup() {
  Serial.begin(9600);
  ACOMP_attachInterrupt(func, FALLING_TRIGGER); // прерывание как только напряжение на -in превысит напряжение на +in
  ADC_disable(); // если используем мультиплексор для компаратора - обяательно выключаем ацп
  ACOMP_setPositiveInput(ADC_1V1); // подключить +in к 1.1В
  ACOMP_setNegativeInput(ANALOG_MUX); // подключить -in к аналоговому мультиплексору (ацп должен быть выключен!);
  /* если в таком режиме включить АЦП , -in компаратора переключится на ADC_AIN1 - pin 7 , до того момента, пока ацп опять не выключится */
  setAnalogMux(ADC_A2); // -in компаратора будет отслеживать вывод ADC_A2
}

void func() { // как только напряжение на входе А2 превысит 1.1В произойдет прерывание
  Serial.println("isr");
}

void loop() {
}
/* прерывание происходит ТОЛЬКО в момент перехода выхода компаратора из одного положения в другое */
#include "directADC.h"
/* пример использования компаратора*/
void setup() {
  Serial.begin(9600);
}
// компаратор уже работает на ногах : +in => (ADC_AIN0 - pin 6)   -in => (ADC_AIN1 - pin 7);
void loop() {
  Serial.println(ACOMP_read()); // прочитать выход компаратора
}
#include "directADC.h"
void setup() {
  Serial.begin(9600);
  ADC_enable(); // вызывается обязательно
  ADC_setPrescaler(64); // без вызова - делитель 2
  ADC_setReference(ADC_VCC); // без вызова - ADC_AREF
  setAnalogMux(ADC_A4); // выбрать ADC_A0-ADC_A7 / ADC_SENSOR - термометр / ADC_1V1 / ADC_GND // Без вызова - ADC_A0
  ADC_autoTriggerEnable(FREE_RUN); // другие варианты см в файле directADC.h
  ADC_startConvert(); // пнуть ацп
}

void loop() {
  Serial.println(ADC_read()); // читаем актуальное значение в любой момент времени, без ожидания
  // можно заменить на ADC_readWhenAvailable() чтобы быть уверенным в том,что результат наиболее свежий (вносит задержку 10-100 мкс в код)
}
#include "directADC.h"
void setup() {
  Serial.begin(9600);
  ADC_enable(); // вызывается обязательно
  ADC_setPrescaler(64); // без вызова - делитель 2
  ADC_setReference(ADC_VCC); // без вызова - ADC_AREF
  ADC_attachInterrupt(adcReady); // добавим прерывание готовности
  setAnalogMux(ADC_A4); // выбрать ADC_A0-ADC_A7 / ADC_SENSOR - термометр / ADC_1V1 / ADC_GND // Без вызова - ADC_A0
}


void loop() {
  delay(1);
  ADC_startConvert(); // начинаем преобразование
}

void adcReady() {
  Serial.println(ADC_read()); // забираем результат
}
#include "directADC.h"
/* пример простой работы с ацп */
void setup() {
  Serial.begin(9600);
  ADC_enable(); // вызывается обязательно
  ADC_setPrescaler(64); // без вызова - делитель 2
  ADC_setReference(ADC_VCC); // без вызова - ADC_AREF
  setAnalogMux(ADC_A4); // выбрать ADC_A0-ADC_A7 / ADC_SENSOR - термометр / ADC_1V1 / ADC_GND // Без вызова - ADC_A0
}

void loop() {
  ADC_startConvert(); // ручной старт преобразования
  while (!ADC_available()); // пока преобразование не готово - ждем или делаем что то полезное
  Serial.println(ADC_read());

  // ADC_read(); - прямая склейка и чтение,если преобразование еще не закончилось - вернет ошибочное значение.
  // ADC_readWhenAvailable(); - дождется окончания преобразования и вернет результат, если уже готово-вернет сразу.
}

ПОДДЕРЖАТЬ


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

5/5 - (2 голоса)
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

2 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх