สารบัญ:

บทช่วยสอน AVR Assembler 6: 3 ขั้นตอน
บทช่วยสอน AVR Assembler 6: 3 ขั้นตอน

วีดีโอ: บทช่วยสอน AVR Assembler 6: 3 ขั้นตอน

วีดีโอ: บทช่วยสอน AVR Assembler 6: 3 ขั้นตอน
วีดีโอ: 2. Arduino for Production! How to Setup Atmel Studio 6 for the AVR Microcontroller 2024, พฤศจิกายน
Anonim
AVR Assembler บทช่วยสอน 6
AVR Assembler บทช่วยสอน 6

ยินดีต้อนรับสู่บทช่วยสอน 6!

กวดวิชาวันนี้จะสั้นที่เราจะพัฒนาวิธีการง่ายๆ ในการสื่อสารข้อมูลระหว่าง atmega328p หนึ่งกับอีก atmega328p โดยใช้สองพอร์ตเชื่อมต่อกัน จากนั้นเราจะนำลูกกลิ้งลูกเต๋าจากบทช่วยสอนที่ 4 และ Register Analyzer จากบทที่ 5 มาเชื่อมต่อเข้าด้วยกัน และใช้วิธีการของเราในการสื่อสารผลลัพธ์ของการทอยลูกเต๋าจากลูกกลิ้งไปยังเครื่องวิเคราะห์ จากนั้นเราจะพิมพ์ม้วนเป็นไบนารีโดยใช้ไฟ LED ที่เราสร้างขึ้นสำหรับเครื่องวิเคราะห์ในบทช่วยสอนที่ 5 เมื่อเราได้งานนี้แล้ว เราจะสามารถสร้างส่วนต่อไปของโครงการโดยรวมของเราในบทช่วยสอนถัดไป

ในบทช่วยสอนนี้ คุณจะต้อง:

  1. บอร์ดสร้างต้นแบบของคุณ
  2. ลูกกลิ้งลูกเต๋าของคุณจากบทช่วยสอน 4
  3. Register Analyzer ของคุณจากบทช่วยสอน 5
  4. สายต่อสองเส้น
  5. สำเนาเอกสารข้อมูลฉบับสมบูรณ์ (ฉบับปรับปรุง 2557):

    www.atmel.com/images/Atmel-8271-8-bit-AVR-M…

  6. สำเนาคู่มือชุดคำสั่ง (ฉบับปรับปรุง 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 ไม่ใช่สิ่งที่สำคัญ ความจริงก็คือตอนนี้เครื่องวิเคราะห์ของเรา "รู้" แล้วว่าการทอยลูกเต๋าคืออะไรและสามารถใช้มันได้ตามนั้น

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

จนกว่าจะถึงครั้งต่อไป…

แนะนำ: