Кнопка, прерывания и Таймер/Счетчик1
- Войдите на сайт для отправки комментариев
Вс, 19/05/2019 - 21:29
Здравствуйте!
Плата Arduino Nano. Кнопка подключена к GND и PORTD2(INT0).
Задача скетча простая: при нажатии на кнопку срабатывает прерывание (INT0_vect) по спадающему изменению фронта сигнала на входе(PORTD2) порта. В обработчике прерывания настраивается Таймер/Счетчик1 и запускается.
Но Таймер/Счетчик1 начинает отсчет сразу, без нажатия кнопки.
Объясните, пожалуйста, где я ошибся в скетче.
#define BUTTON_PIN PORTD2 #define MILLISECONDS_8 0x08 #define MILLISECONDS_64 0x3E8 #define MILLISECONDS_704 0x2AF8 #define MILLISECONDS_1000 0x3D09 ISR (INT0_vect) { TCCR1A = 0x00; TCNT1 = 0x00; OCR1A = MILLISECONDS_1000; TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); // Предделитель 1024 TIMSK1 = (1 << OCIE1A); // Прерывание по совпадению с A ТС1 } ISR (TIMER1_COMPA_vect) { static uint8_t count; EIMSK &= ~(1 << INT0); // Запрещаем внешние прерывания INT0(PORTD2) count++; if (count > 0) { Serial.println("Timer ON"); // Для отладки } } void setup () { Serial.begin(9600); // Для отладки cli(); PORTD |= (1 << BUTTON_PIN); // INPUT_PULLUP EICRA = (1 << ISC01); // По спадающему фронту на входе INT0(PORTD2) EIMSK |= (1 << INT0); // Разрешаем внешние прерывания INT0(PORTD2) sei(); } void loop () { }
... по спадающему изменению фронта сигнала...
по спадающему фронту сигнала
В "программировании" тема про внутренние прерывания ещё не утонула, там обсуждалась проблема (со стр. 4 более внятно), у которой схожие симптомы были.
Спасибо, сейчас посмотрю.
Н-да, а ссыллку, пожалуйста.
http://arduino.ru/forum/programmirovanie/vnutrennie-preryvaniya?page=3#c...
Спасибо, помогло!
Neogar, вы ещё учтите, что ARDUINO IDE по-умолчанию запускает таймер1 из внутренней функции init(), которая запускается до сетапа. Соответссно разумнее будет его остановить в первой-же строчке сетапа, во избежание проблем , и следующей строкой на всякий случай отчистить флаги таймера (TIFR1=0xff).
Neogar, вы ещё учтите, что ARDUINO IDE по-умолчанию запускает таймер1 из внутренней функции init(), которая запускается до сетапа. Соответссно разумнее будет его остановить в первой-же строчке сетапа, во избежание проблем , и следующей строкой на всякий случай отчистить флаги таймера (TIFR1=0xff).
Спасибо, dimax! Регистр TIFR1 я уже очистил, остановку таймера учту.
В этой статье нашел хорошее описание настройки таймера.
Neogar, вы ещё учтите, что ARDUINO IDE по-умолчанию запускает таймер1
Разве? Таймер 0. Или ты имеешь в виду "конфигурирует для ШИМа"?
Как я понял функция "init()" в файле "wiring.c" запускает ТС0 и конфигурирует ТС1 и ТС2 для ШИМа, но не запускает их. Под остановкой ТС1 перед настройкой можно подразумевать его реинициализацию и запуск.
Получается, что если в скетче использовать стандартные функции
, то таймеры настраиваются. Но если использовать
, то таймеры будут НЕ настроены и НЕ запущены (по дефолту после сброса микроконтроллера).
Если в main() не включите init(), то останетесь без millis(), delay() и прочих фишек Ардуино.)