สารบัญ:
- ขั้นตอนที่ 1: เราจะให้ไมโครคอนโทรลเลอร์สองตัวคุยกันได้อย่างไร
- ขั้นตอนที่ 2: รูทีนย่อยการสื่อสาร
- ขั้นตอนที่ 3: บทสรุป
วีดีโอ: บทช่วยสอน AVR Assembler 6: 3 ขั้นตอน
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:02
ยินดีต้อนรับสู่บทช่วยสอน 6!
กวดวิชาวันนี้จะสั้นที่เราจะพัฒนาวิธีการง่ายๆ ในการสื่อสารข้อมูลระหว่าง atmega328p หนึ่งกับอีก atmega328p โดยใช้สองพอร์ตเชื่อมต่อกัน จากนั้นเราจะนำลูกกลิ้งลูกเต๋าจากบทช่วยสอนที่ 4 และ Register Analyzer จากบทที่ 5 มาเชื่อมต่อเข้าด้วยกัน และใช้วิธีการของเราในการสื่อสารผลลัพธ์ของการทอยลูกเต๋าจากลูกกลิ้งไปยังเครื่องวิเคราะห์ จากนั้นเราจะพิมพ์ม้วนเป็นไบนารีโดยใช้ไฟ LED ที่เราสร้างขึ้นสำหรับเครื่องวิเคราะห์ในบทช่วยสอนที่ 5 เมื่อเราได้งานนี้แล้ว เราจะสามารถสร้างส่วนต่อไปของโครงการโดยรวมของเราในบทช่วยสอนถัดไป
ในบทช่วยสอนนี้ คุณจะต้อง:
- บอร์ดสร้างต้นแบบของคุณ
- ลูกกลิ้งลูกเต๋าของคุณจากบทช่วยสอน 4
- Register Analyzer ของคุณจากบทช่วยสอน 5
- สายต่อสองเส้น
-
สำเนาเอกสารข้อมูลฉบับสมบูรณ์ (ฉบับปรับปรุง 2557):
www.atmel.com/images/Atmel-8271-8-bit-AVR-M…
-
สำเนาคู่มือชุดคำสั่ง (ฉบับปรับปรุง 2014):
www.atmel.com/images/atmel-0856-avr-instruc…
นี่คือลิงค์ไปยังคอลเลกชันที่สมบูรณ์ของบทช่วยสอน AVR assembler ของฉัน:
ขั้นตอนที่ 1: เราจะให้ไมโครคอนโทรลเลอร์สองตัวคุยกันได้อย่างไร
เนื่องจากเราเริ่มขยายโครงการเพื่อให้ผลิตภัณฑ์ชิ้นเดียวของเราประกอบด้วยชิ้นส่วนขนาดเล็ก เราจึงจำเป็นต้องมีพินมากกว่าที่ Atmega328P ตัวเดียวสามารถให้ได้ ดังนั้น เราจะทำแต่ละส่วนของโปรเจ็กต์โดยรวมบนไมโครคอนโทรลเลอร์แยกกัน จากนั้นให้พวกเขาแชร์ข้อมูลระหว่างกัน ปัญหาที่เราต้องแก้ไขคือ เราจะมีวิธีง่ายๆ ให้ผู้ควบคุมสามารถพูดคุยและถ่ายโอนข้อมูลระหว่างกันได้อย่างไร สิ่งหนึ่งที่เกี่ยวกับคอนโทรลเลอร์เหล่านี้ก็คือ แต่ละตัวรันคำสั่ง 16 ล้านคำสั่งต่อวินาที นี่เป็นการจับเวลาที่แม่นยำมาก ดังนั้นเราจึงสามารถใช้ช่วงเวลานี้ในการถ่ายโอนข้อมูลได้ หากเราใช้การหน่วงเวลาเป็นมิลลิวินาทีเพื่อสร้างข้อมูล เราก็ไม่จำเป็นต้องแม่นยำขนาดนั้นเพราะ CPU ดำเนินการคำสั่ง 16,000 ครั้งในมิลลิวินาทีเดียว กล่าวอีกนัยหนึ่ง มิลลิวินาทีคือชั่วนิรันดร์สำหรับซีพียู เลยมาลองกับทอยลูกเต๋ากัน ฉันต้องการส่งผลลัพธ์ของการทอยลูกเต๋าจากชิปลูกกลิ้งลูกเต๋าไปยังชิปวิเคราะห์ สมมติว่าคุณกำลังยืนอยู่ฝั่งตรงข้ามถนนและฉันต้องการส่งสัญญาณให้คุณทราบถึงผลลัพธ์ของการทอยลูกเต๋าของฉัน สิ่งหนึ่งที่ฉันทำได้ ถ้าเราทั้งคู่มีนาฬิกา คือ ฉันสามารถเปิดไฟฉายได้ เมื่อคุณพร้อมที่จะรับข้อมูลของฉัน คุณเปิดไฟฉายและเราทั้งคู่จะเริ่มนาฬิกา จากนั้นฉันก็เปิดไฟฉายไว้ตามจำนวนมิลลิวินาทีที่แน่นอนในขณะที่ทอยลูกเต๋าแล้วปิดมัน ดังนั้น ถ้าฉันทอย 12 ฉันจะเปิดไฟไว้ 12 มิลลิวินาที ตอนนี้ปัญหาข้างต้นคือ สำหรับคุณและฉัน ไม่มีทางที่เราจะสามารถจับเวลาสิ่งต่าง ๆ ได้อย่างแม่นยำพอที่จะแยกแยะระหว่าง 5 มิลลิวินาทีและ 12 มิลลิวินาที แต่แล้วเรื่องนี้: สมมติว่าเราตัดสินใจว่าฉันจะเก็บความกระจ่างไว้เป็นเวลาหนึ่งปีสำหรับทุกๆ หมายเลขบนลูกเต๋า? แล้วถ้าฉันหมุน 12 ฉันจะส่องแสงให้คุณเป็นเวลา 12 ปีและฉันคิดว่าคุณจะเห็นด้วยว่าไม่มีทางที่คุณจะทำผิดพลาดในการหาตัวเลขใช่ไหม? คุณสามารถพักสมองและไปเล่นเบสบอล หรือแม้แต่ไปเล่นแครบส์ในเวกัสเป็นเวลา 6 เดือน ตราบใดที่ในบางช่วงของปีเพื่อมองข้ามถนนเพื่อดูว่ามีไฟส่องสว่างอยู่หรือไม่ คุณจะไม่พลาดการนับ นั่นคือสิ่งที่เราทำเพื่อไมโครคอนโทรลเลอร์! มิลลิวินาทีเดียวสำหรับ CPU ก็เหมือนหนึ่งปี ดังนั้นหากฉันเปิดสัญญาณเป็นเวลา 12 มิลลิวินาที แทบไม่มีโอกาสที่ไมโครคอนโทรลเลอร์อื่นจะสับสนเป็นเวลา 10 หรือ 11 ไม่ว่าจะมีการขัดจังหวะหรือไม่ว่าอะไรจะเกิดขึ้นในระหว่างนี้ สำหรับไมโครคอนโทรลเลอร์ มิลลิวินาทีคือชั่วนิรันดร์ นี่คือสิ่งที่เราจะทำ ก่อนอื่นเราจะเลือกพอร์ตสองพอร์ตบนคอนโทรลเลอร์ให้เป็นพอร์ตสื่อสารของเรา ฉันจะใช้ PD6 เพื่อรับข้อมูล (เราสามารถเรียกมันว่า Rx ถ้าเราต้องการ) และฉันจะเลือก PD7 สำหรับการส่งข้อมูล (เราสามารถเรียกมันว่า Tx ถ้าเราต้องการ) ชิปวิเคราะห์จะตรวจสอบเป็นระยะๆ ว่าเป็นพิน Rx และหากเห็นสัญญาณ ชิปจะเลื่อนไปที่ "รูทีนย่อยการสื่อสาร" แล้วส่งสัญญาณย้อนกลับไปยังลูกกลิ้งลูกเต๋าโดยแจ้งว่าพร้อมที่จะรับ พวกเขาทั้งคู่จะเริ่มจับเวลาและลูกกลิ้งลูกเต๋าจะส่งสัญญาณ (เช่น 5V) เป็นมิลลิวินาทีต่อตัวเลขบนลูกเต๋า ดังนั้นหากทอยเป็นดับเบิ้ลซิกหรือ 12 ลูกกลิ้งลูกเต๋าจะตั้งค่า PD7 เป็น 5V เป็นเวลา 12 มิลลิวินาที แล้วตั้งค่ากลับเป็น 0V เครื่องวิเคราะห์จะตรวจสอบพิน PD6 ของมันทุก ๆ มิลลิวินาที นับในแต่ละครั้ง และเมื่อมันกลับไปที่ 0V จากนั้นมันจะส่งออกตัวเลขผลลัพธ์ไปยังจอแสดงผลของตัววิเคราะห์ โดยแสดงเลขฐานสองสิบสองบน LED นั่นคือแผน มาดูกันว่าเราจะนำไปปฏิบัติได้หรือไม่
ขั้นตอนที่ 2: รูทีนย่อยการสื่อสาร
สิ่งแรกที่เราต้องทำคือเชื่อมต่อคอนโทรลเลอร์สองตัว ดังนั้นให้นำสายจาก PD6 มาต่อที่หนึ่งแล้วเชื่อมต่อกับ PD7 ที่อีกสายหนึ่งและในทางกลับกัน จากนั้นเริ่มต้นโดยตั้งค่า PD7 เป็น OUTPUT บนทั้งคู่ และ PD6 เป็น INPUT บนทั้งคู่ ในที่สุดก็ตั้งค่าทั้งหมดเป็น 0V ให้เพิ่มข้อมูลต่อไปนี้ในส่วน Init หรือ Reset ของโค้ดบนไมโครคอนโทรลเลอร์แต่ละตัว:
sbi DDRD, 7; PD7 ตั้งค่าเป็นเอาต์พุต
ซีบีไอ พอร์ตดี, 7; PD7 เริ่มแรก 0V cbi DDRD, 6; PD6 ตั้งค่าเป็นอินพุต cbi PortD, 6; PD6 เริ่มแรก 0V clr รวม; รวมลูกเต๋าเริ่มต้น 0
ตอนนี้ มาตั้งค่ารูทีนย่อยการสื่อสารบนชิปลูกกลิ้งลูกเต๋า ขั้นแรกให้กำหนดตัวแปรใหม่ที่ด้านบนเรียกว่า "ผลรวม" ซึ่งจะเก็บจำนวนทั้งหมดที่ทอยบนคู่ของลูกเต๋าและเริ่มต้นให้เป็นศูนย์
จากนั้นเขียนรูทีนย่อยเพื่อสื่อสารกับตัววิเคราะห์:
สื่อสาร:
cbi พอร์ต D, 7 sbi พอร์ต D, 7; ส่งสัญญาณพร้อมรอ: sbic PinD, 6; อ่าน PinD และข้ามถ้า 0V rjmp รอล่าช้า 8; ความล่าช้าในการซิงโครไนซ์ (พบสิ่งนี้ในการทดลอง) send: dec หน่วงเวลาทั้งหมด 2; ดีเลย์สำหรับแต่ละจำนวนตาย cpi รวม 0; 0 ในที่นี้หมายความว่ามีการส่งจำนวนล่าช้า "ทั้งหมด" breq PC+2 rjmp send cbi PortD, 7; PD7 ถึง 0V clr รวม; รีเซ็ตลูกเต๋าทั้งหมดเป็น 0 ret
ในตัววิเคราะห์ เราเพิ่ม rcall จากรูทีนหลักไปยังรูทีนย่อยของการสื่อสาร:
ตัววิเคราะห์ clr; เตรียมรับเบอร์ใหม่
sbic PinD, 6; ตรวจสอบ PD6 สำหรับสัญญาณ 5V rcall สื่อสาร; ถ้า 5V ไปสื่อสารวิเคราะห์ mov รวม; เอาต์พุตไปยังเครื่องวิเคราะห์ แสดงเครื่องวิเคราะห์ rcall
แล้วเขียน subroutine สื่อสารดังนี้:
สื่อสาร:
รวม clr; รีเซ็ตทั้งหมดเป็น 0 ล่าช้า 10; ชะลอการกำจัดการตีกลับ sbi PortD, 7; ตั้งค่า PB7 เป็น 5V เพื่อส่งสัญญาณพร้อมรับ: หน่วงเวลา 2; รอเลขถัดไป รวมทั้งหมด; เพิ่ม sbic PinD ทั้งหมด 6; ถ้า PD6 กลับไปเป็น 0V แสดงว่าเสร็จแล้ว rjmp ได้รับ; มิฉะนั้น วนสำรองสำหรับข้อมูลเพิ่มเติม cbi PortD, 7; รีเซ็ต PD7 เมื่อเสร็จแล้ว ret
ไปเลย! ตอนนี้ไมโครคอนโทรลเลอร์แต่ละตัวได้รับการตั้งค่าให้สื่อสารผลลัพธ์ของการทอยลูกเต๋าแล้วแสดงบนเครื่องวิเคราะห์
เราจะใช้วิธีการสื่อสารที่มีประสิทธิภาพมากขึ้นในภายหลังเมื่อเราต้องการโอนเนื้อหาของรีจิสเตอร์ระหว่างตัวควบคุมแทนที่จะเป็นเพียงการทอยลูกเต๋า ในกรณีนั้น เราจะยังคงใช้สายไฟเพียงสองเส้นเชื่อมต่อกัน แต่เราจะใช้ 1, 1 เพื่อหมายถึง "เริ่มการส่งสัญญาณ"; 0, 1 หมายถึง "1"; 1, 0 หมายถึง "0"; และสุดท้าย 0, 0 หมายถึง "สิ้นสุดการส่ง"
แบบฝึกหัดที่ 1: ดูว่าคุณสามารถใช้วิธีที่ดีกว่านี้และใช้เพื่อโอนการทอยลูกเต๋าเป็นเลขฐานสอง 8 บิตหรือไม่
ฉันจะแนบวิดีโอที่แสดงการทำงานของฉัน
ขั้นตอนที่ 3: บทสรุป
ฉันได้แนบรหัสที่สมบูรณ์สำหรับการอ้างอิงของคุณ มันไม่สะอาดและเป็นระเบียบเท่าที่ฉันต้องการ แต่ฉันจะทำความสะอาดเมื่อเราขยายมันในบทช่วยสอนในอนาคต
จากนี้ไปฉันจะแนบไฟล์ที่มีรหัสแทนที่จะพิมพ์ทั้งหมดที่นี่ เราจะพิมพ์หัวข้อที่เราสนใจจะพูดคุยกัน
นี่เป็นบทช่วยสอนสั้น ๆ ที่เราคิดค้นวิธีง่ายๆ ในการบอกไมโครคอนโทรลเลอร์ของตัววิเคราะห์ว่าผลลัพธ์ของการทอยลูกเต๋าของเราจากไมโครคอนโทรลเลอร์แบบลูกกลิ้งลูกเต๋าของเราเป็นอย่างไร ในขณะที่ใช้เพียงสองพอร์ต
แบบฝึกหัดที่ 2: แทนที่จะใช้สัญญาณพร้อมเพื่อแสดงเมื่อลูกกลิ้งลูกเต๋าพร้อมที่จะส่งและอีกอันเมื่อเครื่องวิเคราะห์พร้อมที่จะรับ ให้ใช้ "การขัดจังหวะภายนอก" ที่เรียกว่า "การขัดจังหวะการเปลี่ยนพิน" พินบน atmega328p สามารถใช้วิธีนี้ได้ ซึ่งเป็นสาเหตุที่ทำให้มี PCINT0 ถึง PCINT23 ข้างๆ ในไดอะแกรมพินเอาต์ คุณสามารถใช้สิ่งนี้เป็นการขัดจังหวะในลักษณะเดียวกับที่เราทำกับการขัดจังหวะโอเวอร์โฟลว์ตัวจับเวลา ในกรณีนี้ "ตัวจัดการ" ขัดจังหวะจะเป็นรูทีนย่อยที่สื่อสารกับลูกกลิ้งลูกเต๋า วิธีนี้ทำให้คุณไม่จำเป็นต้องเรียกรูทีนย่อยการสื่อสารจาก main จริงๆ มันจะไปที่นั่นทุกครั้งที่มีการขัดจังหวะมาจากการเปลี่ยนสถานะบนพินนั้น
แบบฝึกหัดที่ 3: วิธีที่ดีกว่ามากในการสื่อสารและถ่ายโอนข้อมูลระหว่างไมโครคอนโทรลเลอร์ตัวหนึ่งไปยังอีกตัวหนึ่งคือการใช้อินเทอร์เฟซแบบอนุกรม 2 สายในตัวบนไมโครคอนโทรลเลอร์เอง ลองอ่านส่วนที่ 22 ของแผ่นข้อมูลและดูว่าคุณจะเข้าใจวิธีใช้งานหรือไม่
เราจะใช้เทคนิคที่ซับซ้อนกว่านี้ในอนาคตเมื่อเราเพิ่มตัวควบคุมเพิ่มเติม
ความจริงที่ว่าสิ่งที่เราทำกับเครื่องวิเคราะห์ของเราคือนำจำนวนรวมของการทอยลูกเต๋าแล้วพิมพ์ออกมาเป็นไบนารีโดยใช้ไฟ LED ไม่ใช่สิ่งที่สำคัญ ความจริงก็คือตอนนี้เครื่องวิเคราะห์ของเรา "รู้" แล้วว่าการทอยลูกเต๋าคืออะไรและสามารถใช้มันได้ตามนั้น
ในบทช่วยสอนถัดไป เราจะเปลี่ยนจุดประสงค์ของ "ตัววิเคราะห์" ของเรา แนะนำองค์ประกอบวงจรเพิ่มเติมสองสามอย่าง และใช้การทอยลูกเต๋าในลักษณะที่น่าสนใจยิ่งขึ้น
จนกว่าจะถึงครั้งต่อไป…
แนะนำ:
AVR Assembler บทช่วยสอน 2: 4 ขั้นตอน
AVR Assembler Tutorial 2: บทช่วยสอนนี้เป็นความต่อเนื่องของ "AVR Assembler Tutorial 1" หากคุณยังไม่ผ่านบทช่วยสอน 1 คุณควรหยุดตอนนี้และทำอย่างนั้นก่อน ในบทช่วยสอนนี้ เราจะทำการศึกษาการเขียนโปรแกรมภาษาแอสเซมบลีของ atmega328p u
บทช่วยสอน AVR Assembler 1: 5 ขั้นตอน
AVR Assembler Tutorial 1: ฉันได้ตัดสินใจที่จะเขียนชุดของบทช่วยสอนเกี่ยวกับวิธีการเขียนโปรแกรมภาษาแอสเซมบลีสำหรับ Atmega328p ซึ่งเป็นไมโครคอนโทรลเลอร์ที่ใช้ใน Arduino หากยังมีคนสนใจอยู่ ฉันจะออกสัปดาห์ละครั้งหรือประมาณนั้นจนกว่าของจะหมด
AVR Assembler บทช่วยสอน 8: 4 ขั้นตอน
AVR Assembler บทช่วยสอน 8: ยินดีต้อนรับสู่บทช่วยสอน 8!ในบทช่วยสอนสั้น ๆ นี้ เราจะเปลี่ยนจากการแนะนำแง่มุมใหม่ๆ ของการเขียนโปรแกรมภาษาแอสเซมบลี เพื่อแสดงวิธีย้ายส่วนประกอบการสร้างต้นแบบของเราไปยัง "พิมพ์แล้ว" แผงวงจร. NS
บทช่วยสอน AVR Assembler 7: 12 ขั้นตอน
บทช่วยสอน AVR Assembler 7: ยินดีต้อนรับสู่บทช่วยสอน 7! วันนี้เราจะแสดงวิธีการไล่คีย์แพดก่อน แล้วจึงแสดงวิธีใช้พอร์ตอินพุตแบบอะนาล็อกเพื่อสื่อสารกับปุ่มกด เราจะดำเนินการโดยใช้อินเตอร์รัปต์และสายเดี่ยวเป็น ป้อนข้อมูล. เราจะต่อสายปุ่มกดเพื่อเ
บทช่วยสอน AVR Assembler 9: 7 ขั้นตอน
บทช่วยสอน AVR Assembler 9: ยินดีต้อนรับสู่บทช่วยสอน 9. วันนี้เราจะแสดงวิธีควบคุมทั้งการแสดงผล 7 ส่วนและการแสดงผล 4 หลักโดยใช้รหัสภาษาแอสเซมบลี ATmega328P และ AVR ในการดำเนินการนี้ เราจะต้องใช้ความหลากหลายในการใช้ stack