Print
Category: Microcontroller & Microprocessor
Hits: 1141

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

การขัดจังหวะสามารถแบ่งออกได้เป็น 2 ประเภทหลักๆ คือ

หลักการทำงานของการขัดจังหวะ มีดังนี้

  1. อุปกรณ์ภายนอกหรือซอฟต์แวร์จะส่งสัญญาณขัดจังหวะไปยังไมโครโปรเซสเซอร์
  2. ไมโครโปรเซสเซอร์จะหยุดการทำงานที่ดำเนินอยู่ในปัจจุบันชั่วคราว
  3. ไมโครโปรเซสเซอร์จะบันทึกค่าสถานะการทำงานปัจจุบันลงในหน่วยความจำ
  4. ไมโครโปรเซสเซอร์จะเปลี่ยนเส้นทางการประมวลผลไปยังโปรแกรมย่อยการขัดจังหวะ
  5. โปรแกรมย่อยการขัดจังหวะจะจัดการกับเหตุการณ์สำคัญที่เกิดขึ้น
  6. โปรแกรมย่อยการขัดจังหวะจะส่งสัญญาณกลับไปยังไมโครโปรเซสเซอร์
  7. ไมโครโปรเซสเซอร์จะกลับมาทำงานที่ดำเนินอยู่เดิม

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

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

ไมโครคอนโทรลเลอร์ ESP32 พัฒนาโดย Espressif Systems มีระบบขัดจังหวะที่ยืดหยุ่นมาก IRAM_ATTR เป็นคำหลักที่ใช้ระบุว่าควรวางฟังก์ชันเฉพาะไว้ใน RAM ภายในของ ESP32 เพื่อการดำเนินการที่รวดเร็วยิ่งขึ้น โดยเฉพาะอย่างยิ่งที่สำคัญอย่างยิ่งสำหรับ Interrupt Service Routines (ISR) เพื่อให้แน่ใจว่าฟังก์ชันดังกล่าวสามารถทำงานได้อย่างรวดเร็วและไม่ถูกขัดจังหวะโดยการทำงานของหน่วยความจำแฟลช .

จำนวน "ชุดการขัดจังหวะ" ที่สามารถรองรับได้:

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



อ้างอิงถึงการใช้IRAM_ATTR คำหลักสำหรับรูทีนการบริการขัดจังหวะ (ISR) บน ESP32 โดยทั่วไปจะทำเพื่อให้แน่ใจว่า ISR ถูกจัดเก็บไว้ใน RAM ภายใน (IRAM) ของ ESP32 เพื่อให้สามารถดำเนินการได้อย่างรวดเร็วและไม่ได้รับผลกระทบจากการทำงานของแฟลชที่อาจเกิดขึ้น

อธิบายให้ชัดเจนกว่านี้:

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

เพื่อป้องกันสิ่งนี้ ควรวางโค้ดสำคัญเช่น ISR ไว้ใน IRAM เพื่อให้แน่ใจว่าการตอบสนองของการขัดจังหวะจะเกิดขึ้นทันที และไม่ต้องรอการทำงานของแฟลชใดๆ

นี่เป็นตัวอย่างง่ายๆ ของวิธีที่คุณอาจใช้IRAM_ATTR ด้วย ISR:

 

void IRAM_ATTR handleInterrupt() {

    // Your ISR code here

}

   โดยการวางIRAM_ATTR ก่อนคำจำกัดความฟังก์ชัน ISR คุณกำลังสั่งให้ ESP-IDF (กรอบการพัฒนาอย่างเป็นทางการสำหรับ ESP32) เพื่อวางจัดการขัดจังหวะ ทำงานใน RAM ภายใน ช่วยให้มั่นใจถึงการดำเนินการที่รวดเร็วเมื่อเกิดการขัดจังหวะ

อย่างไรก็ตาม โปรดทราบว่า IRAM มีขนาดจำกัด ดังนั้นให้ใช้IRAM_ATTR อย่างรอบคอบและเฉพาะสำหรับฟังก์ชันที่ความเร็วในการดำเนินการเป็นสิ่งสำคัญ เช่น ISR หากคุณใช้งานมากเกินไป พื้นที่ IRAM ของคุณจะหมด ซึ่งจะส่งผลให้เกิดข้อผิดพลาดในการคอมไพล์

 

ตัวอย่าง 5 buttons

// Define 5 buttons
struct Button {
const uint8_t PIN;
uint32_t numberKeyPresses;
bool pressed;
};

Button buttons[] = {
{18, 0, false},
{19, 0, false},
{20, 0, false},
{21, 0, false},
{22, 0, false}
};

// ISR for all buttons
void IRAM_ATTR handleInterrupt() {
for (int i = 0; i < 5; i++) {
if (digitalRead(buttons[i].PIN) == LOW) { // If button is pressed
buttons[i].numberKeyPresses++;
buttons[i].pressed = true;
}
}
}

void setup() {
Serial.begin(115200);

// Attach interrupt for all buttons
for (int i = 0; i < 5; i++) {
pinMode(buttons[i].PIN, INPUT_PULLUP);
attachInterrupt(buttons[i].PIN, handleInterrupt, FALLING);
}
}

void loop() {
for (int i = 0; i < 5; i++) {
if (buttons[i].pressed) {
Serial.printf("Button %d has been pressed %u times\n", i + 1, buttons[i].numberKeyPresses);
buttons[i].pressed = false;
}
}
}


อธิบาย Code นี้:

ตรวจสอบให้แน่ใจว่า Pin ที่คุณใช้ (18, 19, 20, 21, 22 ในตัวอย่างนี้) พร้อมใช้งานสำหรับจุดประสงค์นี้บนบอร์ด/โมดูล ESP32 เฉพาะของคุณ ถ้าไม่คุณสามารถเปลี่ยนเป็นหมุดอื่นที่เหมาะสมได้

 REF .

https://lastminuteengineers.com/handling-esp32-gpio-interrupts-tutorial/

 

powered by social2s