Lab 4.2 : การใช้ I/O Interrupt เพื่อสั่งงาน LED


Lab 4.2 – การใช้ I/O Interrupt เพื่อสั่งงาน LED

โจทย์

ให้นักศึกษาเขียนโปรแกรมที่ทำงานตามนี้

  • (A) ทำให้ LED กระพริบทุกๆ 1 วินาที
  • (B) เมื่อใดที่ผู้ใช้กดปุ่ม Run กลับสถานะของไฟ LED ทันที

4.2.1 ให้ตรวนเงื่อนไข (B) โดยใช้ I/O Interrupt ส่วน (A) อยู่ใน main()

4.2.2 ให้ตรวจเงือ่นไข (A) โดยใช้ Timer Interrupt ส่วน (B) อยู่ใน main()

 

การตรวจจับการกดปุ่มโดยใช้ Interrupt

การเขียนโปรแกรมโดยใช้ interrupt ตรวจจับการกดปุ่ม จะทำให้โปรแกรมนี้เขียนได้ง่ายขึ้นมาก เพราะ code ส่วนที่ตอบสนองการกดปุ่มสามารถนำไปใส่ไว้ใน Interrupt Service Routine (ISR) ได้ ส่วน Code ที่ควบการติดดับของ LED ก็ทิ้งไว้ใน main() ได้

 

การ Setup

เนื่องจาก Run Button ต่อกับกับขา B7 ซึ่ง PIC มี Interrupt ที่ชื่อ INT_RB ไว้คอยตรวจการเปลี่ยนแปลงของขาของ PortB จึงสามารถนำมาใช้งานสำหรับโจทย์นี้ได้ โดยใน main() จะต้องประกาศดังนี้

enable_interrupts(INT_RB7);    // generate interrupt when B7 changes
enable_interrupts(GLOBAL);

และสร้าง function ที่จะทำงานทุกครั้งที่เกิด Interrupt ขึ้นมาโดยมีชื่อ Interrupt ประกาศไว้ด้วย ดังนี้

#INT_RB
void rb_isr(void) {
... 
}

ดังนั้นโครงสร้างของโปรแกรมทั้งหมดจะเป็นดังนี้

#INT_RB
void rb_isr(void) {
... 
}
void main(void) {
 enable_interrupts(INT_RB7);    // generate interrupt when B7 changes
 enable_interrupts(GLOBAL);
...
}

คำแนะนำ

  • rb_isr จะเปลี่ยนเป็นชื่ออื่นใดก็ได้ แต่จะต้องมีประกาศ #INT_RB นำหน้าเสมอ
  • ห้ามแทรกคำสั่งใดๆ ระหว่าง #INT_RB กับชื่อ function เพราะจะทำให้ interrupt หยุดทำงาน
  • เนื่องจาก Interrupt จะเกิดเมื่อสถานะของขาเปลี่ยนแปลง ดังนั้น interrupt นี้จะเกิดทั้งตอนกด และปล่อย ปุ่ม ขอให้เขียนโปรแกรมตรวจสอบสิ่งนี้ไว้ให้ดี เช่น ใน rb_isr ให้เขียนเช็คด้วยว่าตอนนั้นๆ ขา RB0 เป็น high หรือ low