บทที่ 5 Interrupt เทอดศักดิ์ ลิ่วหาทอง สาขาวิชาอิเล็กทรอนิกส์ สถาบันเทคโนโลยีพระจอมเกล้าเจ้าคุณทหารลาดกระบัง
Interrupt ปัญหาของการเขียนโปรแกรมติดต่อกับอุปกรณ์ต่อพ่วงจำนวนมากคือ ไม่ทราบเวลาที่แน่นอนที่อุปกรณ์ต่อพ่วงเหล่านั้นต้องการติดต่อกับ PIC ทำให้ PIC ต้องทำการวนตรวจสอบตลอดเวลาว่าเมื่อไหร่อุปกรณ์ต่อพ่วงต้องการที่จะติดต่อด้วย เทคนิคที่ใช้ในการตรวจสอบมีอยู่ 2 เทคนิคคือ Polling Interrupt
Polling Polling เป็นการเขียนโปรแกรมเพื่อตรวจสอบโลจิกที่ได้รับจากอุปกรณ์ต่อพ่วงตลอดเวลาว่าเมื่อไหร่ที่อุปกรณ์ต่อพ่วงต้องการที่จะติดต่อด้วย ตัวอย่างเช่นการตรวจสอบการกดสวิทช์ โปรแกรมจะ ต้องตรวจสอบตลอดเวลาว่าเมื่อไหร่ที่ผู้ใช้กดสวิทช์ ข้อดีของ Polling คือเขียนโปรแกรมง่าย และ ตรวจสอบการทำงานของโปรแกรมได้ง่าย ข้อเสียคือ PIC จะต้องเสียเวลาในการตรวจสอบการ กดสวทช์ตลอดเวลาทำให้ไม่สามารถทำงานอย่างอื่นได้ while(1) { if(PORTBbits.RB0==0) i++; if(i==8) i=7; PORTD = LED[i]; Delay10KTCYx(100); } if(PORTAbits.RA5==0) i--; if(i<0) i=0;
Interrupt Interrupt เป็นวงจรดิจิตอลที่อยู่ใน PIC ทำการตรวจสอบโลจิกที่ได้รับจากอุปกรณ์ต่อพ่วง เมื่อวงจรตรวจพบว่าอุปกรณ์ต่อพ่วงต้องการติดต่อด้วยก็จะไปเรียกโปรแกรมที่เหมาะสมต่อไป (Interrupt Service Routine ISR) Interrupt Service Routine i++; if(i==8) i=7; PORTD = LED[i]; Delay10KTCYx(100);
Interrupt Source สัญญาณ Interrupt ของ PIC18F8722 มีดังนี้ TMR0, TMR1, TMR2, TMR3, TMR4 เป็นสัญญาณ Interrupt ที่เกิดจากวงจร Timer ที่อยู่ภายใน PIC RB เป็นสัญญาณ Interrupt ที่เกิดจากการตรวจสอบว่ามีบิทใดบิทหนึ่งของ RB<0:7> มีการเปลี่ยนสถานะ INT0, INT1, INT2, INT3 เป็นสัญญาณ Interrupt ที่เกิดจากอุปกรณ์ต่อพ่วงภายนอกส่งสัญญาณมาบอก PIC ว่าต้องการติดต่อด้วย
Interrupt Priority เนื่องจาก PIC สามารถรับสัญญาณ Interrupt ได้หลายสัญญาณ ดังนั้นจึงมีโอกาสที่จะมีสัญญาณ Interrupt หลายสัญญาณส่งไปให้ PIC พร้อมๆกัน หรือในเวลาที่ใกล้เคียงกัน ตัวอย่างเช่นผู้ใช้กดสวิทช์เพื่อส่งสัญญาณ INT0 ไปบอก PIC ว่าต้องการติดต่อด้วย พร้อมกับ TMR0 ส่งสัญญาณ Interrupt ไปบอก PIC ให้อ่านค่าอุณหภูมิจาก Thermal Sensor ดังนั้นจะต้องมีวิธีการเพื่อตัดสินใจว่าจะให้ PIC ทำการติดต่อกับผู้ใช้ก่อน หรือจะให้อ่านค่าจาก Thermal Sensor ก่อน
Interrupt Priority ถ้า PIC ตัดสินใจติดต่อกับผู้ใช้ก่อนที่จะไปอ่านค่าจาก Thermal Sensor แสดงว่า INT0 มี Priority สูงกว่า TMR0 แต่ถ้า PIC อ่านค่าจาก Thermal Sensor ก่อนติดต่อกับผู้ใช้ แสดงว่า TMR0 มี Priority สูงกว่า INT0 ถ้ามีสัญญาณ Interrupt ที่มี Priority สูง (High Priority) PIC จะไปเรียกโปรแกรมที่เก็บไว้ใน Address ที่ 0008H แต่ถ้ามีสัญญาณ Interrupt ที่มี Priority ต่ำ (Low Priority) PIC จะไปเรียกโปรแกรที่เก็บไว้ใน Address ที่ 0018H
Interrupt กำหนดคุณสมบัติของ I/O Port, ADC, Timer และ Interrupt void main (void) { กำหนดคุณสมบัติของ I/O Port, ADC, Timer และ Interrupt กำหนดค่าเริ่มต้นของ I/O Port while (1) คำสั่งที่ 1; คำสั่งที่ 2; : คำสั่งที่ N } 0018H Timer Interrupt (Low Priority Interrupt) อ่านค่าจาก Thermal Sensor { คำสั่งที่ 1; คำสั่งที่ 2; คำสั่งที่ 3; : คำสั่งที่ N } 0008H INT0 Interrupt (High Priority Interrupt) ติดต่อกับผู้ใช้ { คำสั่งที่ 1; คำสั่งที่ 2; : คำสั่งที่ N }
Interrupt Bit สัญญาณ Interrupt แต่ละสัญญาณมี Flag, Enable และ Priority Bit เพื่อใช้ควบคุมการทำงานดังนี้ Flag Bit (TMR0IF, TMR1IF, TMR2IF, TMR3IF, TMR4IF, RBIF, INT0IF, INT1IF, INT2IF, INT3IF) ถ้าเป็น 1 คือตรวจสอบพบสัญญาณ Interrupt ถ้าเป็น 0 คือไม่พบสัญญาณ Interrupt Enable Bit (TMR0IE, TMR1IE, TMR2IE, TMR3IE, TMR4IE, RBIE, INT0IE, INT1IE, INT2IE, INT3IE) ถ้าเป็น 1 คือ Enable ถ้าเป็น 0 คือ Disable
Interrupt Bit Priority Bit (TMR0IP, TMR1IP, TMR2IP, TMR3IP, TMR4IP, RBIP, INT0IP, INT1IP, INT2IP, INT3IP) ถ้าเป็น 1 คือตั้งให้เป็น High Priority ถ้าเป็น 0 ตั้งให้เป็น Low Priority
Interrupt Bit นอกจาก Flag, Enable, และ Priority ที่สัญญาณ Interrupt แต่ละตัวต้องมีแล้ว ยังมีบิทที่ใช้ควบคุมการทำงานทั้งหมดของสัญญาณ Interrupt คือ IPEN (Interrupt Priority Enable) ถ้าเป็น 1 เป็นการ Enable การทำงานแบบ Priority ถ้าเป็น 0 คือไม่มีการทำงานแบบ Priority
IPEN=1 GIEH (Global Interrupt Enable High) ถ้าเป็น 1 จะ Enable สัญญาณ Interrupt ทุกตัวที่มี Priority Bit = 1 ถ้าเป็น 0 จะ Disable สัญญาณ Interrupt ทุกตัวที่มี Priority Bit = 1 GIEL (Global Interrupt Enable Low) ถ้าเป็น 1 จะ Enable สัญญาณ Interrupt ทุกตัวที่มี Priority Bit = 0 ถ้าเป็น 0 จะ Disable สัญญาณ Interrupt ทุกตัวที่มี Priority Bit = 0
IPEN=1 ถ้า Flag Bit ของสัญญาณ Interrupt แบบ High Priority เท่ากับ 1 PIC จะไปเรียกโปรแกรมที่ Address 0008H ถ้า Flag Bit ของสัญญาณ Interrupt แบบ Low Priority เท่ากับ 1 PIC จะไปเรียกโปรแกรมที่ Address 0018H
IPEN=0 PEIE (Peripheral Interrupt Enable) ถ้าเป็น 1 จะ Enable สัญญาณ Interrupt จากอุปกรณ์ต่อพ่วงทุกตัว ถ้าเป็น 0 จะ Disable สัญญาณ Interrupt จากอุปกรณ์ต่อพ่วงทุกตัว GIE (Global Interrupt Enable) ถ้าเป็น 1 จะ Enable สัญญาณ Interrupt ทุกตัว ถ้าเป็น 0 จะ Disable สัญญาณ Interrupt ทุกตัว เมื่อ Flag Bit ของสัญญาณ Interrupt ตัวใดตัวหนึ่งเป็น 1 PIC จะไปเรียกโปรแกรมที่ Address 0008H
Interrupt Respond เมื่อ Flag Bit = 1 และ PIC เรียกใช้โปรแกรม Interrupt Service Routine (ISR) แล้ว จะทำให้ GIEH = 0, GIEL = 0 (ถ้า IPEN = 1) หรือ GIE = 0 (ถ้า IPEN = 0) เพื่อป้องกันไม่ให้ PIC รับสัญญาณ Interrupt อื่นอีก สัญญาณ Interrupt แบบ High Priority สามารถแทรกการทำงานของ Interrupt แบบ Low Priority แต่สัญญาณ Interrupt แบบ Low Priority ไม่สามารถแทรกการทำงานของ Interrupt แบบ High Priority
Interrupt Respond เนื่องจาก PIC มีสัญญาณ Interrupt อยู่หลายสัญญาณ ดังนั้นเมื่อ ISR ถูกเรียกใช้แล้ว โปรแกรมจะต้องทำการตรวจสอบว่า เป็นสัญญาณ Interrupt ชนิดใด โดยการตรวจสอบว่า Flag Bit ของ Interrupt ตัวใดเป็น 1 เพื่อป้องกันไม่ให้ PIC รับสัญญาณ Interrupt อื่นอีก เมื่อออกจาก ISR แล้ว GIE = 1 (หรือ GIEH=1, GIEL=1) โดยอัตโนมัติเพื่อให้ PIC สามารถรับสัญญาณ Interrupt ตัวใหม่ได้