คำถามเริ่มต้น
ฉันมีคำถามทั่วไปเกี่ยวกับการจัดการอินเทอร์รัปต์ในไมโครคอนโทรลเลอร์ ฉันใช้ MSP430 แต่ฉันคิดว่าคำถามอาจขยายไปยังยูซีเอสอื่น ๆ ฉันต้องการทราบว่าเป็นวิธีปฏิบัติที่ดีในการเปิด / ปิดการใช้งานอินเตอร์รัปต์ตามรหัสหรือไม่ ฉันหมายถึงถ้าฉันมีบางส่วนของรหัสที่ไม่ไวต่อการขัดจังหวะ (หรือแย่กว่านั้นคือต้องไม่ฟังการขัดจังหวะไม่ว่าด้วยเหตุผลใดก็ตาม) ดีกว่าไหมที่จะ:
- ปิดการใช้งานอินเทอร์รัปต์ก่อนและเปิดใช้งานอีกครั้งหลังจากส่วนที่สำคัญ
- วางธงไว้ใน ISR ที่เกี่ยวข้องและ (แทนที่จะปิดการใช้งานอินเตอร์รัปต์) ตั้งค่าสถานะเป็นเท็จก่อนส่วนสำคัญและรีเซ็ตเป็นจริงทันทีหลังจากนั้น เพื่อป้องกันรหัสของ ISR จากการถูกดำเนินการ
- ไม่ใช่ทั้งสองข้อเสนอแนะจึงยินดีต้อนรับ!
อัปเดต: อินเตอร์รัปต์และแผนภูมิสถานะ
ฉันจะให้สถานการณ์ที่เฉพาะเจาะจง ให้เราสมมติว่าเราต้องการใช้แผนภูมิสถานะซึ่งประกอบด้วย 4 บล็อก:
- การเปลี่ยน / ผล
- เงื่อนไขการออก
- กิจกรรมเข้า
- ทำกิจกรรม
นี่คือสิ่งที่อาจารย์สอนเราที่มหาวิทยาลัย อาจไม่ใช่วิธีที่ดีที่สุดในการทำคือทำตามรูปแบบนี้:
while(true) {
/* Transitions/Effects */
//----------------------------------------------------------------------
next_state = current_state;
switch (current_state)
{
case STATE_A:
if(EVENT1) {next_state = STATE_C}
if(d == THRESHOLD) {next_state = STATE_D; a++}
break;
case STATE_B:
// transitions and effects
break;
(...)
}
/* Exit activity -> only performed if I leave the state for a new one */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(current_state)
{
case STATE_A:
// Exit activity of STATE_A
break;
case STATE_B:
// Exit activity of STATE_B
break;
(...)
}
}
/* Entry activity -> only performed the 1st time I enter a state */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(next_state)
{
case STATE_A:
// Entry activity of STATE_A
break;
case STATE_B:
// Entry activity of STATE_B
break;
(...)
}
}
current_state = next_state;
/* Do activity */
//----------------------------------------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
}
ขอให้เราสมมติว่าจากSTATE_A
ฉันต้องการที่จะอ่อนไหวต่อการขัดจังหวะที่มาจากชุดของปุ่ม (พร้อมระบบ debouce ฯลฯ ฯลฯ ) buttonPressed
เมื่อกดคนหนึ่งของปุ่มเหล่านี้ขัดจังหวะถูกสร้างขึ้นและธงที่เกี่ยวข้องกับพอร์ตอินพุตจะถูกคัดลอกลงในตัวแปร หาก debounce ถูกตั้งค่าเป็น 200 ms ในบางกรณี (ตัวจับเวลาจ้องจับผิดตัวจับเวลาตัวนับเคาน์เตอร์ ... ) เรามั่นใจว่าbuttonPressed
ไม่สามารถอัปเดตด้วยค่าใหม่ก่อน 200 ms นี่คือสิ่งที่ฉันขอให้คุณ (และตัวฉันเอง :) แน่นอน
ฉันต้องเปิดใช้งานการขัดจังหวะในกิจกรรม DO STATE_A
และปิดการใช้งานก่อนออกหรือไม่
/* Do activity */
//-------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
Enable_ButtonsInterrupt(); // and clear flags before it
// Do fancy stuff and ...
// ... wait until a button is pressed (e.g. LPM3 of the MSP430)
// Here I have my buttonPressed flag ready!
Disable_ButtonsInterrupt();
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
ในทางที่ผมแน่ใจว่าในครั้งต่อไปผม execxute บล็อก 1 (เปลี่ยนแปลง / ผลกระทบ) ที่ย้ำต่อไปผมแน่ใจว่าเงื่อนไขการตรวจสอบพร้อมเปลี่ยนไม่ได้มาจากการขัดจังหวะภายหลังที่มีการเขียนทับค่าก่อนหน้าของbuttonPressed
ผมว่า ต้องการ (แม้ว่ามันจะเป็นไปไม่ได้ที่สิ่งนี้เกิดขึ้นเพราะ 250 ms ต้องผ่านไป)