attiny85: ISR не срабатывает для PCINT2?
Я использую attiny85 для считывания скорости вращения вентилятора, сообщаемой парой 4-проводных вентиляторов. Я планировал подключить выход TACH от вентиляторов к контактам 1 и 2, но столкнулся с проблемой: я смог без проблем обработать прерывания на контакте 1, но не могу заставить ISR срабатывать при изменениях на контакте 2. Код, демонстрирующий проблему, выглядит следующим образом:
#define PIN_LED 0
#define PIN_TACH2 2
void setup() {
cli();
pinMode(PIN_TACH2, INPUT_PULLUP);
pinMode(PIN_LED, OUTPUT);
GIMSK |= _BV(PCIE);
PCMSK |= _BV(digitalPinToPCMSKbit(PIN_TACH2));
sei();
}
void loop() {
digitalWrite(PIN_LED, 1);
delay(2000);
}
ISR(PCINT0_vect) {
byte tach2;
tach2 = (PINB & _BV(PIN_TACH2));
if (! tach2) {
digitalWrite(PIN_LED, 0);
}
}
Если я заменю определения PIN_TACH2 и PIN_TACH2_INT на
контакт 1, например...
#define PIN_TACH2 1
#define PIN_TACH2_INT PCINT1
...работает отлично (прерывания также работают для контактов 0 и 3).
Почему я не могу обработать прерывания смены вывода для вывода 2?
для @chrisl
Это всего лишь тестовый код. Светодиод горит до тех пор, пока не сработает ISR, после чего он погаснет на 2 секунды. С прерываниями, подключенными к контактам 1 или 3, все работает так, как и ожидалось: падающий фронт на контакте заставляет светодиод погаснуть.
На контакте 2 ISR никогда не срабатывает.
@larsks, 👍0
Обсуждение1 ответ
Лучший ответ:
Итак, получается, что это была действительно глупая проблема, и полностью по моей вине, но я оставлю этот вопрос здесь в надежде, что это убережет кого-то другого от такой же проблемы.
Ответ...
ПЕРЕД ТЕСТИРОВАНИЕМ СХЕМЫ ОТКЛЮЧИТЕ ПРОГРАММАТОР
Вот и все. При отключенном программаторе все работает как надо.
Поскольку это решение вашей проблемы, пожалуйста, примите свой ответ как правильный, чтобы другие могли увидеть, что это было правильно., @chrisl
@chrisl, тебе придется подождать два дня, чтобы принять свой собственный ответ., @larsks
Я думаю, уже прошло 2 дня, пора., @frogstair
- Почему необходимо использовать ключевое слово volatile для глобальных переменных при обработке прерываний в ардуино?
- Серийное прерывание
- Влияет ли `millis()` на длинные ISR?
- PCINT0, PCINT1, PCINT2 и т. д. на ATtiny45/85
- Как прервать функцию цикла и перезапустить ее?
- Как назначить прерывание на нажатие кнопки с помощью ATtiny? (прерывание не срабатывает с моим кодом)
- Прерывание переполнения таймера AVR не работает
- ATtiny85 AC Phase Control для регулировки яркости лампочки
Я не совсем понимаю, что должен делать ваш код. Вы просто включаете светодиод каждые 2 секунды. Объясните подробнее, чего вы ожидаете, что происходит вместо этого и что вы видите, используя контакты 1 или 3., @chrisl
PCINT должен погасить светодиод. Через 2 секунды он снова загорится. Простой тестовый код. С PCINT1/3, похоже, работает (светодиод можно отключить), но с PCINT2 — нет. Похоже, *должно* работать, но откуда мне знать?, @Majenko
Полагаю, что между номерами контактов и битами PORTB существует соответствие 1:1?, @Majenko
@majenko судя по техническому описанию, так оно и есть., @larsks
Вы не найдёте этого в техническом описании. Вы найдёте это только в исходном коде или документации для используемого вами определения ядра/платы., @Majenko
Константы PCINT* взяты прямо из документации и относятся к битам регистра PCMSK. Судя по [определению платы](https://github.com/damellis/attiny/blob/master/variants/tiny8/pins_arduino.h), нумерация выводов совпадает с нумерацией в документации., @larsks
Ладно, тогда всё выглядит отлично. Должен сказать, я не понимаю, почему это не работает., @Majenko
У вас есть другой чип Attiny? Тот, который вы используете, может быть повреждён., @Gerben
@Gerben Я наблюдаю то же самое поведение со вторым чипом Attiny., @larsks