สารบัญ:

ส่วนที่ 2 - การประกอบ GPIO ARM - RGB - การเรียกฟังก์ชัน - สวิตช์: 6 ขั้นตอน
ส่วนที่ 2 - การประกอบ GPIO ARM - RGB - การเรียกฟังก์ชัน - สวิตช์: 6 ขั้นตอน

วีดีโอ: ส่วนที่ 2 - การประกอบ GPIO ARM - RGB - การเรียกฟังก์ชัน - สวิตช์: 6 ขั้นตอน

วีดีโอ: ส่วนที่ 2 - การประกอบ GPIO ARM - RGB - การเรียกฟังก์ชัน - สวิตช์: 6 ขั้นตอน
วีดีโอ: 7. How to Output to a Pin to Blink an LED for Arm Microcontrollers - GPIO Tutorial Part 2 2024, พฤศจิกายน
Anonim
ส่วนที่ 2 - การประกอบ GPIO ARM - RGB - การโทรฟังก์ชัน - สวิตช์
ส่วนที่ 2 - การประกอบ GPIO ARM - RGB - การโทรฟังก์ชัน - สวิตช์

ในตอนที่ 1 เราได้เรียนรู้วิธีสลับไฟ LED สีแดงดวงเดียวบนบอร์ดพัฒนา MSP432 LaunchPad จาก Texas Instruments โดยใช้แอสเซมบลีแทน C / C++

ในคำแนะนำนี้ เราจะทำสิ่งที่คล้ายกัน - ควบคุม RGB LED ที่อยู่บนบอร์ดเดียวกันนั้นด้วย

ระหว่างทาง เราหวังว่าจะเพิ่มพูนความรู้ของเราเกี่ยวกับการประกอบ ARM ไม่ใช่แค่สนุกกับการให้แสง LED บางตัวเท่านั้น

ขั้นตอนที่ 1: มากระโดดกันเลย

จริงๆแล้ววิดีโอแรกบอกทุกอย่าง ไม่มากที่จะเพิ่ม

ประเด็นหลักของมันคือการขับเคลื่อนความคิดที่ว่าพอร์ต I/O แต่ละพอร์ตบน MSP432 ประกอบด้วยบล็อกของที่อยู่ "ลงทะเบียน" ซึ่งแต่ละพอร์ตจะประกอบด้วยหลายบิต

นอกจากนี้ บิตยังจัดกลุ่มในลักษณะมุมฉาก นั่นคือ บิต 0 ของที่อยู่รีจิสเตอร์แต่ละตัวอ้างอิงถึงพิน I/O ภายนอกเดียวกัน

เราย้ำแนวคิดที่ว่าต้องใช้ที่อยู่ลงทะเบียนหลายแห่งสำหรับพอร์ตนั้น เพื่อทำบางสิ่งด้วยบิตหรือพินเพียงอันเดียว

แต่ในกรณีนี้ เนื่องจากเรากำลังจัดการกับ RGB LED เราจึงต้องจัดการกับสามบิตสำหรับที่อยู่การลงทะเบียนแต่ละรายการ

เราเสริมว่าเราต้องการรีจิสเตอร์หลายตัว: รีจิสเตอร์ DIR, รีจิสเตอร์ SEL0, รีจิสเตอร์ SEL1 และรีจิสเตอร์ OUTPUT และครั้งละสามบิต

ขั้นตอนที่ 2: ปรับปรุงโค้ด - เพิ่มฟังก์ชัน

Image
Image

ดังที่คุณเห็นในขั้นตอนข้างต้น โปรแกรมหลักวนซ้ำหลายรหัส กล่าวคือ เมื่อเราปิดไฟ LED

ดังนั้นเราจึงสามารถเพิ่มฟังก์ชันให้กับโปรแกรมได้ เรายังต้องเรียกใช้ฟังก์ชันนั้นทุกครั้งที่ต้องการปิดไฟ LED แต่มันทำให้โค้ดบางตัวยุบเป็นคำสั่งเดียว

หากโค้ด LED-off ของเราเกี่ยวข้องกับคำสั่งอื่นๆ มากขึ้น นี่จะเป็นการช่วยประหยัดหน่วยความจำอย่างแท้จริง

ส่วนหนึ่งของโปรแกรมฝังตัวและไมโครคอนโทรลเลอร์กำลังตระหนักถึงขนาดของโปรแกรมมากขึ้น

วิดีโออธิบาย

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

ขั้นตอนที่ 3: เพิ่ม Busy-Loop Delay

ในส่วน Declarations ของโค้ด ให้เพิ่มค่าคงที่เพื่อให้ง่ายต่อการ tweek สำหรับช่วงเวลาที่ต้องการ:

; คำใดๆ หลังเครื่องหมายอัฒภาค (';') เริ่มแสดงความคิดเห็น

; รหัสในส่วนนี้กำหนดชื่อให้กับค่า; คุณสามารถใช้ '.equ' ได้เช่นกัน แต่มันต่างกันเล็กน้อย; '.equ' (ฉันคิดว่า) ไม่สามารถเปลี่ยนแปลงได้ ในขณะที่ '.set' หมายความว่าคุณทำได้; เปลี่ยนค่าของ 'DLYCNT' ในภายหลังในรหัสหากคุณต้องการ;'DLYCNT' จะถูกใช้เป็นค่านับถอยหลังในรูทีนย่อยการหน่วงเวลา DLYCNT.set 0x30000

เพิ่มฟังก์ชันหน่วงเวลาใหม่:

ล่าช้า:.asmfunc; การเริ่มต้นของรูทีนย่อยหรือฟังก์ชัน 'การหน่วงเวลา'

MOV R5, #DLYCNT; โหลดคอร์ซีพียูรีจิสเตอร์ R5 ด้วยค่าที่กำหนดให้กับ 'DLYCNT' ดลลี่ลูป; เครื่องหมายนี้เป็นจุดเริ่มต้นของลูปการหน่วงเวลา แอสเซมเบลอร์กำหนดที่อยู่ SUB R5, #0x1; ลบ 1 จากค่าปัจจุบันใน core cpu register R5 ซีเอ็มพี R5, #0x0; เปรียบเทียบค่าปัจจุบันใน R5 ถึง 0 BGT dlyloop; สาขาหากค่าใน R5 มากกว่า 0 เพื่อติดป้ายกำกับ (ที่อยู่) 'dlyloop' บีเอ็กซ์ แอลอาร์; ถ้าเรามาถึงตรงนี้ แสดงว่าค่า R5 เป็น 0 คืนค่าจากรูทีนย่อย.endasmfunc; ทำเครื่องหมายจุดสิ้นสุดของรูทีนย่อย

จากนั้นในเนื้อหาหลัก ภายในลูปหลัก เรียกใช้หรือเรียกฟังก์ชันการหน่วงเวลานั้น:

; นี่คือส่วนของโค้ด ของเนื้อหาหลักหรือฟังก์ชันหลัก (ดูไฟล์ 'main.asm')

; นี่คือการวนซ้ำใน 'main' และแสดงให้เห็นว่าเราเรียกหรือใช้ฟังก์ชัน 'delay' ใหม่นั้นอย่างไร; '#REDON' และ '#GRNON' ยังเป็นการประกาศ (ค่าคงที่) (ดูด้านบนสุดของ 'main.asm'); เป็นเพียงวิธีง่ายๆ ในการตั้งค่าสีที่ระบุของ RGB LED ลูป MOV R0, #REDON;Red - ตั้งค่า core cpu register R0 ด้วยค่าที่กำหนดให้กับ 'REDON' STRB R0, [R4];core register R4 ก่อนหน้านี้ถูกตั้งค่าด้วยที่อยู่เอาต์พุต GPIO;เขียนสิ่งที่อยู่ใน R0 ลงในที่อยู่ที่ระบุโดย R4 BL ดีเลย์;สาขาไปยังฟังก์ชัน 'delay' ใหม่ BL ledsoff;สาขาไปยังฟังก์ชัน 'ledsoff' ที่มีอยู่แล้ว BL ดีเลย์;ditto MOV R0, #GRNON;Green - ditto STRB R0, [R4]; และอื่นๆ BL ล่าช้า BL ledsoff BL ล่าช้า

วิดีโอมีรายละเอียด

ขั้นตอนที่ 4: มาตรฐานการเรียกขั้นตอนสถาปัตยกรรม ARM (AAPCS)

น่าจะเป็นช่วงเวลาที่ดีที่จะแนะนำบางสิ่งบางอย่าง มันเป็นแบบแผนของภาษาแอสเซมบลี เรียกอีกอย่างว่าโพรซีเดอร์การเรียกมาตรฐานสำหรับสถาปัตยกรรม ARM

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

มิฉะนั้น เราอาจรู้สึกเหมือนกำลังดื่มน้ำจากท่อส่งน้ำขนาดใหญ่ ข้อมูลมากเกินไป

ทะเบียนหลัก

เนื่องจากเราคุ้นเคยกับการลงทะเบียนหลักของ MSP432 แล้ว เรามาลองใช้มาตรฐานเหล่านี้กัน เราจะปฏิบัติตามนี้เมื่อเราเขียนฟังก์ชันถัดไป (เปิด/ปิด LED)

1) เราควรจะใช้ R0 เป็นพารามิเตอร์ของฟังก์ชัน หากเราต้องการส่งค่าไปยังฟังก์ชัน (รูทีนย่อย) เราควรใช้ R0 เพื่อทำเช่นนั้น

2) เราจะใช้ Link Register เพื่อจุดประสงค์ - มีที่อยู่ที่ระบุตำแหน่งที่จะกลับไปหลังจากรูทีนย่อยเสร็จสมบูรณ์

คุณจะเห็นวิธีที่เราใช้สิ่งเหล่านี้

ขั้นตอนที่ 5: ฟังก์ชันพร้อมพารามิเตอร์ - ฟังก์ชันที่ซ้อนกัน

เราสามารถล้างโค้ดของเราและลดจำนวนหน่วยความจำที่ใช้โดยการรวมส่วนที่ซ้ำกันเป็นฟังก์ชันเดียว ความแตกต่างเพียงอย่างเดียวในตัวของลูปหลักคือ เราจำเป็นต้องมีพารามิเตอร์ เพื่อให้เราสามารถส่งผ่านสีต่างๆ ที่เราอยากเห็นของ RGB LED ได้

ดูวิดีโอสำหรับรายละเอียด (ขออภัยในความยาว)

ขั้นตอนที่ 6: อินพุต GPIO - เพิ่มสวิตช์

มาทำให้มันน่าสนใจยิ่งขึ้น ได้เวลาเพิ่มการควบคุมสวิตช์ลงในโปรแกรมประกอบของเราแล้ว

คำแนะนำนี้มีภาพที่แสดงให้เห็นว่าสวิตช์ออนบอร์ดสองตัวเชื่อมต่อกับ MSP432 อย่างไร

โดยพื้นฐานแล้ว: สวิตช์ 1 (SW1 หรือ S1) เชื่อมต่อกับ P1.1 และสวิตช์ 2 (SW2 หรือ S2) เชื่อมต่อกับ P1.4

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

เราจัดการกับการสลับ LED สีแดงเดียวในคำแนะนำนี้ ดังนั้นเราจึงต้องเพิ่มโค้ดเพื่อจัดการกับสวิตช์

พอร์ต 1 ลงทะเบียนบล็อกที่อยู่

โปรดจำไว้ว่าเราได้กล่าวถึงสิ่งเหล่านี้ในคำแนะนำก่อนหน้านี้ แต่เราต้องรวมใหม่:

  • พอร์ต 1 อินพุตการลงทะเบียนที่อยู่ = 0x40004C00
  • พอร์ต 1 เอาท์พุทการลงทะเบียนที่อยู่ = 0x40004C02
  • ที่อยู่พอร์ต 1 ทิศทางการลงทะเบียน = 0x40004C04
  • พอร์ต 1 ตัวต้านทาน เปิดใช้งานที่อยู่ลงทะเบียน = 0x40004C06
  • พอร์ต 1 เลือก 0 ที่อยู่ลงทะเบียน = 0x40004C0A
  • พอร์ต 1 เลือก 1 ที่อยู่ลงทะเบียน = 0x40004C0C

เมื่อใช้พอร์ตเป็นอินพุต ควรใช้ตัวต้านทานแบบดึงขึ้นหรือดึงลงภายในของ MSP432

เนื่องจากบอร์ดพัฒนา Launchpad ได้ต่อสายสวิตช์ทั้งสองเข้ากับกราวด์ (LOW เมื่อกด) ซึ่งหมายความว่าเราควรใช้ตัวต้านทานแบบดึงขึ้นเพื่อให้แน่ใจว่าเรามีค่าสถานะสูงเมื่อไม่ได้กด

ตัวต้านทานแบบดึงขึ้น / ดึงลง

ต้องใช้ที่อยู่ Port 1 Register สองแห่งเพื่อผูกอินพุตสวิตช์เหล่านั้นกับตัวต้านทานแบบดึงขึ้น

1) ใช้ Port 1 Resistor-Enable register (0x40004C06) เพื่อระบุว่าคุณต้องการตัวต้านทาน (สำหรับสองบิตนั้น)

2) จากนั้นใช้พอร์ต 1 เอาต์พุตรีจิสเตอร์ (0x40004C02) เพื่อตั้งค่าตัวต้านทานเป็นแบบดึงขึ้นหรือแบบดึงลง อาจดูสับสนว่าเรากำลังใช้เอาต์พุตรีจิสเตอร์กับอินพุต การลงทะเบียนเอาต์พุตเกือบจะเหมือนกับวัตถุประสงค์สองประการ

ดังนั้น ในการกล่าวใหม่อีกวิธีหนึ่ง รีจิสเตอร์เอาต์พุตสามารถส่งเอาต์พุต HIGH หรือ LOW ไปยังเอาต์พุต (เช่น LED สีแดงเดี่ยว) และ / หรือใช้เพื่อตั้งค่าตัวต้านทานแบบดึงขึ้นหรือแบบดึงลงสำหรับอินพุต แต่เฉพาะในกรณีที่เปิดใช้งานคุณสมบัตินั้นผ่านการลงทะเบียน Resistor-Enable

สิ่งสำคัญในข้างต้น - เมื่อส่ง/ตั้งค่า LOW หรือ HIGH ไปยังบิตเอาต์พุตใดๆ คุณจะต้องรักษาสถานะดึงขึ้น/ดึงลงของบิตอินพุตพร้อมกัน

(วิดีโอพยายามอธิบาย)

การอ่านบิตอินพุตพอร์ต

  • ตั้งค่า SEL0 / SEL1 สำหรับฟังก์ชัน GPIO
  • ตั้งค่าการลงทะเบียน DIR เป็นอินพุตสำหรับบิตสวิตช์ แต่เป็นเอาต์พุตสำหรับ LED (พร้อมกันในไบต์เดียวกัน)
  • เปิดใช้งานตัวต้านทาน
  • ตั้งเป็นตัวต้านทานแบบดึงขึ้น
  • อ่านพอร์ต
  • คุณอาจต้องการกรองค่าที่อ่านเพื่อแยกเฉพาะบิตที่คุณต้องการ (สวิตช์ 1 และ 2)

แนะนำ: