Почему не работает прерывание после нажатия кнопки
Реализовать обработку прерывания при нажатии кнопки, и самого старта по переднему фронту, вывод прерывания и к которому подключена кнопка 11. Почему не работает прерывание после нажатия кнопки?
#include <PinChangeInterrupt.h>
const uint8_t buttonPin = 11;
volatile bool buttonPressed = false;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
attachPCINT(buttonPin, buttonISR, RISING);
Serial.begin(9600);
}
void loop() {
if (buttonPressed) {
Serial.println("Button pressed!");
buttonPressed = false;
}
}
void buttonISR() {
buttonPressed = true;
}
Модель:
@Good York, 👍0
Обсуждение1 ответ
Лучший ответ:
Я только что проверил правильный код с некоторыми изменениями:
#include <PinChangeInterrupt.h>
const uint8_t buttonPin = 11;
volatile bool buttonPressed = false;
void buttonISR() {
buttonPressed = true;
}
void loop() {
if (buttonPressed) {
delay(20);
buttonPressed = false;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
}
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
attachPCINT(digitalPinToPCINT(buttonPin), buttonISR, RISING);
pinMode(LED_BUILTIN, OUTPUT);
}
А с attachPCINT(digitalPinToPCINT(buttonPin), buttonISR, RISING);
все работает безупречно. Разница лишь в том, что digitalPinToPCINT
(как пытается предложить каждый пример для библиотеки PinChangeInterrupt).
Вы также пробовали attachInterrupt + digitalPinToInterrupt с выводом 11, но Arduino Uno имеет только два контакта D2 и D3, поддерживающих внешние прерывания. Так что это не могло работать с D11. Это также зависит от MCU (см. справку по attachInterrupt()). р>
PCINT более или менее связан со старыми AVR, такими как Atmega328 или Atmega2560. И PCINT в Atmega2560 доступен не на всех портах (он использует ISR для каждого порта и имеет много портов.
Если причиной является симулятор proteus, вы также можете опустить ISR (поскольку вы здесь ничего серьезного не делаете) и просто опросить пин:
const uint8_t buttonPin = 11;
bool buttonPressed = false;
void loop() {
bool pinHigh = (digitalRead(buttonPin) == HIGH);
if (pinHigh && buttonPressed) { // кнопка отпущена
delay(20);
buttonPressed = false;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
} else if (!pinHigh && !buttonPressed) {
buttonPressed = true;
}
}
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
}
Просто чтобы подчеркнуть это, digitalPinToInterrupt
предназначена для контактов D2 и D3 на Uno (эта функция возвращает 0 или 1 соответственно) при использовании с attachInterrupt
, однако digitalPinToPCINT
предназначена для прерываний **Pin Change**, которые ОП использует., @Nick Gammon
Почему у меня не работает, я использую arduino uno, @Good York
@GoodYork вам нужно изменить: attachPCINT(buttonPin, buttonISR, RISING);
на attachPCINT(digitalPinToPCINT(buttonPin), buttonISR, RISING);
или просто попробуйте использовать мой код (он переключает встроенный светодиод - он очень прост откат тоже), @KIIV
Я скопировал ваш код, просто заменил светодиод на Serial.println
, и что-то у меня не работает, @Good York
Возможно проблема с проводкой. Или, если вы пробуете это только в эмуляторе, обычно это не очень хорошо работает с ISR., @KIIV
Я делаю это в эмуляторе Proteus, @Good York
@GoodYork Пожалуйста, сфотографируйте свою проводку и измените свой вопрос, включив эту фотографию., @Nick Gammon
@NickGammon У меня есть только та модель, которая уже прикреплена к вопросу., @Good York
*Я делаю это в эмуляторе Proteus* - вы не указали это в своем вопросе. Эмуляторы **могут неточно воспроизводить** то, что происходит в реальной жизни. Следовательно, ваша проблема в эмуляторе. Попробуйте использовать настоящую Ардуино., @Nick Gammon
*У меня есть только та модель, которая уже прикреплена к вопросу* - если у вас есть эмулятор, то у вас даже этого нет. Я прочитал вопрос и увидел, что вы утверждали, что используете Arduino Uno., @Nick Gammon
*Почему у меня не работает, я использую arduino uno* - вы должны были сказать "Я использую Arduino Uno в эмуляторе Proteus". Один из них — это реальная аппаратная часть, которая ведет себя предсказуемым образом, которую мы все можем протестировать. Другая часть программного обеспечения., @Nick Gammon
то это просто невозможно сделать в эмуляторе?, @Good York
Вы можете сделать это без прерываний, я обычно просто опрашиваю кнопки каждые несколько миллисекунд. Добавлен код без isr, @KIIV
@KIIV *задача такая: Кнопку надо подключить к соответствующему пину прерывания PCINT3* - у них задача, которая использовать PCINT3. Задача не в том, чтобы решить какую-то реальную проблему., @Nick Gammon
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Как правильно использовать volatile переменные в Arduino?
- Как прервать функцию цикла и перезапустить ее?
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- Управление функцией включения на драйвере микрошагового устройства
- Захват прерывания на обоих фронтах, когда он установлен на RISING или FALLING
Нагрузки на осциллографе может быть достаточно, чтобы отсоединить контакт 11. Рассмотрите возможность отсоединения осциллографа от контакта 11 и повторения теста. Если это сработает, я создам ответ с более подробной информацией и вещами, которые можно попробовать., @st2000
Снял осциллограф с контакта 11, все равно не работает, @Good York
Вы пробовали прикрепить Interrupt вместо этого? https://reference.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/ обратите внимание на использование digitalPinToInterrupt и на то, что только определенные контакты на каждой модели могут использоваться как таковые. Если это работает, вероятно, ошибка в вашем PinChangeInterrupt.h или с чем он связан., @Abel
Пробовал
attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, FALLING)
тоже не работает, @Good YorkСм. https://reference.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/. Обратите внимание, что GPIO 11 НЕ отображается в столбце таблицы со списком выводов, которые можно использовать для генерации прерываний (за исключением nano 33 IOT, Zero и 101) — рекомендуем использовать 2 или 3. Если вы хотите прерывание по переднему фронту, используйте резистор PULL DOWN. https://www.seeedstudio.com/blog/2020/02/21/pull-up-resistor-vs-pull-down-differences-arduino-guide/ Таким образом, нажатие кнопки, а не ее отпускание приводит к int . Наконец, подтвердите, что кнопка будет подпрыгивать., @DrG
Но вывод 11 — это прерывание PCINT3?, @Good York
Какую плату вы используете? Вот хороший простой пример того, как сделать что-то подобное — это может помочь https://roboticsbackend.com/arduino-interrupts/ (мне следовало добавить в этот список хотя бы еще одну плату)., @DrG
Я использую arduino uno, задача следующая: Кнопку нужно подключить к соответствующему пину прерывания PCINT3. Имеется ли в виду задача какие пины запускают прерывание PCINT3, тогда можно было бы подключиться к 3 или 2 пину, @Good York
Я думаю, мне нужно сделать через прерывания смены контакта, что-то вроде этого:
void setup () { pinMode (кнопкаPin, INPUT_PULLUP); PCMSK0 |= (1 << PCINT3); PCIFR |= (1 << PCIE0); attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, RISING); Серийный.начать(9600); }
но это не работает, @Good YorkИзвините, но я не могу интерпретировать вашу задачу для вас. Вот еще одна хорошая ссылка, которая может помочь. https://gammon.com.au/interrupts Сами разберетесь., @DrG
возможно ли отслеживать нажатие кнопки с помощью прерываний смены контакта?, @Good York
Обратите внимание на небольшую разницу между вашим attachPCINT и в [примере](https://github.com/NicoHood/PinChangeInterrupt/blob/master/examples/PinChangeInterrupt_Led/PinChangeInterrupt_Led.ino#L45). Есть дополнительный digitalPinToPCINT, в основном вы, вероятно, ловите радио на какой-то другой пин., @KIIV
@GoodYork, я так понимаю, вы ничего этого не делали с реальным оборудованием. Что вопрос основан только на эмуляции? Вы должны были сказать это в вопросе. Пожалуйста, вернитесь и отредактируйте свой вопрос, четко указав, что вопрос основан только на эмуляции am. (Если вам интересно, почему эмуляция не отражает реальный мир... возможно, нам следует начать с того, что такие компании, как Atmel (теперь Microchip), вряд ли раскроют все о конструкции своего процессора.), @st2000