Bir Uno kaç tane kesme pini kullanabilir?


16

Arduino Uno R3 ile 7 kanallı bir RC alıcısı arıyorum. Belgelerde en fazla 2 kesinti iğnesinden bahsederken, diğer bazı bloglarda PinChangeInt kütüphanesi ile kesinti olarak 20 iğneye kadar kullandığımdan söz ettim. Peki, Arduino yerel olarak kaç kesinti yapabilir? Ve bu, PinChangeInt gibi yazılım desteği ile kaçının ele alınabileceğinden farklı mı?

Yanıtlar:


13

İki tip "pin değiştirme" tipi kesinti vardır. Uno'da iki tane olan harici kesintiler. Bunlar 0 ve 1 olarak adlandırılır, ancak karttaki 2 ve 3 dijital pimlerini ifade ederler. Bunlar yükselen, düşen, değişim (yükselen veya düşen) veya DÜŞÜK algılamak için yapılandırılabilir .

Buna ek olarak, 20 pimden herhangi birinde (A0 ila A5 ve D0 ila D13) pim durumunda bir değişiklik tespit eden "pim değiştirme" kesintileri vardır. Bu pim değiştirme kesintileri de donanım tabanlıdır, bu nedenle kendi içlerinde dış kesintiler kadar hızlı olacaktır.

Her iki tür de kayıt düzeyinde biraz kullanışlıdır, ancak standart IDE, arabirimi harici kesintilere basitleştiren attachInterrupt (n) ve detachInterrupt (n) içerir. Pim değiştirme kesintilerini basitleştirmek için Pim Değiştirme Kitaplığı'nı da kullanabilirsiniz .

Bununla birlikte, bir dakika boyunca kütüphaneden uzaklaşarak, pin değiştirme kesintilerinin harici kesintilerden daha hızlı veya daha hızlı olabileceğini belirleyebiliriz. Bir kere, pin değiştirme kesintileri pim grupları üzerinde çalışsa da, tüm partiyi etkinleştirmeniz gerekmez. Örneğin, D4 pimindeki değişiklikleri tespit etmek istiyorsanız, bu yeterli olacaktır:

Örnek çizim:

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

Testlerim, "test" piminin (pim 5) kesme pimindeki (pim 4) bir değişikliğe tepki vermesinin 1.6 µs sürdüğünü göstermektedir.


Şimdi basit (tembel?) Yaklaşımı kullanır ve attachInterrupt () kullanırsanız, sonuçların daha yavaş değil daha yavaş olduğunu göreceksiniz.

Örnek kod:

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

Bu, test pimini değiştirmek için 3.7 µs alır, yukarıdaki 1.6 µs'den çok daha fazla. Neden? Derleyicinin "genel" kesme işleyicisi için üretmesi gereken kod, akla gelebilecek her bir kaydı ISR'ye girdikten sonra kaydetmeli (onları itmeli) ve geri dönmeden önce (onları pop) geri yüklemelidir. Ayrıca başka bir işlev çağrısının ek yükü vardır.


Artık attachInterrupt () yönteminden kaçınarak ve bunu kendimiz yaparak çözebiliriz:

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'de en hızlısı bu - bir saat döngüsü bir yere kaydedilmiş gibi görünüyor.


Pim değişikliği kesintileri için bir uyarı var. Bunlar topludır, bu yüzden çok sayıda pimde kesmeler yapmak istiyorsanız, hangisinin değiştiği kesmenin içinde test etmeniz gerekir . Önceki pin durumunu kaydedip yeni pin durumu ile karşılaştırarak bunu yapabilirsiniz. Bu özellikle yavaş değildir, ancak kontrol etmeniz gereken daha fazla iğne, daha yavaş olacaktır.

Partiler:

  • A0 - A5
  • D0 - D7
  • D8 ila D13

Sadece birkaç kesme pimi istiyorsanız, sadece farklı gruplardan (örneğin D4 ve D8) pimler kullanmayı seçerek herhangi bir testten kaçınabilirsiniz.


Daha fazla ayrıntı için http://www.gammon.com.au/interrupts


9

İki tür kesinti vardır. Arduino Oyun Parkı ne dedi:

Herhangi bir Arduino'nun kalbindeki işlemcinin iki farklı türde kesintisi vardır: “harici” ve “pim değişimi”. ATmega168 / 328'de (yani, Arduino Uno / Nano / Duemilanove'da), INT0 ve INT1'de yalnızca iki harici kesme pimi vardır ve bunlar Arduino pimleri 2 ve 3'e eşleştirilebilir. DÜŞEN sinyal kenarları veya düşük seviyede. Tetikleyiciler donanım tarafından yorumlanır ve kesinti çok hızlıdır. Arduino Mega'nın birkaç harici kesme pimi daha var.

Diğer yandan, pim değiştirme kesintileri daha birçok pim üzerinde etkinleştirilebilir. ATmega168 / 328 tabanlı Arduinos için, Arduino'nun 20 sinyal pininin herhangi birinde veya hepsinde etkinleştirilebilir; ATmega tabanlı Arduinos'da 24 pinle etkinleştirilebilir. RISING veya FALLING sinyal kenarlarında eşit olarak tetiklenirler, bu yüzden kesinti almak için uygun pinleri ayarlamak, ne olduğunu belirlemek (sinyal hangi pin? ... sinyal yükseldi veya düştü?) Ve düzgün işlemek için. Ayrıca, pim değiştirme kesintileri MCU üzerinde 3 “port” olarak gruplanır, bu nedenle tüm pim gövdesi için sadece 3 kesinti vektörü (alt rutinler) vardır. Bu, tek bir kesintideki eylemi çözme işini daha da karmaşık hale getirir.

Temel olarak, harici kesintiler, hepsi donanım tabanlı olduğu için son derece hızlıdır. Ancak, pin değişikliği kesintileri de var, ancak bunlar çoğunlukla yazılım tabanlı oldukları için çok daha yavaş görünüyor.

tl; dr: 20 kesme pimi birlikte çok daha yavaştır. 2 kesme pimi en hızlı ve en verimlidir.


EDIT: Ben sadece veri sayfasına baktım ve hangi pim değiştiğini (üç kesme vektörüne bölünmesine rağmen) hiçbir belirti ile seçilen herhangi bir pim için bir pim değişim kesmesi tetiklendi diyor .

  • Harici kesmeler için, pin 3'ün yeni değiştiğini söyleyecektir
  • Pim değişikliği için izlediğiniz bir pim değişikliğini size söyleyecektir !

Gördüğünüz gibi, bir pin değiştirme kesintisi, önceki durumları depolayarak ve endişelendiğiniz pin olup olmadığını görerek ISR'ye çok fazla yük ekler. Uyku durumu için iyi olabilir, ancak harici kesintileri kullanmak daha iyidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.