วันพุธที่ 22 มีนาคม พ.ศ. 2560

Arduino กับการใช้งานอินเตอร์รัพท์

Arduino กับการใช้งานอินเตอร์รัพท์


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

ชนิดของอินเตอร์รัพท์

แบ่งตามชนิดของการเกิดได้ดังนี้
  • อินเตอร์รัพท์จากภายนอก เช่น การเปลี่ยนสถานะลอจิกของพอร์ตใดพอร์ตหนึ่ง
  • อินเตอร์รัพท์จากภายใน เช่น อินเตอร์รัพท์ที่เกิดจากทามเมอร์

การควบคุมอินเตอร์รัพท์

การควบคุมอินเตอร์รัพท์ คือการควบคุมว่าจะให้ซีพียูตอบสนองต่ออินเตอร์รัพท์หรือไม่ แบ่งได้ดังนี้
    • Disable Interrupt คือการควบคุมให้ซีพียูไม่ตอบสนองกับอินเตอร์รัพท์ เมื่อเกิดการอินเตอร์รัพท์ขึ้นซีพียูจะปล่อยผ่านอินเตอร์รัพท์นั้น
    • Enable Interrupt คือการควบคุมให้ซีพียูตอบสนองต่ออินเตอร์รัพท์ไปตามปกติ
การควบคุมอินเตอร์รัพท์จะใช้ในกรณีที่ต้องการให้ซีพียูกระทำคำสั่งที่ไม่สามารถหยุดการทำงานได้ เช่น การนับเวลา หากมีการอินเตอร์รัพท์เกิดขึ้นจะทำให้การนับเวลาคลาดเคลื่อนได้

การใช้งานอินเตอร์รัพท์ใน Arduino

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

พอร์ตที่สามารถใช้งานอินเตอร์รัพท์ได้

ในบอร์ด Arduino จะมีพอร์ตที่สามารถใช้อินเตอร์รัพท์ได้แบบจำกัด โดยพอร์ตที่สามารถใช้อินเตอร์รัพท์ได้ในบอร์ด Arduino แต่ละรุ่นก็จะแตกต่างกัน ซึ่งสามารถดูได้ตามตารางด้านล่างนี้
Boardint.0int.1int.2int.3int.4int.5
Uno, Ethernet23    
Mega25602321201918
Leonardo32017 
Due(see below)
ในการสร้างอินเตอร์รัพท์ จะใช้ลำดับขาอินเตอร์รัพท์มาใส่ในฟังก์ชั่น เช่น ในตาราง บอร์ด Arduino Uno มีพอร์ต 2 เป็นขาอินเตอร์รัพท์ลำดับที่ 0 ดังนั้นเมื่อนำไปใช้ในคำสั่ง ต้องนำหมายเลข 0 ไปใส่ ส่วนใน Arduino Due สามารถใช้งานอินเตอร์รัพท์ได้ทุกขา หากนำไปใส่ในคำสั่ง ก็สามารถนำหมายเลขขาไปใส่ได้เลย

คำสั่งกำหนดใช้อินเตอร์รัพท์

คำสั่ง attachInterrupt() เป็นคำสั่งกำหนด และสร้างอินเตอร์รัพท์ โดยมีรูปแบบการใช้งานดังนี้
รูปแบบคำสั่ง attachInterrupt(interrupt, ISR, mode)
  • interrupt คือลำดับขาอินเตอร์รัพท์ตามที่ได้ดูไปในตารางที่ผ่านมา ใน Arduino Due สามารถใส่หมายเลขขาลงไปได้เลย
  • ISR คือชื่อฟังก์ชั่นที่จะไปถูกเรียกขึ้นมาเมื่อเกิดอินเตอร์รัพท์
  • mode รูปแบบที่จะให้เกิดอินเตอร์รัพท์ มีทั้งหมด 4 รูปแบบดังนี้
    • LOW จะเกิดอินเตอร์รัพท์ต่อเมื่อพอร์ตที่กำหนดไว้มีสถานะเป็น LOW
    • CHANGE จะเกิดอินเตอร์รัพท์เมื่อพอร์ตที่กำหนดไว้มีการเปลี่ยนสถานะ เช่น จากสถานะ HIGH เป็น LOW หรือจาก LOW เป็น HIGH
    • RISING จะเกิดอินเตอร์รัพท์เมื่อพอร์ตที่กำหนดไว้มีการเปลี่ยนสถานะจาก LOW เป็น HIGH
    • FALLING จะเกิดอินเตอร์รัพท์เมื่อพอร์ตที่กำหนดไว้มีการเปลี่ยนสถานะจาก HIGH เป็น LOW
    • HIGH จะเกิดอินเตอร์รัพท์ต่อเมื่อพอร์ตที่กำหนดไว้มีสถานะเป็น HIGH
ตัวอย่างการใช้งาน
int ledPin = 13; 

void setup() {
  pinMode(ledPin, OUTPUT);
  attachInterrupt(0, TriggerLED, FALLING);
  // ใช้งานขาอินเตอร์รัพท์ลำดับ 0 หรือขา D2 ใน Arduino Uno R3
  // เรียกฟังก์ชั่น TriggerLED() ขึ้นมาทำงาน เมื่อเกิดอินเตอร์รัพท์ขึ้น
  // เกิดอินเตอร์รัพท์เมื่อรูปแบบเป็น FALLING หรือก็คือจากสถานะ HIGH เป็น LOW
  // จากที่กำหนดไว้ หากใช้พอร์ต D2 ใน Arduino Uno R3 ต่ออยู่กับสวืตซ์ เมื่อ
  // ทำการกดสวิตซ์ จะทำให้สถานะเปลี่ยนจาก LOW เป็น HIGH พอปล่อยสวิตซ์ สถานะ
  // จะเปลี่ยนจาก HIGH เป็น LOW ทำให้เกิดการอินเตอร์รัพท์ขึ้น แล้วไปเรียกฟังก์ชั่น
  // TriggerLED() ขึ้นมาทำงาน 
} 

void loop() { 
  delay(10); 
} 

void TriggerLED() {
  digitalWrite(ledPin, !digitalRead(ledPin));
}
วงจร

คำสั่งควบคุมอินเตอร์รัพท์

มีด้วยกัน 2 คำสั่ง คือ
  • noInterrupt() เป็นคำสั่งที่ทำให้ซีพียูอยู่ในสถานะ Disable Interrupt
  • Interrupt() เป็นคำสั่งที่ทำให้ซีพียูอยู่ในสถานะ Enable Interrupt

คำสั่งยกเลิกใช้อินเตอร์รัพท์

รูปแบบ detachInterrupt(interrupt)
คำสั่ง detachInterrupt() คือคำสั่งที่ใช้ในการยกเลิกการใช้งานอินเตอร์รัพท์ โดยพารามิเตอร์ interrupt ต้องใส่เป็นลำดับขาอินเตอร์รัพท์ หรือใน Arduino Due จะต้องใส่เป็นหมายเลขขา

ไม่มีความคิดเห็น:

แสดงความคิดเห็น