Uno가 처리 할 수있는 인터럽트 핀은 몇 개입니까?


16

Arduino Uno R3과 함께 7 채널 RC 수신기를 사용하려고합니다. 문서에는 최대 2 개의 인터럽트 핀에 대한 언급이 있지만 다른 블로그에서는 PinChangeInt 라이브러리와 함께 최대 20 개의 핀을 인터럽트로 사용하는 것에 대한 언급을 보았습니다. 그렇다면 Arduino는 기본적으로 몇 개의 인터럽트를 처리 할 수 ​​있습니까? 그리고 이것은 PinChangeInt와 같은 소프트웨어 지원으로 처리 할 수있는 수와 다른가?

답변:


13

"핀 변경"유형 인터럽트에는 두 가지 유형이 있습니다. Uno에 2 개의 외부 인터럽트가 있습니다. 그것들은 0과 1이라고 불리지 만 보드의 디지털 핀 2와 3을 가리 킵니다. 이들은 상승, 하강, 변화 (상승 또는 하강) 또는 LOW 를 감지하도록 구성 할 수 있습니다 .

그 외에도 20 개의 핀 (A0 ~ A5 및 D0 ~ D13)에서 핀 상태 변경을 감지하는 "핀 변경"인터럽트가 있습니다. 이 핀 변경 인터럽트는 하드웨어 기반 이므로 외부 인터럽트만큼 빠릅니다.

두 가지 유형 모두 레지스터 수준에서 약간 사용하기 쉽지만 표준 IDE에는 attachInterrupt (n) 및 detachInterrupt (n)이 포함되어있어 외부 인터럽트 인터페이스를 단순화합니다. 핀 변경 라이브러리 를 사용하여 핀 변경 인터럽트를 단순화 할 수도 있습니다 .

그러나 1 분 동안 라이브러리에서 벗어나면 핀 변경 인터럽트가 외부 인터럽트보다 빠르거나 빠를 수 있습니다. 우선 핀 배치 인터럽트가 핀 배치에서 작동하지만 전체 배치를 활성화 할 필요는 없습니다. 예를 들어, D4 핀의 변경 사항을 감지하려면 다음과 같이 충분합니다.

스케치 예 :

ISR (PCINT2_vect)
 {
 // handle pin change interrupt for D0 to D7 here
 if (PIND & bit (4))  // if it was high
   PORTD |= bit (5);  // turn on D5
 else
   PORTD &= ~bit (5); // turn off D5
 }  // end of PCINT2_vect

void setup ()
  { 
  // pin change interrupt (example for D4)
  PCMSK2 |= bit (PCINT20);  // want pin 4
  PCIFR  |= bit (PCIF2);    // clear any outstanding interrupts
  PCICR  |= bit (PCIE2);    // enable pin change interrupts for D0 to D7
  pinMode (4, INPUT_PULLUP);
  pinMode (5, OUTPUT);
  }  // end of setup

void loop ()
  {
  }

필자의 테스트에 따르면 "테스트"핀 (핀 5)이 인터럽트 핀 (핀 4)의 변화에 ​​반응하는 데 1.6µs가 걸린 것으로 나타났습니다.


이제 간단한 (lazy?) 접근 방식을 사용하고 attachInterrupt ()를 사용하면 결과가 더 빠르지 않고 느리다는 것을 알 수 있습니다.

예제 코드 :

void myInterrupt ()
 {
 if (PIND & bit (2))  // if it was high
   PORTD |= bit (5);  // turn on D5
 else
   PORTD &= ~bit (5); // turn off D5
 }  // end of myInterrupt

void setup ()
  { 
  attachInterrupt (0, myInterrupt, CHANGE);
  pinMode (2, INPUT_PULLUP);
  pinMode (5, OUTPUT);
  }  // end of setup

void loop ()
  {
  }

테스트 핀을 교체하는 데 3.7µs가 걸리며, 이는 1.6µs보다 훨씬 높습니다. 왜? 컴파일러가 "일반적인"인터럽트 핸들러에 대해 생성해야하는 코드는 ISR에 진입 할 때 모든 가능한 레지스터를 저장 한 다음 (누르고) 반환하기 전에 복원해야합니다. 또한 다른 함수 호출의 오버 헤드가 있습니다.


이제 우리는 attachInterrupt ()를 피하고 스스로 수행함으로써 그 문제를 해결할 수 있습니다.

ISR (INT0_vect)
 {
 if (PIND & bit (2))  // if it was high
   PORTD |= bit (5);  // turn on D5
 else
   PORTD &= ~bit (5); // turn off D5
 }  // end of INT0_vect

void setup ()
  { 
  // activate external interrupt 0

  EICRA &= ~(bit(ISC00) | bit (ISC01));  // clear existing flags
  EICRA |=  bit (ISC00);    // set wanted flags (any change interrupt)
  EIFR   =  bit (INTF0);    // clear flag for interrupt 0
  EIMSK |=  bit (INT0);     // enable it

  pinMode (2, INPUT_PULLUP);
  pinMode (5, OUTPUT);
  }  // end of setup

void loop ()
  {
  }

이는 1.52 µs에서 가장 빠릅니다. 한 클럭 사이클이 어딘가에 저장된 것처럼 보입니다.


그래도 핀 변경 인터럽트에는 한 가지주의 사항이 있습니다. 일괄 처리되므로 많은 핀에 인터럽트 를 적용 하려면 인터럽트 내부에서 변경된 핀을 테스트해야합니다 . 이전 핀 상태를 저장하고이를 새 핀 상태와 비교하면됩니다. 반드시 느릴 필요는 없지만 확인할 핀이 많을수록 느려집니다.

배치는 다음과 같습니다.

  • A0에서 A5
  • D0에서 D7
  • D8에서 D13

인터럽트 핀을 몇 개 더 원하는 경우 다른 배치 (예 : D4 및 D8)의 핀을 사용하도록 선택하면 테스트를 피할 수 있습니다.


자세한 내용은 http://www.gammon.com.au/interrupts


9

인터럽트에는 두 가지 유형이 있습니다. 무엇 아두 이노 운동장은 말했다 :

Arduino의 핵심 프로세서에는 "외부"및 "핀 변경"이라는 두 가지 종류의 인터럽트가 있습니다. ATmega168 / 328 (예 : Arduino Uno / Nano / Duemilanove), INT0 및 INT1에는 2 개의 외부 인터럽트 핀만 있으며 Arduino 핀 2 및 3에 매핑됩니다. 이러한 인터럽트는 RISING 또는 트리거시 트리거되도록 설정할 수 있습니다. 하강 신호 에지 또는 로우 레벨. 트리거는 하드웨어에 의해 해석되며 인터럽트는 매우 빠릅니다. Arduino Mega에는 몇 가지 외부 인터럽트 핀이 있습니다.

반면 핀 변경 인터럽트는 더 많은 핀에서 활성화 될 수 있습니다. ATmega168 / 328 기반 Arduino의 경우 Arduino의 신호 핀 중 일부 또는 모두에서 활성화 할 수 있습니다. ATmega 기반 Arduino의 경우 24 핀에서 활성화 할 수 있습니다. RISING 또는 FALLING 신호 에지에서 동일하게 트리거되므로 인터럽트를 수신 할 적절한 핀을 설정하고 어떤 핀이 발생했는지 (신호 핀이 상승 또는 하강 했는가) 결정하는 것은 인터럽트 코드에 달려 있습니다. 제대로 처리합니다. 또한 핀 변경 인터럽트는 MCU에서 3 개의 "포트"로 그룹화되므로 전체 핀 바디에 대해 3 개의 인터럽트 벡터 (서브 루틴) 만 있습니다. 이를 통해 단일 인터럽트에 대한 조치를 해결하는 작업이 훨씬 더 복잡해집니다.

기본적으로 외부 인터럽트는 모두 하드웨어 기반이기 때문에 매우 빠릅니다. 그러나 핀 변경 인터럽트도 있지만 소프트웨어 기반이기 때문에 속도가 훨씬 느려 보입니다.

tl; dr : 20 개의 인터럽트 핀이 함께 훨씬 느립니다. 2 개의 인터럽트 핀이 가장 빠르고 효율적입니다.


편집 : 방금 데이터 시트를 보았고 어떤 핀이 변경되었는지 표시하지 않고 선택한 핀 하나 에 대해 핀 변경 인터럽트가 트리거된다고 말합니다 (3 개의 인터럽트 벡터로 나뉘어 있음).

  • 외부 인터럽트의 경우 3 번 핀이 변경 되었음을 알려줍니다
  • 핀 변경의 경우 모니터링중인 핀 변경 사항을 알려줍니다 !

보다시피, 핀 변경 인터럽트는 이전 상태를 저장하고 걱정되는 핀인지 확인하여 처리해야하는 ISR에 많은 오버 헤드를 추가합니다. 수면 상태에는 문제가 없지만 외부 인터럽트를 사용하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.