Arduino и прерывания: быстрый способ получить значения выводов


11

Я использую Arduino Uno и уже настроил его для работы с прерываниями на цифровых выводах 2, 3, 4 и 5 в соответствии с объяснением 1, которое я нашел.

void setup() содержит следующий код для настройки прерываний.

  //Endable Interrupts for PCIE2 Arduino Pins (D0-7)
  PCICR |= (1<<PCIE2);

  //Setup pins 2,3,4,5
  PCMSK2 |= (1<<PCINT18);
  PCMSK2 |= (1<<PCINT19);
  PCMSK2 |= (1<<PCINT20);
  PCMSK2 |= (1<<PCINT21);

  //Trigger Interrupt on rising edge
  MCUCR = (1<<ISC01) | (1<<ISC01);

И теперь функция ISR (PCINT2_vect) срабатывает при каждом прерывании. Это работает как шарм. У меня вопрос, какой самый лучший / быстрый способ узнать, какой пин был сработал?

Я нашел что-то в Re: Лучше использовать ISR (PCINT2_vect) или attachInterrupt на контактах 2, 3? , но я не понимаю код, и он не работает из коробки. Но выглядит впечатляюще ...

Каково решение?

[2] http://arduino.cc/forum/index.php/topic,72496.15.html#lastPost

Редактировать:

В данный момент я читаю состояние контакта из входного регистра контактов:

  if (PIND & 0b00000100)
    Serial.println( "PIN 2" );
  if (PIND & 0b00001000)
    Serial.println( "PIN 3" );
  if (PIND & 0b00010000)
    Serial.println( "PIN 4" );
  if (PIND & 0b00100000)
    Serial.println( "PIN 5" );

В конце я хочу посчитать прерывания на выводах. Но как я могу заверить, что не считаются дважды?


В электронике все больше людей, вероятно, перепутались с Arduinos и другими электронными вещами.
Эрлз

Если вы думаете, вопрос должен быть там, пометьте его. Я решил свои проблемы с логином.
Madc

3
@Earlz: Это вопрос программирования, так что это по теме . Тот факт, что это для любителей платформы, не имеет значения; Посмотрите сотни других вопросов по Arduino на стеке потока для справки.
BlueRaja - Дэнни Пфлюгофт

Ответы:


4

У меня есть первое решение, но я не смог проверить надежность, так как аппаратное обеспечение не закончено.

Сначала я добавил oldPins и tickCount как глобальные переменные:

static byte oldPins = 0;
volatile unsigned int tickCount[4] = { 0, 0, 0, 0 };

И вот как я решил ISR на данный момент. Лучшие решения более чем приветствуются.

ISR( PCINT2_vect ) {
  //Read values from digital pins 2 to 7
  const byte actPins = PIND;
  //Match this values agaist the oldPins bitmask (XOR and AND for raising edge)
  const byte setPins = (oldPins ^ actPins) & actPins;

  if (setPins & 0b00000100)
    tickCount[0]++;
  if (setPins & 0b00001000)
    tickCount[1]++;
  if (setPins & 0b00010000)
    tickCount[2]++;
  if (setPins & 0b00100000)
    tickCount[3]++;

  oldPins = actPins;
}

1
Если вы обновляете tickCount [] в ISR, вы должны объявить его с помощью квалификатора типа 'volatile'.
icarus74

Я обновил код внутри ответа. Для получения дополнительной информации см. Документацию
arduino
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.