Arduino Mega 2560 подсчет задержек между событиями на разных контактах
Мне интересно, как точно посчитать задержки времени между событиями нарастания, происходящими на 4 разных линиях/контактах, используя Input Capture Arduino Mega 2560. Как синхронизировать таймер/счетчики? Буду признателен за вашу помощь и предложения.
@Bakyt, 👍0
1 ответ
Это невозможно. По крайней мере, без модификации оборудования.
Микроконтроллер ATmega2560, лежащий в основе Arduino Mega, четыре входных блока захвата, подключенных к входным контактам захвата ICP[1345]. К сожалению, на плате Arduino разведены только два из этих контактов. В таблице ниже перечислены четыре контакта ICP с указанием их номеров на Пакет TQFP и на плате Arduino:
pin package Arduino
───────────────────────────
ICP1/PD4 47 --
ICP3/PE7 9 --
ICP4/PL0 35 49
ICP5/PL1 36 48
Если вам не удастся припаять провода к отсутствующим контактам, вы не сможете использовать четыре входных блока захвата.
Что касается синхронизации, у вас есть два варианта:
Если вы используете предварительный делитель (т.е. коэффициент предварительного делителя больше, чем один), вы должны использовать его функцию «сброса предварительного делителя» с битом TSM (Режим синхронизации таймера/счетчика) включен. Это позволит вам запустите четыре таймера одновременно, когда вы очистите бит TSM. Смотрите Подробности в техническом описании микроконтроллера.
Если вы не используете предварительный делитель, вы можете просто запустить четыре таймеры в быстрой последовательности, с отключенными прерываниями. Они не будут начинаются почти одновременно, но вы можете компенсировать это, когда устанавливая их начальные значения.
В качестве примера второго варианта следующая функция запускает четыре таймера без предварительного делителя и синхронизированного подсчета:
void init_timers() {
// Очищаем конфигурации таймера.
TCCR1A = 0; TCCR1B = 0;
TCCR3A = 0; TCCR3B = 0;
TCCR4A = 0; TCCR4B = 0;
TCCR5A = 0; TCCR5B = 0;
// Устанавливаем начальные значения.
TCNT1 = 0;
TCNT3 = 2;
TCNT4 = 4;
TCNT5 = 6;
// Запускаем таймеры.
noInterrupts();
TCCR1B = _BV(CS10);
TCCR3B = _BV(CS30);
TCCR4B = _BV(CS40);
TCCR5B = _BV(CS50);
interrupts();
}
Раздел, который запускает таймеры, компилируется в эту сборку:
cli ; noInterrupts();
ldi r24, 0x01 ; r24 = _BV(CS10)
sts TCCR1B, r24 ; TCCR1B = r24
sts TCCR3B, r24 ; TCCR3B = r24
sts TCCR4B, r24 ; TCCR4B = r24
sts TCCR5B, r24 ; TCCR5B = r24
sei ; interrupts();
Поскольку инструкция sts
завершается за два такта, эта задержка будет
компенсировать смещение начальных значений таймера.
Теперь, если вас не волнует точность на уровне микросекунд, вы можете забыть
о таймерах и использовании внешних прерываний (или прерываний по изменению состояния контактов)
и запишите время с помощью micros()
.
- Считать данные датчика повторно через указанное время?
- Arduino mega PinChangeInterrupt с 16 битным таймером
- Использование millis() и micros() внутри процедуры прерывания
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- ATtiny85 AC Phase Control для регулировки яркости лампочки