Arduino Mega TIMER1 интервал в одну секунду
Правильно ли установлен этот таймер для Arduino Mega? Он должен отсчитывать ровно одну секунду. И почему, когда я печатаю в последовательном мониторе (seconds_passed++), он увеличивается на 2, а не на 1?
Полный код на Pastebin: ССЫЛКА
noInterrupts();
//set and initialize the TIMER1
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // set entire TCCR1B register to 0
TCCR1B |= (1 << CS12);
TIMSK1 |= (1 << TOIE1);
TCNT1 = 3036;
attachInterrupt(digitalPinToInterrupt(ignition_pin), ignitionSignal, CHANGE);
interrupts();
ISR(TIMER1_OVF_vect) {
//TIMER1 overflow interrupt -- occurs every 1sec --
instantSpeed();
LPG_Consumption();
LPG_injector_open_duration = 0;
unleadedConsumption();
unleadinj_Open_Duration = 0;
seconds_passed++;
vss_pulses = 0;
TCNT1 = 3036;
}
@Adam, 👍1
Обсуждение1 ответ
Ваша конфигурация таймера пока в порядке. Тем не менее я рекомендую использовать вектор
прерывания TIMER1_COMPA_vect вместо TIMER1_OVF_vect
, который имеет преимущество лучшей читаемости (в моем представлении), и TCNT1
не нужно сбрасывать в ISR (вместо этого OCR1A просто инициализируется с 62500 один раз в setup()
). Поэтому TIMER0 должен работать в режиме CTC (очистить таймер при сравнении совпадений), а WGM12
должен быть установлен в TCR1B.
Причина,
по которой seconds_passed увеличивается в два раза, заключается в том, что вы выполняете последовательную печать(seconds_passed++)
в instantSpeed ()
. Печать на последовательном интерфейсе чертовски медленная, и использовать ее в ISR-это никуда не годится!
Спасибо, вы имеете в виду что-то вроде этого: TCR1A = 0; // отменить настройку таймера Arduino TCR1B = 0; // то же самое TCNT1 = 0; // таймер сброса OCR1A = 62500 - 1; // период = 62500 тактов TCR1B = _BV(WGM12) // Режим CTC, ВВЕРХУ = OCR1A | _BV(CS12); // часы в F_CPU/256 TIMSK1 = _BV(OCIE1A); // прерывание на выходе сравнение A, @Adam
Я не могу гарантировать, потому что у меня сейчас нет atmega2560, так что, возможно, придется кое-что исправить. Что должен делать TOP=OCR1A
? Я не думаю, что в этом есть необходимость. Также я думаю, что " OCR1A=62500 "теоретически правильно ("галочки" в 0 нет), но, вероятно, вы не заметите никакой разницы..., @Sim Son
Это всего лишь комментарий., @Adam
Все в порядке! Я предлагаю вам попробовать это автономно, мигнув светодиодом, просто чтобы посмотреть. Если это не сработает, не стесняйтесь спрашивать!, @Sim Son
@Adam: Избегайте написания кода в комментариях: он не очень читаем. Вместо этого опубликуйте ссылку. @SimSon: 1. Адам скопировал вставку из [этого ответа](https://arduinoprosto.ru/q/54547). 2. Таймер отсчитывает от 0 до OCR1A
_включительно. Если вам нужен период 62500, то для OCR1A
следует установить значение 62500-1=62499., @Edgar Bonet
@EdgarBonet так что практически сброс TCNT-это один тик?, @Sim Son
- Выводы прерываний Arduino Mega 2560 и отображение портов с помощью поворотного энкодера
- Измерение скорости двигателя постоянного тока с помощью поворотного энкодера
- Установка timer3 в режиме CTC - конфликт с сервобиблиотекой
- Сообщение об ошибке: "exit status 1 expected initializer before 'void'."
- Как измерить ультразвуковой датчик без импульсного метода?
- Проблема прерывания библиотеки MPU6050 Arduino Jeff Rowberg
- Таймеры, выводы ШИМ и цифровые выходы на Arduino Mega
- Serial — отправляет данные в Arduino, пока Arduino отправляет данные
Я не эксперт в этом, но Mega работает на 16 МГц. ваш прескалер 256, поэтому TCMT1 должен быть 16000000/256 в течение 1 секунды?, @Juraj
Вы задали новый вопрос на ту же тему, вместо того, чтобы улучшить свой предыдущий вопрос. По крайней мере, удалите свой предыдущий вопрос сейчас, @chrisl