- ทำไมเราต้องขัดจังหวะ?
- ประเภทของการขัดจังหวะใน MSP430
- การควบคุมโปรแกรมขัดจังหวะใน MSP430
- MSP430 Circuit เพื่อทดสอบ GPIO Interrupt
- การเขียนโปรแกรม MSP430 สำหรับการขัดจังหวะ
- การอัปโหลดโปรแกรมไปยัง MSP430 จาก CCS
- โปรแกรมขัดจังหวะบน MSP430
ลองพิจารณานาฬิกาดิจิตอลธรรมดา ๆ ที่ตั้งโปรแกรมไว้เพื่อแสดงเวลาให้คุณเห็นตอนนี้จินตนาการว่าคุณต้องการเปลี่ยนเขตเวลา คุณจะทำอะไร? คุณเพียงแค่กดปุ่มที่เปลี่ยนเป็นเมนูที่ให้คุณเปลี่ยนเขตเวลาได้ ที่นี่ระบบไม่สามารถคาดเดาการขัดจังหวะภายนอกของคุณต่อกระบวนการรักษาเวลาและไม่สามารถขอให้คุณรอได้เนื่องจากกำลังยุ่งอยู่กับการเพิ่มค่าวินาทีในนาฬิกาของคุณ นี่คือจุดที่การขัดจังหวะมีประโยชน์
การขัดจังหวะไม่จำเป็นต้องอยู่ภายนอกเสมอไป มันสามารถอยู่ภายในได้เช่นกัน เวลาส่วนใหญ่ในการขัดจังหวะแบบฝังยังช่วยอำนวยความสะดวกในการสื่อสารระหว่างอุปกรณ์ต่อพ่วงสองชิ้นของ CPU พิจารณาว่าตัวจับเวลาที่ตั้งไว้ล่วงหน้าถูกรีเซ็ตและการขัดจังหวะจะถูกทริกเกอร์เมื่อเวลาถึงค่าในรีจิสเตอร์ตัวจับเวลา ตัวจัดการขัดจังหวะสามารถใช้เพื่อเริ่มต้นอุปกรณ์ต่อพ่วงอื่น ๆ เช่น DMA
ในบทช่วยสอนนี้เราได้ใช้การขัดจังหวะภายนอกบน MSP430เพื่อสลับไฟ LED ต่างๆ เมื่ออินเทอร์รัปต์ภายนอกได้รับจากการเปลี่ยนสถานะโดยใช้ปุ่มกดการควบคุมจะถูกโอน (จองล่วงหน้า) ไปยัง ISR และทำตามความจำเป็น หากต้องการทราบข้อมูลพื้นฐานเช่นการตั้งค่าสภาพแวดล้อม CCS สำหรับ MSP430G2 launchpad ให้ไปที่ลิงก์นี้เพื่อเริ่มต้นกับ MSP430 โดยใช้ CCS เนื่องจากเราจะไม่ลงรายละเอียดในบทช่วยสอนนี้ ตรวจสอบบทช่วยสอนอื่น ๆ ที่ใช้ MSP430 โดยใช้ Energia IDE และ CCS ตามลิงค์
ทำไมเราต้องขัดจังหวะ?
จำเป็นต้องมีการขัดจังหวะเพื่อบันทึกค่าโสหุ้ยการสำรวจในระบบฝังตัว พวกเขาจะถูกเรียกเมื่องานที่มีลำดับความสำคัญสูงกว่าจำเป็นต้องดำเนินการโดยการล้างข้อมูลก่อนงานที่กำลังรันอยู่ นอกจากนี้ยังสามารถใช้เพื่อปลุก CPU จากโหมดพลังงานต่ำได้อีกด้วย เมื่อถูกปลุกโดยการเปลี่ยนขอบของสัญญาณภายนอกผ่านพอร์ต GPIO ISR จะดำเนินการและ CPU จะกลับสู่โหมดพลังงานต่ำอีกครั้ง
ประเภทของการขัดจังหวะใน MSP430
การขัดจังหวะใน MSP430อยู่ภายใต้ประเภทต่อไปนี้ -
- รีเซ็ตระบบ
- Non-Maskable Interrupt
- Maskable Interrupt
- Vectored และ Non-Vectored Interrupt
รีเซ็ตระบบ:
มันสามารถเกิดขึ้นเนื่องจากอุปทานแรงดันไฟฟ้า (Vcc) และเนื่องจากสัญญาณในระดับต่ำในขา RST / NMI ด้วยโหมดรีเซ็ตเลือกและยังสามารถเกิดขึ้นได้เนื่องจากเหตุผลเช่นล้นเวลาจ้องจับผิดและการละเมิดการรักษาความปลอดภัยที่สำคัญ
การขัดจังหวะแบบไม่ปิดบัง:
การขัดจังหวะเหล่านี้ไม่สามารถปิดบังโดยคำแนะนำของ CPU เมื่อเปิดใช้งานการขัดจังหวะทั่วไปแล้วการขัดจังหวะที่ไม่สามารถปิดบังได้จะไม่สามารถเปลี่ยนจากการประมวลผลได้ สิ่งนี้สร้างขึ้นโดยแหล่งที่มาเช่นข้อบกพร่องของ Oscillator และขอบที่กำหนดให้กับ RST / NMI ด้วยตนเอง (ในโหมด NMI)
การขัดจังหวะหน้ากาก:
เมื่อการขัดจังหวะเกิดขึ้นและหากคำสั่ง CPU สามารถมาสก์ได้แสดงว่าการขัดจังหวะแบบ Maskable พวกเขาไม่จำเป็นต้องภายนอกเสมอไป พวกเขายังขึ้นอยู่กับอุปกรณ์ต่อพ่วงและหน้าที่ของมันด้วย การขัดจังหวะพอร์ตภายนอกที่ใช้ที่นี่อยู่ภายใต้หมวดหมู่นี้
Vectored Interrupts และ Non-Vectored Interrupts:
Vectored:ในกรณีนี้อุปกรณ์ที่ขัดจังหวะจะให้แหล่งที่มาของการขัดจังหวะโดยส่งที่อยู่เวกเตอร์ขัดจังหวะ ที่อยู่ของ ISR ได้รับการแก้ไขที่นี่และการควบคุมจะถูกโอนไปยังที่อยู่นั้นและ ISR จะดูแลส่วนที่เหลือ
Non-Vectored: ที่ นี่การขัดจังหวะทั้งหมดมี ISR ทั่วไป เมื่อการขัดจังหวะเกิดขึ้นจากแหล่งที่มาที่ไม่ได้รับการตรวจสอบการควบคุมจะถูกโอนไปยังที่อยู่ทั่วไปซึ่งการขัดจังหวะที่ไม่ใช่ vectored ทั้งหมดจะแบ่ง
การควบคุมโปรแกรมขัดจังหวะใน MSP430
เมื่อเกิดการขัดจังหวะ MCLK จะเปิดและ CPU จะถูกเรียกกลับจากสถานะ OFF เนื่องจากการควบคุมของโปรแกรมถูกโอนไปยังที่อยู่ ISR หลังจากเกิดการขัดจังหวะค่าในตัวนับโปรแกรมและการลงทะเบียนสถานะจะถูกย้ายไปที่สแต็ก
ติดต่อกันสถานะสมาชิกจะถูกล้างออกจึงล้าง GIE และยกเลิกโหมดพลังงานต่ำอินเตอร์รัปต์ที่มีลำดับความสำคัญสูงสุดจะถูกเลือกและดำเนินการโดยการวางที่อยู่เวกเตอร์ขัดจังหวะในตัวนับโปรแกรม ก่อนที่เราจะไปที่MSP430 GPIO Interrupt Example Code ของเราสิ่งสำคัญคือต้องเข้าใจการทำงานของ Port register ที่เกี่ยวข้อง
พอร์ตรีจิสเตอร์สำหรับ GPIO Control บน MSP430:
pxDIR:เป็นรีจิสเตอร์ควบคุมทิศทางพอร์ต ช่วยให้โปรแกรมเมอร์สามารถเลือกฟังก์ชันของมันได้โดยการเขียน 0 หรือ 1 หากพินถูกเลือกเป็น 1 ก็จะทำหน้าที่เป็นเอาต์พุต พิจารณาว่าพอร์ต 1 เป็นพอร์ต 8 บิตและหากต้องกำหนดพิน 2 และ 3 เป็นพอร์ตเอาต์พุตดังนั้นจึงต้องตั้งค่ารีจิสเตอร์ P1DIR ด้วยค่า 0x0C
pxIN:เป็นรีจิสเตอร์แบบอ่านอย่างเดียวและสามารถอ่านค่าปัจจุบันในพอร์ตได้โดยใช้รีจิสเตอร์นี้
pxOUT:รีจิสเตอร์เฉพาะนี้สามารถใช้เพื่อเขียนค่าไปยังพอร์ตได้โดยตรง สามารถทำได้เฉพาะเมื่อปิดใช้งานการลงทะเบียนแบบดึงขึ้น / แบบเลื่อนลง
pxREN:เป็นรีจิสเตอร์ 8 บิตที่ใช้เพื่อเปิดหรือปิดการลงทะเบียนแบบพูลอัพ / แบบเลื่อนลง เมื่อตั้งค่าพินเป็น 1 ทั้งในรีจิสเตอร์ pxREN และ pxOUT พินนั้นจะถูกดึงขึ้น
pxDIR |
pxREN |
pxOUT |
การกำหนดค่า I / O |
0 |
0 |
X |
อินพุตที่ปิดใช้งานตัวต้านทาน |
0 |
1 |
0 |
อินพุตที่เปิดใช้งานแบบเลื่อนลงภายใน |
0 |
1 |
1 |
อินพุตที่เปิดใช้งาน Pullup ภายใน |
1 |
X |
X |
เอาท์พุท - pxREN ไม่มีผล |
pxSEL และ pxSEL2:เนื่องจากพินทั้งหมดใน MSP430 เป็นมัลติเพล็กซ์จึงต้องเลือกฟังก์ชันเฉพาะก่อนใช้งาน เมื่อทั้งการลงทะเบียน pxSEL และ pxSEL2 ถูกตั้งค่าเป็น 0 สำหรับพินใดพินหนึ่งระบบจะเลือก I / O สำหรับวัตถุประสงค์ทั่วไป เมื่อตั้งค่า pxSEL เป็น 1 ฟังก์ชันอุปกรณ์ต่อพ่วงหลักจะถูกเลือกและอื่น ๆ
pxIE:เปิดหรือปิดการขัดจังหวะสำหรับพินเฉพาะในพอร์ต x
pxIES:เลือกขอบที่สร้างอินเทอร์รัปต์ สำหรับ 0 จะมีการเลือกขอบที่เพิ่มขึ้นและสำหรับ 1 จะเลือกขอบลดลง
MSP430 Circuit เพื่อทดสอบ GPIO Interrupt
วงจร MSP430 ที่ใช้ทดสอบMSP430 Interrupt Example code ของเราแสดงอยู่ด้านล่าง
กราวด์ของบอร์ดใช้กราวด์ทั้ง LED และปุ่ม ด้านตรงข้ามในแนวทแยงมุมของปุ่มกดโดยปกติจะเป็นขั้วเปิดและเชื่อมต่อได้เมื่อกดปุ่มกดลง ตัวต้านทานเชื่อมต่อก่อน LED เพื่อหลีกเลี่ยงการใช้กระแสไฟสูงโดย LED โดยปกติจะใช้ตัวต้านทานต่ำในช่วง 100 โอห์ม - 220 โอห์ม
เราใช้ 3 รหัสที่แตกต่างกันเพื่อทำความเข้าใจเกี่ยวกับพอร์ตอินเตอร์รัปต์ สองรหัสแรกใช้วงจรเดียวกันกับใน Circuit Diagram 1 ให้เราดำดิ่งลงไปในโค้ด หลังจากทำการเชื่อมต่อแล้วการตั้งค่าของฉันจะมีลักษณะเช่นนี้
การเขียนโปรแกรม MSP430 สำหรับการขัดจังหวะ
MSP430 Interrupt Program ที่สมบูรณ์สามารถพบได้ที่ด้านล่างของหน้านี้คำอธิบายของรหัสมีดังนี้
บรรทัดด้านล่างจะหยุดตัวจับเวลาของสุนัขเฝ้าบ้านจากการทำงาน ตัวจับเวลา Watchdog มักจะดำเนินการสองอย่าง หนึ่งคือการป้องกันไม่ให้ตัวควบคุมจากลูปที่ไม่มีที่สิ้นสุดโดยการรีเซ็ตตัวควบคุมและอีกตัวหนึ่งคือมันทริกเกอร์เหตุการณ์เป็นระยะโดยใช้ตัวจับเวลาในตัว เมื่อไมโครคอนโทรลเลอร์ถูกรีเซ็ต (หรือเปิดเครื่อง) ไมโครคอนโทรลเลอร์จะอยู่ในโหมดจับเวลาและมีแนวโน้มที่จะรีเซ็ต MCU หลังจาก 32 มิลลิวินาที บรรทัดนี้จะหยุดตัวควบคุมไม่ให้ทำเช่นนั้น
WDTCTL = WDTPW + WDTHOLD;
การตั้งค่ารีจิสเตอร์P1DIRเป็นค่า 0x07 กำหนดทิศทางของ pin0, pin1 และ pin2 เป็นเอาต์พุต การตั้งค่าP1OUTเป็น 0x30 จะกำหนดค่าอินพุตด้วยตัวต้านทานแบบพูลอัพภายในที่เปิดใช้งานบนพิน 4 และพิน 5 การตั้งค่าP1RENเป็น 0x30 จะเปิดใช้งานการดึงภายในของพินเหล่านี้ P1IEเปิดใช้งานการขัดจังหวะโดยที่ P1IES จะเลือกการเปลี่ยนจากสูงไปต่ำเป็นขอบขัดจังหวะบนพินเหล่านี้
P1DIR - = 0x07; P1OUT = 0x30; P1REN - = 0x30; P1IE - = 0x30; P1IES - = 0x30; P1IFG & = ~ 0x30;
บรรทัดถัดไปเปิดใช้งานโหมดพลังงานต่ำและเปิดใช้งานGIEในการลงทะเบียนสถานะเพื่อให้สามารถรับอินเทอร์รัปต์ได้
__bis_SR_register (LPM4bits + GIE)
ตัวนับโปรแกรมถูกตั้งค่าด้วยแอดเดรสของเวกเตอร์พอร์ต 1 โดยใช้มาโคร
PORT1_VECTOR #pragma vector = PORT1_VECTOR __interrupt เป็นโมฆะ Port_1 (โมฆะ)
รหัสด้านล่างจะสลับไฟ LED แต่ละดวงที่เชื่อมต่อกับ pin0, pin1, pin2 ทีละรายการ
ถ้า (นับ% 3 == 0) { P1OUT ^ = BIT1; P1IFG & = ~ 0x30; นับ ++; } else if (นับ% 3 == 1) { P1OUT ^ = BIT1; P1IFG & = ~ 0x30; นับ ++; } else { P1OUT ^ = BIT2; P1IFG & = ~ 0x30; นับ ++; }
แผนภาพวงจร 2:
ในทำนองเดียวกันลองใช้พินอื่นเพื่อให้เข้าใจแนวคิดได้ดีขึ้นมาก ดังนั้นที่นี่ปุ่มกดจึงเชื่อมต่อกับพิน 2.0 แทนที่จะเป็นพิน 1.5 วงจรที่แก้ไขมีดังนี้ อีกครั้งวงจรนี้ใช้เพื่อทดสอบโปรแกรมขัดจังหวะปุ่ม MSP430
ที่นี่พอร์ต 2 ใช้สำหรับอินพุต จึงต้องใช้เวกเตอร์ขัดจังหวะที่แตกต่างกัน P1.4และP2.0รับอินพุต
เนื่องจากพอร์ต 2 ใช้สำหรับอินพุตเท่านั้น P2DIR จึงถูกตั้งค่าเป็น 0 ในการตั้งค่าพิน 0 ของพอร์ต 2 เป็นอินพุตที่เปิดใช้งานตัวต้านทานแบบดึงขึ้นภายในต้องตั้งค่าการลงทะเบียน P2OUT และ P2REN ด้วยค่า 1 เพื่อเปิดใช้งาน ขัดจังหวะบน pin0 ของพอร์ต 2 และเพื่อเลือกขอบของการขัดจังหวะ P2IE และ P2IES ถูกตั้งค่าด้วยค่า 1 ในการรีเซ็ตแฟล็กในพอร์ต 2 P2IFG จะถูกล้างเพื่อให้สามารถตั้งค่าแฟล็กได้อีกครั้งบน การเกิดการขัดจังหวะ
P2DIR - = 0x00; P2OUT = 0x01; P2REN - = 0x01; P2IE - = 0x01; P2IES - = 0x01; P2IFG & = ~ 0x01;
เมื่อแหล่งสัญญาณขัดจังหวะมาจากพอร์ต 1 ไฟ LED ที่เชื่อมต่อกับขา 1 ของพอร์ต 1 จะติดสว่าง เมื่อแหล่งสัญญาณขัดจังหวะเป็นของพอร์ต 2 ไฟ LED ที่เชื่อมต่อกับขา 2 ของพอร์ต 1 จะติดสว่าง
#pragma vector = PORT1_VECTOR __interrupt โมฆะ Port_1 (โมฆะ) { P1OUT ^ = BIT1; P1IFG & = ~ 0x10; สำหรับ (i = 0; i <20000; i ++) { } P1OUT ^ = BIT1; } #pragma vector = PORT2_VECTOR __interrupt โมฆะ Port_2 (โมฆะ) { P1OUT ^ = BIT2; P2IFG & = ~ 0x01; สำหรับ (j = 0; j <20000; j ++) { } P1OUT ^ = BIT2; }
การอัปโหลดโปรแกรมไปยัง MSP430 จาก CCS
ในการโหลดโปรเจ็กต์ไปยัง Launchpad และดีบักให้เลือกโปรเจ็กต์แล้วคลิกไอคอนดีบักในแถบเครื่องมือ หรือกด F11 หรือคลิกRunàDebugเพื่อเข้าสู่โหมดดีบัก
เมื่อเข้าสู่โหมดดีบักแล้วให้กดปุ่มวิ่งสีเขียวเพื่อเรียกใช้โค้ดที่โหลดใน MCU ได้อย่างอิสระ ตอนนี้เมื่อกดปุ่มกดลงการขัดจังหวะจะถูกกระตุ้นโดยการเปลี่ยนแปลงของขอบดังนั้นจึงแจ้งให้เปลี่ยนสถานะของ LED
โปรแกรมขัดจังหวะบน MSP430
หลังจากอัปโหลดโค้ดสำเร็จแล้วเราสามารถทดสอบได้โดยใช้ปุ่มกด รูปแบบ LED จะเปลี่ยนไปตามโปรแกรมของเราเมื่อใดก็ตามที่มีการขัดจังหวะโดยใช้ปุ่มกด
การทำงานทั้งหมดสามารถพบได้ในวิดีโอที่เชื่อมโยงด้านล่าง หวังว่าคุณจะสนุกกับบทช่วยสอนและเรียนรู้สิ่งที่เป็นประโยชน์ หากคุณมีคำถามใด ๆ โปรดทิ้งไว้ในส่วนความคิดเห็นหรือใช้ฟอรัมของเราสำหรับคำถามทางเทคนิคอื่น ๆ