Uno có thể xử lý bao nhiêu chân ngắt?


16

Tôi đang xem xét sử dụng bộ thu RC 7 kênh với Arduino Uno R3. Trong tài liệu này, có đề cập đến tối đa 2 chân ngắt, trong khi trên một số blog khác tôi đã thấy đề cập đến việc sử dụng tối đa 20 chân làm ngắt, với thư viện PinChangeInt. Vì vậy, Arduino có thể xử lý bao nhiêu ngắt? Và điều này có khác với bao nhiêu có thể được xử lý với phần mềm hỗ trợ như PinChangeInt không?

Câu trả lời:


13

Có hai loại ngắt "thay đổi pin". Các ngắt ngoài, trong đó có hai trên Uno. Chúng được gọi là 0 và 1, tuy nhiên chúng đề cập đến chân kỹ thuật số 2 và 3 trên bảng. Chúng có thể được cấu hình để phát hiện tăng, giảm, thay đổi (tăng hoặc giảm) hoặc THẤP.

Ngoài ra, đó là các ngắt "thay đổi pin", giúp phát hiện sự thay đổi trạng thái chân trong bất kỳ trong số 20 chân (A0 đến A5 và D0 đến D13). Các ngắt thay đổi pin này cũng dựa trên phần cứng , vì vậy, bản thân chúng sẽ nhanh như các ngắt bên ngoài.

Cả hai loại đều hơi khó sử dụng ở cấp độ đăng ký, nhưng IDE tiêu chuẩn bao gồm Đính kèm (n) và DetachInterrupt (n) giúp đơn giản hóa giao diện với các ngắt ngoài. Bạn cũng có thể sử dụng Thư viện thay đổi mã pin để đơn giản hóa các ngắt thay đổi pin.

Tuy nhiên, chỉ đạo thư viện trong một phút, chúng ta có thể thiết lập rằng các ngắt thay đổi pin có thể nhanh hơn hoặc nhanh hơn các ngắt bên ngoài. Đối với một điều, mặc dù các ngắt thay đổi pin hoạt động trên các lô chân, bạn không phải kích hoạt toàn bộ lô. Ví dụ: nếu bạn muốn phát hiện các thay đổi trên chân D4, điều này sẽ đủ:

Ví dụ phác thảo:

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 ()
  {
  }

Thử nghiệm của tôi chỉ ra rằng phải mất 1.6 nút để pin "thử nghiệm" (chân 5) phản ứng với thay đổi trên chân ngắt (chân 4).


Bây giờ nếu bạn thực hiện phương pháp đơn giản (lười biếng?) Và sử dụng Đính kèm () bạn sẽ thấy kết quả chậm hơn, không nhanh hơn.

Mã ví dụ:

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 ()
  {
  }

Việc này cần 3.7 Thay đổi để kiểm tra pin thử nghiệm, nhiều hơn rất nhiều so với 1.6. Tại sao? Bởi vì mã trình biên dịch phải tạo cho trình xử lý ngắt "chung" phải lưu mọi thanh ghi có thể hiểu được (đẩy chúng) khi vào ISR, sau đó khôi phục chúng (bật chúng) trước khi quay lại. Thêm vào đó là chi phí của một cuộc gọi chức năng khác.


Bây giờ chúng ta có thể giải quyết vấn đề đó bằng cách tránh Đính kèm () và tự thực hiện:

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 ()
  {
  }

Đó là tốc độ nhanh nhất trong số tất cả tại 1.52, - có vẻ như một chu kỳ đồng hồ đã được lưu ở đâu đó.


Tuy nhiên, có một cảnh báo cho các ngắt thay đổi pin. Chúng được bó theo từng đợt, vì vậy nếu bạn muốn có nhiều ngắt trên nhiều chân, bạn cần kiểm tra bên trong ngắt cái nào đã thay đổi. Bạn có thể làm điều đó bằng cách lưu trạng thái pin trước đó và so sánh nó với trạng thái pin mới. Điều này không nhất thiết phải đặc biệt chậm, nhưng bạn càng cần kiểm tra nhiều chân thì càng chậm.

Các đợt là:

  • A0 đến A5
  • D0 đến D7
  • D8 đến D13

Nếu bạn chỉ muốn thêm một vài chân ngắt, bạn có thể tránh mọi thử nghiệm bằng cách chỉ chọn sử dụng ghim từ các lô khác nhau (ví dụ: D4 và D8).


Thêm chi tiết tại http://www.gammon.com.au/interrupts


9

Có hai loại ngắt. Những gì Arduino Sân chơi cho biết:

Bộ xử lý ở trung tâm của bất kỳ Arduino nào cũng có hai loại ngắt khác nhau: Thay đổi bên ngoài, và thay đổi pin. Chỉ có hai chân ngắt ngoài trên ATmega168 / 328 (nghĩa là trong Arduino Uno / Nano / Duemilanove), INT0 và INT1, và chúng được ánh xạ tới chân Arduino 2 và 3. Các ngắt này có thể được đặt để kích hoạt trên RISING hoặc FALLING cạnh tín hiệu, hoặc ở mức thấp. Các kích hoạt được giải thích bởi phần cứng và ngắt rất nhanh. Arduino Mega có sẵn một vài chân ngắt ngoài.

Mặt khác, các ngắt thay đổi pin có thể được kích hoạt trên nhiều chân khác. Đối với Arduinos dựa trên ATmega168 / 328, chúng có thể được bật trên bất kỳ hoặc tất cả 20 chân tín hiệu của Arduino; trên Arduinos dựa trên ATmega, chúng có thể được bật trên 24 chân. Chúng được kích hoạt như nhau trên các cạnh tín hiệu RISING hoặc FALLING, do đó, tùy thuộc vào mã ngắt để đặt các chân thích hợp để nhận các ngắt, để xác định điều gì đã xảy ra (chân nào? ... tín hiệu tăng hay giảm?), Và để xử lý nó đúng cách. Hơn nữa, các ngắt thay đổi pin được nhóm thành 3 cổng port trên MCU, do đó chỉ có 3 vectơ ngắt (chương trình con) cho toàn bộ thân của các chân. Điều này làm cho công việc giải quyết hành động trên một ngắt đơn thậm chí còn phức tạp hơn.

Về cơ bản, các ngắt ngoài cực kỳ nhanh vì tất cả đều dựa trên phần cứng. Tuy nhiên, cũng có các ngắt thay đổi pin, nhưng những cái đó dường như chậm hơn nhiều vì chúng chủ yếu dựa trên phần mềm.

tl; dr: 20 chân ngắt với nhau chậm hơn nhiều. 2 chân ngắt là nhanh nhất và hiệu quả nhất.


EDIT: Tôi chỉ nhìn vào biểu dữ liệu và nó nói rằng một ngắt thay đổi pin được kích hoạt cho bất kỳ chân nào được chọn mà không có dấu hiệu nào cho thấy chân nào đã thay đổi (mặc dù nó được chia thành ba vectơ ngắt).

  • Đối với các ngắt ngoài, nó sẽ cho bạn biết pin 3 vừa thay đổi
  • Để thay đổi mã pin, nó sẽ cho bạn biết mã pin đã thay đổi mà bạn đang theo dõi!

Như bạn có thể thấy, một ngắt thay đổi pin sẽ thêm rất nhiều chi phí vào ISR mà bạn phải xử lý bằng cách lưu trữ các trạng thái trước đó và xem đó có phải là pin mà bạn lo lắng không. Có thể tốt cho trạng thái ngủ, nhưng tốt hơn là sử dụng các ngắt bên ngoài.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.