Arduino 和中断:获取引脚值的快速方法

电器工程 C++ Arduino 中断
2022-02-02 11:26:19

根据我找到的解释1 ,我使用Arduino Uno并已将其设置为处理数字引脚 2、3、4 和 5 上的中断。

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: 中找到了一些东西:在引脚 2、3 上使用 ISR(PCINT2_vect) 或 attachInterrupt 更好吗?,但我不明白代码,它不能开箱即用。但它看起来令人印象深刻......

解决办法是什么?

[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" );

最后,我想计算引脚上的中断。但是我怎么能保证,没有计算两次呢?

1个回答

我自己有第一个解决方案,但我无法测试可靠性,因为硬件没有完成喷射。

首先,我将 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;
}