Uno สามารถจัดการพินขัดจังหวะได้กี่อัน?


16

ฉันกำลังมองหาการใช้ตัวรับสัญญาณ RC 7 ช่องด้วย Arduino Uno R3 ในเอกสารประกอบมีการกล่าวถึงหมุดอินเตอร์รัปต์สูงสุด 2 อันในขณะที่ในบล็อกอื่น ๆ ที่ฉันได้เห็นการใช้อินเทอร์รัปต์มากถึง 20 พินโดยมีไลบรารี PinChangeInt ดังนั้น Arduino สามารถขัดจังหวะได้กี่ตัว และนี่แตกต่างจากจำนวนที่สามารถจัดการกับการสนับสนุนซอฟต์แวร์เช่น PinChangeInt ได้หรือไม่

คำตอบ:


13

การขัดจังหวะประเภท "การเปลี่ยนพิน" มีสองประเภท การขัดจังหวะภายนอกซึ่งมีสองอย่างใน Uno พวกเขาเรียกว่า 0 และ 1 แต่พวกเขาอ้างถึงหมุดดิจิตอล 2 และ 3 บนกระดาน เหล่านี้สามารถกำหนดค่าให้ตรวจจับเพิ่มขึ้นลดลงเปลี่ยน (เพิ่มขึ้นหรือลดลง) หรือต่ำ

นอกจากนั้นยังเป็นการขัดจังหวะ "การเปลี่ยนพิน" ซึ่งตรวจจับการเปลี่ยนแปลงสถานะพินใน 20 พินใด ๆ (A0 ถึง A5 และ D0 ถึง D13) การขัดจังหวะการเปลี่ยนพินเหล่านี้ยังเป็นไปตามฮาร์ดแวร์ดังนั้นในตัวมันเองจะเร็วเท่ากับการขัดจังหวะภายนอก

ทั้งสองชนิดมีการใช้งานในระดับรีจิสเตอร์เล็กน้อย แต่ IDE มาตรฐานประกอบด้วย attachInterrupt (n) และ detachInterrupt (n) ซึ่งทำให้อินเตอร์เฟซเข้ากับอินเตอร์รัปต์ภายนอกได้ง่าย คุณยังสามารถใช้Pin Change Libraryเพื่อทำให้การขัดจังหวะการเปลี่ยนพินง่ายขึ้น

อย่างไรก็ตามการล้างไลบรารีเป็นเวลาหนึ่งนาทีเราสามารถสร้างการขัดจังหวะการเปลี่ยนพินได้เร็วหรือเร็วกว่าอินเตอร์รัปต์ภายนอก สำหรับสิ่งหนึ่งแม้ว่าการเปลี่ยนพินจะหยุดการทำงานของแบทช์ แต่คุณไม่จำเป็นต้องเปิดใช้งานแบทช์ทั้งหมด ตัวอย่างเช่นหากคุณต้องการตรวจจับการเปลี่ยนแปลงในพิน 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 ()
  {
  }

การทดสอบของฉันระบุว่าใช้เวลา 1.6 fors สำหรับพิน "ทดสอบ" (พิน 5) เพื่อตอบสนองต่อการเปลี่ยนแปลงของหมุดขัดจังหวะ (ขา 4)


ตอนนี้ถ้าคุณใช้วิธีง่ายๆ (สันหลังยาว) และใช้ 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 tos ในการเปลี่ยนพินการทดสอบมากกว่า 1.6 aboves ด้านบน ทำไม? เนื่องจากรหัสที่คอมไพเลอร์จำเป็นต้องสร้างสำหรับตัวจัดการขัดจังหวะ "ทั่วไป" จึงต้องบันทึกการลงทะเบียนที่เป็นไปได้ทั้งหมด (ดันพวกมัน) เมื่อเข้าสู่ 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กล่าวว่า:

โปรเซสเซอร์ที่เป็นหัวใจของ Arduino ใด ๆ มีการขัดจังหวะสองแบบ:“ ภายนอก” และ“ การเปลี่ยนพิน” มีเพียงอินเตอร์พินขัดจังหวะภายนอกสองตัวบน ATmega168 / 328 (เช่นใน Arduino Uno / Nano / Duemilanove), INT0 และ INT1 และพวกเขาจะถูกแมปกับ Arduino pins 2 และ 3 อินเทอร์รัปต์เหล่านี้สามารถตั้งค่าให้เรียกใช้ RISING หรือ การตกของขอบสัญญาณหรือในระดับต่ำ ฮาร์ดแวร์จะถูกทริกเกอร์ตีความและขัดจังหวะเร็วมาก Arduino Mega มีหมุดขัดจังหวะภายนอกเพิ่มเติมอีกสองสามรายการ

ในทางกลับกันการขัดจังหวะการเปลี่ยนพินสามารถเปิดใช้งานบนพินอื่น ๆ อีกมากมาย สำหรับ Arduinos ที่ใช้ ATmega168 / 328 พวกเขาสามารถเปิดใช้งานบนหมุดสัญญาณ Arduino ใด ๆ หรือทั้งหมด 20 ตัว บน Arduinos ที่ใช้ ATmega สามารถเปิดใช้งานได้บน 24 พิน พวกมันถูกทริกเกอร์อย่างเท่าเทียมกันบนขอบสัญญาณ RISING หรือ FALLING ดังนั้นมันขึ้นอยู่กับการขัดจังหวะของรหัสเพื่อตั้งพินที่เหมาะสมที่จะรับสัญญาณขัดจังหวะเพื่อตรวจสอบสิ่งที่เกิดขึ้น เพื่อจัดการกับมันอย่างถูกต้อง นอกจากนี้การขัดจังหวะการเปลี่ยนพินจะถูกจัดกลุ่มเป็น 3“ พอร์ต” บน MCU ดังนั้นจึงมีเพียง 3 เวกเตอร์ขัดจังหวะ (รูทีนย่อย) สำหรับร่างกายทั้งหมดของหมุด สิ่งนี้ทำให้งานของการแก้ไขการกระทำบนขัดจังหวะเดียวที่ซับซ้อนยิ่งขึ้น

โดยพื้นฐานแล้วการอินเตอร์รัปต์ภายนอกนั้นเร็วมากเนื่องจากเป็นฮาร์ดแวร์ทั้งหมด อย่างไรก็ตามยังมีการเปลี่ยนแปลงการขัดจังหวะด้วยหมุด แต่สิ่งเหล่านั้นดูเหมือนจะช้ากว่ามากเพราะส่วนใหญ่เป็นซอฟต์แวร์พื้นฐาน

tl; dr:หมุดขัดจังหวะทั้ง 20 ตัวพร้อมกันนั้นช้ากว่ามาก หมุดขัดจังหวะ 2 อันรวดเร็วและมีประสิทธิภาพมากที่สุด


แก้ไข:ฉันเพิ่งดูแผ่นข้อมูลและมันบอกว่ามีการขัดจังหวะการเปลี่ยนพินสำหรับหมุดใด ๆที่เลือกโดยไม่มีข้อบ่งชี้ว่ามีการเปลี่ยนแปลงพินใด (แม้ว่ามันจะแบ่งออกเป็นสามเวกเตอร์ขัดจังหวะ)

  • สำหรับการขัดจังหวะภายนอกมันจะบอกคุณว่าขา 3 เพิ่งเปลี่ยนไป
  • สำหรับการเปลี่ยนพินมันจะบอกคุณว่าเปลี่ยนพินที่คุณกำลังตรวจสอบ!

อย่างที่คุณเห็นการขัดจังหวะการเปลี่ยนพินเพิ่มค่าใช้จ่ายจำนวนมากใน ISR ที่คุณต้องจัดการโดยการจัดเก็บสถานะก่อนหน้านี้และดูว่าเป็นพินที่คุณกังวลหรือไม่ อาจดีสำหรับสถานะสลีป แต่จะดีกว่าถ้าใช้อินเทอร์รัปต์ภายนอก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.