Таймеры Arduino UNO — Часть 5. Измерение длительности импульсов и частоты (Input Capture)

Теория

Режим Input Capture (ICP1)

Режим Input Capture — это специальная функция Timer1 в микроконтроллере ATmega328P, которая позволяет с высокой точностью измерять моменты прихода фронтов сигнала (нарастающего или спадающего) на пине ICP1 (Arduino UNO — пин D8).

Когда на вход ICP1 поступает выбранный фронт сигнала, текущее значение счётчика TCNT1 автоматически копируется в регистр ICR1. Это позволяет точно зафиксировать момент события без задержек, которые могли бы возникнуть при опросе пина в обычном коде.

Как измерить частоту и длительность

  • Частота рассчитывается как F = F_CPU / (Prescaler * ΔTCNT), где ΔTCNT — разница между двумя захватами, а Prescaler — выбранный делитель таймера.
  • Длительность импульса можно определить, измерив время между фронтами (нарастающим и спадающим) одного импульса.

Input Capture полезен в задачах, где требуется высокая точность измерений — например, при создании тахометров, анализаторов сигналов, частотомеров.

Практика

Измерение частоты сигнала от датчика Холла

Пример кода для измерения частоты вращения колеса с датчиком Холла:


volatile uint16_t lastCapture = 0;
volatile uint16_t period = 0;
float frequency = 0;

void setup() {
  Serial.begin(9600);
  pinMode(8, INPUT);

  TCCR1A = 0; // Обычный режим
  TCCR1B = 0;
  TCCR1B |= (1 << ICES1); // Захват по нарастающему фронту
  TCCR1B |= (1 << CS11);  // Предделитель 8
  TIMSK1 |= (1 << ICIE1); // Разрешение прерывания захвата
}

ISR(TIMER1_CAPT_vect) {
  uint16_t capture = ICR1;
  period = capture - lastCapture;
  lastCapture = capture;
}

void loop() {
  if (period > 0) {
    frequency = 16000000.0 / (8.0 * period);
    Serial.print("Частота: ");
    Serial.print(frequency);
    Serial.println(" Гц");
    delay(500);
  }
}
  

Проект: Тахометр на Arduino UNO

В этом проекте мы используем Input Capture для создания тахометра, измеряющего обороты в минуту (RPM) двигателя.


volatile uint16_t lastCapture = 0;
volatile uint16_t period = 0;
float rpm = 0;

void setup() {
  Serial.begin(9600);
  pinMode(8, INPUT);

  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1B |= (1 << ICES1); // Захват по нарастающему фронту
  TCCR1B |= (1 << CS11);  // Предделитель 8
  TIMSK1 |= (1 << ICIE1); // Прерывание захвата
}

ISR(TIMER1_CAPT_vect) {
  uint16_t capture = ICR1;
  period = capture - lastCapture;
  lastCapture = capture;
}

void loop() {
  if (period > 0) {
    float frequency = 16000000.0 / (8.0 * period);
    rpm = frequency * 60.0; // 1 импульс на оборот
    Serial.print("RPM: ");
    Serial.println(rpm);
    delay(500);
  }
}
  

Такой тахометр можно использовать в моделях автомобилей, мотоциклов, вентиляторах и других механизмах, где нужно измерять скорость вращения.

<< Проекты << Все товары >> Статьи, уроки >>

Написать отзыв

Примечание: HTML разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Задатчик тока 4 20мА. Схема простого в изготовлении токового задатчика

Задатчик тока 4 20мА. Схема простого в изготовлении токового задатчика

Прибор позволяет получать на выходе 0...20 мА, 4...20 мА. Области применения представленного устр..

Понижающий преобразователь напряжения с ограничением по току 8...36В в 1,25...32В 5А

Понижающий преобразователь напряжения с ограничением по току 8...36В в 1,25...32В 5А

Импульсный преобразователь напряжения постоянного тока с 8 ... 36В в 1,25 ... 32В на основе мик..

99.70грн.

Arduino SIM800 управление реле по исходящему звонку

Arduino SIM800 управление реле по исходящему звонку

Предлагаю вашему вниманию пример простого применения возможностей SIM800 при исходящем звонке. В рез..

Простейший способ проверки GSM-модуля

Простейший способ проверки GSM-модуля

Бывают моменты, когда нас выводит из себя такая штуковина как GSM модуль к любительской плате контро..

Стабилизатор напряжения 5В 1,5А L7805CV

Стабилизатор напряжения 5В 1,5А L7805CV

Стабилизатор напряжения в виде микросхемы с тремя ногамиИспользуется для стабилизации нестабилизиров..

12.54грн.