ВНЕШНИЕ ПРЕРЫВАНИЯ НА РАЗНЫХ НОГАХ МИКРОКОНТРОЛЛЕРОВ СЕМЕЙСТВА ATMEGA.

 

AtmegaPA pinout

 

Помнится, еще на заре своего увлечения программированием я делал систему климат-контроля на базе Ардуино и очень удивлялся, почему у меня не работают кнопки. На самом деле, чем больше пихаешь в loop() всякого мусора, тем хуже. По идее, там должно крутиться что-то базовое, типа отрисовки данных на экране или что-то наподобие. Короче, только самый важный, базовый функционал. И чем меньше кода - тем лучше, потому что микроконтроллер одноядерный и выполняет инструкции последовательно, что иногда бывает долго и не всегда попадает в ритм с вашими нажатиями кнопок - когда вы жмете PB1 он может обрабатывать PB0 тогда не будет никакой реакции до следующего цикла. Однако же, на всякие кнопочки, которые должны сработать при нажатии немедленно, можно создать обработчик по прерыванию. Приведу здесь небольшое опаисание что к чему и маленький примерчик.

To understand it better, I will divide this guide into three parts:

  • Register of ports that will trigger interrupts (PCICR)
  • Pin registers that will trigger interrupts (PCMSK)
  • Generate Events (ISR PCINT Vect)
PCICR | = B00000001; // We activate the interrupts of the PB port
PCICR | = B00000010; // We activate the interrupts of the PC port
PCICR | = B00000100; // We activate the interrupts of the PD port
PCICR | = B00000101; // We activate the interrupts of the PB and PD ports
  • PCMSK0 -> PB -> D8 to D13 pins
  • PCMSK1 -> PC -> A0 to A5 pins
  • PCMSK2 -> PD -> D0 to D7 pins
CMSK0 |= B00000100; // We activate the interrupts on pin D10
PCMSK1 |= B00001000; // We activate the interrupts on pin A3
  • PCINT0_vect -> PB -> Pines D8 a D13
  • PCINT1_vect -> PC -> Pines A0 a A5
  • PCINT2_vect-> PD -> Pines D0 a D7

To be able to use them we will simply have to use the ISR routine, for which I always say that the best is an example to understand it:

ISR (PCINT0_vect) {
// code to execute
}
Здесь, как пример, приведу спизженный где-то Ардуино говнокод:
 
int counter = 0;
void setup() {
  Serial.begin(9600);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  PCICR |= B00000100; // Enable interrupts on PD port
  PCMSK2 |= B00110000; // Trigger interrupts on pins D4 and D5
sei(); //enable interrupts
} void loop() { Serial.print("The counter is now at: "); Serial.println(counter);   delay(100); } ISR (PCINT2_vect) { if (digitalRead(4)) { counter++; } else if (digitalRead(5)) { counter--; } }

Тут главное понять суть. Активация прерываний идет двумя регистрами:

PCICR - здесь мы указываем порт.

PCMSK2 - здесь мы указываем конкретные ноги.

ISR (PCINT2_vect) {
//Здесь наш обработчик. Можно прописать вызов какой-то функции, проинициированной ранее.
}

Разумеется, все то же должно работать и в Microchip Studio, я уже публиковал программу управления энкодером на основе таких прерываний.