สารบัญ:

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

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

วีดีโอ: บทช่วยสอน AVR Assembler 9: 7 ขั้นตอน
วีดีโอ: Learning AVR-C Episode 10: Serial Communication (TX) 2024, พฤศจิกายน
Anonim
AVR Assembler บทช่วยสอน 9
AVR Assembler บทช่วยสอน 9

ยินดีต้อนรับสู่กวดวิชา 9

วันนี้เราจะแสดงวิธีควบคุมทั้งการแสดงผล 7 ส่วนและการแสดงผล 4 หลักโดยใช้รหัสภาษาแอสเซมบลี ATmega328P และ AVR ในการดำเนินการนี้ เราจะต้องเปลี่ยนวิธีใช้งานสแต็กเพื่อลดจำนวนรีจิสเตอร์ที่เราต้องผูกไว้ เราจะเพิ่มตัวเก็บประจุสองสามตัว (ฟิลเตอร์กรองความถี่ต่ำ) เพื่อพยายามลดเสียงรบกวนบนปุ่มกดของเรา เราจะสร้างเครื่องขยายแรงดันไฟฟ้าจากทรานซิสเตอร์สองสามตัวเพื่อให้สวิตช์ขัดจังหวะ INT0 ของเราทำงานได้ดีขึ้นสำหรับปุ่มแรงดันต่ำที่แถวด้านล่างของปุ่มกด และเราจะเอาหัวโขกกำแพงเล็กน้อย พยายามหาตัวต้านทานที่ถูกต้อง เพื่อให้สิ่งนั้นทำงานได้อย่างถูกต้อง

เราจะใช้ปุ่มกดของเราจากบทช่วยสอน 7

ในการทำบทช่วยสอนนี้ นอกเหนือจากเนื้อหามาตรฐาน คุณจะต้อง:

  1. จอแสดงผล 7 ส่วน

    www.sparkfun.com/products/8546

  2. จอแสดงผล 4 หลัก

    www.sparkfun.com/products/11407

  3. ปุ่มกด

    www.sparkfun.com/products/97

  4. เอกสารข้อมูลสำหรับการแสดงผลซึ่งสามารถดาวน์โหลดได้จากหน้าที่เกี่ยวข้องที่ลิงก์ไปด้านบน
  5. ตัวเก็บประจุเซรามิก 68 pf, ตัวเก็บประจุ 104 สองตัว, ตัวต้านทานหนึ่งตัว, ทรานซิสเตอร์ 2N3904 NPN สองตัว

นี่คือลิงค์ไปยังคอลเลกชันที่สมบูรณ์ของบทช่วยสอน AVR assembler ของฉัน:

ขั้นตอนที่ 1: การเดินสายจอแสดงผล 7-seg

การเดินสายไฟจอแสดงผล 7-seg
การเดินสายไฟจอแสดงผล 7-seg
การเดินสายไฟจอแสดงผล 7-seg
การเดินสายไฟจอแสดงผล 7-seg
การเดินสายไฟจอแสดงผล 7-seg
การเดินสายไฟจอแสดงผล 7-seg

เราจะใช้รหัสเดียวกันกับที่ใช้ในบทช่วยสอน 7 สำหรับปุ่มกดเพื่อควบคุมการแสดงผล 7 ส่วน ดังนั้นคุณจะต้องทำสำเนาและเราจะแก้ไขมัน

เราจะแมปเซ็กเมนต์กับพินของไมโครคอนโทรลเลอร์ดังนี้:

(dp, g, f, e, d, c, b, a) = (PD7, PD6, PB5, PB4, PB3, PB2, PB1, PB0)

โดยที่ตัวอักษรของเซ็กเมนต์แสดงในรูปภาพพร้อมกับพินเอาต์ที่สอดคล้องกับ 5V ทั่วไปและแต่ละเซ็กเมนต์ LED รวมถึงจุดทศนิยม (dp) ที่ด้านล่างขวาของจอแสดงผล เหตุผลก็คือเพื่อให้เราสามารถป้อนตัวเลขทั้งหมดลงในรีจิสเตอร์เดียวและเอาต์พุตที่ลงทะเบียนกับพอร์ต B และ D เพื่อทำให้เซ็กเมนต์สว่างขึ้น ดังที่คุณเห็นว่าบิตต่างๆ มีลำดับเลขตั้งแต่ 0 ถึง 7 ดังนั้นพวกมันจะจับคู่กับพินที่ถูกต้องโดยไม่ต้องตั้งค่าและล้างแต่ละบิต

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

ฉันควรเพิ่มว่าคุณต้องใส่ตัวต้านทานระหว่างขั้วบวกทั่วไปของจอแสดงผลกับราง 5V ฉันเลือกตัวต้านทาน 330 โอห์มตามปกติ แต่ถ้าคุณชอบ คุณสามารถคำนวณความต้านทานขั้นต่ำที่จำเป็นเพื่อให้ได้ความสว่างสูงสุดจากจอแสดงผลโดยไม่ต้องทอด นี่คือวิธีการ:

ขั้นแรกให้ดูที่แผ่นข้อมูลและสังเกตว่าในหน้าแรกจะมีคุณสมบัติต่างๆ ของการแสดงผล ปริมาณที่สำคัญคือ "กระแสไปข้างหน้า" (I_f = 20mA) และ "แรงดันไปข้างหน้า" (V_f = 2.2V) สิ่งเหล่านี้บอกคุณว่าต้องการให้แรงดันตกคร่อมจอแสดงผลถ้ากระแสเท่ากับกระแสไปข้างหน้า นี่คือกระแสสูงสุดที่จอแสดงผลจะใช้โดยไม่ต้องทอด นอกจากนี้ยังเป็นความสว่างสูงสุดที่คุณจะได้รับจากส่วนต่างๆ

ลองใช้กฎของโอห์มและกฎวงของ Kirchoff เพื่อหาค่าความต้านทานขั้นต่ำที่เราจะต้องใส่ในอนุกรมกับจอแสดงผลเพื่อให้ได้ความสว่างสูงสุด กฎของ Kirchoff กล่าวว่าผลรวมของแรงดันไฟฟ้าเปลี่ยนแปลงรอบวงปิดในวงจรเท่ากับศูนย์ และกฎของโอห์มบอกว่าแรงดันตกคร่อมตัวต้านทาน R คือ: V = I R โดยที่ I คือกระแสที่ไหลผ่านตัวต้านทาน

จากแรงดันไฟต้นทางของ V และไปรอบ ๆ วงจรของเรา เรามี:

V - V_f - ฉัน R = 0

ซึ่งหมายความว่า (V - V_f)/I = R ดังนั้นความต้านทานที่จำเป็นเพื่อให้ได้ความสว่างสูงสุด (และอาจจะทอดส่วน) จะเป็น:

R = (V - V_f)/I_f = (5.0V - 2.2V)/0.02A = 140 โอห์ม

ดังนั้นหากคุณต้องการคุณสามารถใช้ 150 โอห์มได้อย่างมีความสุขโดยไม่ต้องกังวล อย่างไรก็ตาม ฉันคิดว่า 140 โอห์มทำให้มันสว่างเกินไปสำหรับความชอบของฉัน ดังนั้นฉันจึงใช้ 330 โอห์ม (ซึ่งเป็นความต้านทาน Goldilocks ส่วนตัวของฉันสำหรับ LED)

ขั้นตอนที่ 2: รหัสแอสเซมบลีและวิดีโอ

ฉันได้แนบรหัสแอสเซมบลีและวิดีโอแสดงการทำงานของปุ่มกดพร้อมกับจอแสดงผล อย่างที่คุณเห็น เราได้จับคู่ปุ่มโทรซ้ำกับ "r", คีย์แฟลชไปที่ "F", เครื่องหมายดอกจันกับ "A" และเครื่องหมายแฮชกับ "H" สิ่งเหล่านี้สามารถจับคู่กับการดำเนินการต่างๆ เช่น แบ็คสเปซ ป้อน และอะไรที่ไม่ใช่ หากคุณต้องการใช้แป้นพิมพ์สำหรับพิมพ์ตัวเลขบนจอ LCD หรือจอแสดงผล 4 หลักต่อไป คราวนี้ฉันจะไม่อ่านโค้ดทีละบรรทัดเพราะมันคล้ายกับที่เราได้ทำไปแล้วในบทช่วยสอนก่อนหน้านี้มาก ความแตกต่างส่วนใหญ่เป็นเพียงสิ่งเดียวกันที่เรารู้อยู่แล้วว่าต้องทำอย่างไร เช่น การขัดจังหวะและตารางค้นหา คุณควรอ่านโค้ดและดูสิ่งใหม่ๆ ที่เราเพิ่มเข้าไป และสิ่งที่เราเปลี่ยนแปลงไปและหามันจากที่นั่น เราจะกลับไปที่การวิเคราะห์ทีละบรรทัดในบทช่วยสอนถัดไปเมื่อเราแนะนำแง่มุมใหม่ๆ ของการเข้ารหัสภาษาแอสเซมบลีบนไมโครคอนโทรลเลอร์ AVR

ทีนี้มาดูการแสดงผล 4 หลักกัน

ขั้นตอนที่ 3: การเดินสายจอแสดงผล 4 หลัก

การเดินสายไฟจอแสดงผล 4 หลัก
การเดินสายไฟจอแสดงผล 4 หลัก
การเดินสายไฟจอแสดงผล 4 หลัก
การเดินสายไฟจอแสดงผล 4 หลัก

ตามแผ่นข้อมูล จอแสดงผล 4 หลักมีกระแสไฟไปข้างหน้า 60 mA และแรงดันไฟไปข้างหน้า 2.2 โวลต์ จากการคำนวณแบบเดิม ฉันสามารถใช้ตัวต้านทาน 47 โอห์มได้ถ้าต้องการ แต่ฉันจะใช้… hrm.. ให้ฉันดู… แล้ว 330 โอห์มล่ะ

วิธีต่อสายจอแสดงผล 4 หลักคือมี 4 แอโนด หนึ่งตัวสำหรับแต่ละหลัก และหมุดอื่น ๆ ควบคุมว่าส่วนใดที่มาในแต่ละหลัก คุณสามารถแสดงตัวเลข 4 หลักพร้อมกันได้เนื่องจากเป็นแบบมัลติเพล็กซ์ กล่าวอีกนัยหนึ่ง เหมือนกับที่เราทำกับลูกเต๋าสองลูก เราเพียงแค่หมุนเวียนพลังผ่านแต่ละขั้วบวกและมันจะกะพริบทีละลูก มันจะทำเร็วมากจนตาของเราจะไม่เห็นกะพริบและดูเหมือนตัวเลขสี่หลักจะเปิดอยู่ อย่างไรก็ตาม เพื่อให้แน่ใจ วิธีที่เราจะเขียนโค้ดคือตั้งค่าตัวเลขทั้งสี่หลัก จากนั้นวนรอบแอโนด แทนที่จะตั้งค่า ย้าย ตั้งค่า ย้าย ฯลฯ ด้วยวิธีนี้ เราจะทราบระยะเวลาที่แม่นยำระหว่างการให้แสงแต่ละหลัก.

สำหรับตอนนี้ มาทดสอบกันว่าเซ็กเมนต์ทั้งหมดใช้งานได้

วางตัวต้านทาน 330 โอห์มระหว่างรางบวกของเขียงหั่นขนมกับขั้วบวกตัวแรกบนจอแสดงผล แผ่นข้อมูลบอกเราว่าหมุดมีหมายเลขตั้งแต่ 1 ถึง 16 ทวนเข็มนาฬิกาโดยเริ่มจากด้านล่างซ้าย (เมื่อคุณดูหน้าจอตามปกติ.. โดยมีจุดทศนิยมอยู่ด้านล่าง) และระบุว่าขั้วบวกเป็นขาที่ 6, 8, 9 และ 12.

ดังนั้นเราจึงเชื่อมต่อพิน 6 กับ 5V จากนั้นนำขั้วลบจากราง GND ของคุณแล้วจิ้มไปที่พินอื่น ๆ ทั้งหมดและดูว่าเซ็กเมนต์ทั้งหมดสว่างขึ้นบนตัวเลขที่ตรงกัน (ซึ่งจริง ๆ แล้วเป็นตัวเลขที่สองจาก ทางขวา). ตรวจสอบให้แน่ใจว่าคุณได้ส่วนทั้ง 7 และจุดทศนิยมให้สว่างขึ้น

ตอนนี้ติดสาย GND ของคุณลงในหมุดตัวใดตัวหนึ่งเพื่อให้แสงส่วนใดส่วนหนึ่งสว่างขึ้น และคราวนี้ย้ายตัวต้านทานไปรอบ ๆ อีก 3 ขั้วบวก และดูว่าส่วนเดียวกันสว่างขึ้นในแต่ละหลักอื่น ๆ

มีอะไรผิดปกติ?

ปรากฎว่า pinout บนแผ่นข้อมูลไม่ถูกต้อง เนื่องจากเป็นแผ่นข้อมูลและพินเอาต์สำหรับจอแสดงผลแบบ 12 พิน 4 หลัก เช่น. อันที่ไม่มีจุดทศนิยมหรือทศนิยมบน จอที่ได้มาตอนสั่งเป็นจอ 16 พิน 4 หลักครับ อันที่จริง บนของฉัน แอโนดเซ็กเมนต์อยู่ที่พิน 1, 2, 6 และ 8 แอโนดโคลอนคือพิน 4 (แคโทดพิน 12) และแอโนด dp บนคือพิน 10 (แคโทดคือพิน 9)

แบบฝึกหัดที่ 1: ใช้ตัวต้านทานและสายกราวด์ของคุณเพื่อทำแผนที่ว่าพินใดสอดคล้องกับส่วนใดและจุดทศนิยมบนจอแสดงผล เพื่อให้ส่วนที่ถูกต้องสว่างขึ้นเมื่อเราเขียนโค้ด

วิธีที่เราต้องการโค้ดสำหรับแผนผังเซกเมนต์นั้นเหมือนกับที่เราทำกับการแสดงตัวเลข 7 หลักตัวเดียวด้านบน -- เราไม่ต้องเปลี่ยนอะไรในโค้ด สิ่งเดียวที่เราเปลี่ยนคือวิธีการเชื่อมต่อสายไฟ บนกระดาน เพียงเสียบพินพอร์ตที่ถูกต้องบนไมโครคอนโทรลเลอร์เข้ากับพินที่เกี่ยวข้องบนจอแสดงผล 4 หลัก ตัวอย่างเช่น PB0 ยังคงไปที่พินที่สอดคล้องกับเซ็กเมนต์ a, PB1 ไปที่เซ็กเมนต์ B เป็นต้น

ข้อแตกต่างเพียงอย่างเดียวคือตอนนี้เราต้องการพินเพิ่มเติม 4 พินสำหรับแอโนด เนื่องจากเราไม่สามารถไปที่ราง 5V ได้อีกต่อไป เราต้องการไมโครคอนโทรลเลอร์เพื่อตัดสินใจว่าตัวเลขใดจะได้น้ำผลไม้

ดังนั้นเราจะใช้ PC1, PC2, PC3 และ PD4 เพื่อควบคุมแอโนดของตัวเลข 4 ตัว

คุณอาจไปข้างหน้าและเสียบสายไฟ (อย่าลืมตัวต้านทาน 330 โอห์มบนสายแอโนด!)

ขั้นตอนที่ 4: การเข้ารหัสจอแสดงผล 4 หลัก

การเข้ารหัสจอแสดงผล 4 หลัก
การเข้ารหัสจอแสดงผล 4 หลัก

ลองคิดดูว่าเราต้องการเขียนโค้ดการแสดงผลนี้อย่างไร

เราต้องการให้ผู้ใช้กดปุ่มบนแป้นพิมพ์และให้ตัวเลขปรากฏขึ้นตามลำดับบนหน้าจอเมื่อกดปุ่มแต่ละปุ่ม ดังนั้น ถ้าฉันกด 1 ตามด้วย 2 มันจะแสดงบนจอแสดงผลเป็น 12 ฉันยังต้องการเก็บค่านั้นไว้ที่ 12 สำหรับการใช้งานภายใน แต่เราจะพูดถึงเรื่องนี้ในภายหลัง ตอนนี้ฉันแค่ต้องการเขียนมาโครใหม่ซึ่งจะกดแป้นของคุณและแสดงมัน อย่างไรก็ตาม เนื่องจากเรามีตัวเลขเพียง 4 หลัก ฉันต้องการให้แน่ใจว่ามันอนุญาตให้คุณพิมพ์ตัวเลขได้เพียงสี่ตัวเท่านั้น

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

นอกจากนี้เรายังต้องการให้เลื่อน "เคอร์เซอร์" ไปทางขวาช่องว่างเมื่อเราพิมพ์ตัวเลขถัดไป เพื่อที่ว่าถ้าฉันต้องการพิมพ์ 1234 เช่น หลังจากที่ฉันพิมพ์ 1 เคอร์เซอร์จะเลื่อนไปเพื่อให้ตัวเลขถัดไปที่ฉันพิมพ์ปรากฏบนจอแสดงผล 7 ส่วนถัดไป เป็นต้น ทั้งหมดนี้เกิดขึ้นฉันยังต้องการที่จะเห็นสิ่งที่ฉันพิมพ์เพื่อที่จะยังคงต้องวนผ่านตัวเลขและแสดงพวกเขา

เสียงเหมือนคำสั่งสูง?

สิ่งต่าง ๆ เลวร้ายยิ่งกว่าเดิม เราต้องการรีจิสเตอร์สำหรับใช้งานทั่วไปอีก 4 ตัวที่เราสามารถใช้เก็บค่าปัจจุบันของตัวเลข 4 หลักที่เราต้องการแสดงได้ (หากเราจะวนไปตามค่าเหล่านี้ เราต้องเก็บไว้ที่ใดที่หนึ่ง) และปัญหาคือเรามี ใช้ทะเบียนรถทั่วไปอย่างบ้าคลั่ง และถ้าเราไม่ระวัง เราจะไม่เหลืออะไรอีกแล้ว ดังนั้นจึงเป็นความคิดที่ดีที่จะจัดการกับปัญหานั้นเร็วกว่าในภายหลังและแสดงให้คุณเห็นถึงวิธีเพิ่มรีจิสเตอร์โดยใช้สแต็ก

เริ่มจากลดความซับซ้อนของสิ่งต่าง ๆ เล็กน้อย ใช้สแต็ก และเพิ่มรีจิสเตอร์บางส่วน จากนั้นเราจะพยายามทำงานอ่านและแสดงตัวเลขของเราบนจอแสดงผล 4 หลักให้สำเร็จ

ขั้นตอนที่ 5: กด 'n Pop

พุชแอนด์ป๊อป
พุชแอนด์ป๊อป

มี "ทะเบียนวัตถุประสงค์ทั่วไป" เพียงไม่กี่รายการที่เรามีให้ใช้งาน และเมื่อใช้งานแล้วจะไม่มีอีกต่อไป ดังนั้นจึงเป็นแนวทางที่ดีในการเขียนโปรแกรมที่จะใช้เฉพาะกับตัวแปรสองสามตัวที่ใช้เป็นที่เก็บข้อมูลชั่วคราวที่คุณต้องการสำหรับการอ่านและเขียนไปยังพอร์ตและ SRAM ด้วยหรืออย่างอื่นที่คุณต้องการในรูทีนย่อยทุกที่เป็นต้น ตั้งชื่อพวกเขา ดังนั้นสิ่งที่ฉันทำไปแล้วตอนนี้ที่เราได้เริ่มต้นและกำลังเรียนรู้ที่จะใช้ Stack ก็คือการผ่านโค้ดและค้นหาการลงทะเบียนวัตถุประสงค์ทั่วไปที่มีชื่อซึ่งใช้ภายในรูทีนย่อยเดียวหรืออินเตอร์รัปต์เท่านั้นและไม่มีที่อื่นในโค้ดและแทนที่ ด้วยหนึ่งในการลงทะเบียนชั่วคราวของเราและการกดและป๊อปอัพไปยังสแต็ก อันที่จริงแล้ว หากคุณดูโค้ดที่เขียนขึ้นสำหรับไมโครคอนโทรลเลอร์ที่มีขนาดเล็กกว่า หรือหากคุณย้อนเวลากลับไปเมื่อชิปทั้งหมดมีขนาดเล็กลง คุณจะเห็นรีจิสเตอร์สำหรับใช้งานทั่วไปเพียงสองสามรายการเท่านั้นที่ต้องใช้สำหรับทุกสิ่ง คุณจึงไม่สามารถทำได้ เพียงเก็บค่าไว้ในนั้นและปล่อยทิ้งไว้เพราะคุณต้องลงทะเบียนสำหรับสิ่งอื่น ดังนั้นคุณจะเห็น pushin' และ poppin' ทั่วทุกแห่งในรหัส บางทีฉันควรจะตั้งชื่อชั่วคราวของเราว่าลงทะเบียน AX และ BX เป็นความรุ่งโรจน์ที่เคารพในวันที่ผ่านมาเหล่านั้น

ตัวอย่างจะช่วยให้ชัดเจนยิ่งขึ้น

โปรดสังเกตว่าในการแปลงแบบแอนะล็อกเป็นดิจิทัลแบบสมบูรณ์ขัดจังหวะ ADC_int เราใช้รีจิสเตอร์วัตถุประสงค์ทั่วไปที่เราตั้งชื่อ buttonH ซึ่งเราใช้ในการโหลดค่าของ ADCH และเปรียบเทียบกับตารางการค้นหาของการแปลงแอนะล็อกเป็นปุ่มแบบแอนะล็อก เราใช้การลงทะเบียน buttonH นี้ภายในรูทีนย่อย ADC_int เท่านั้นและไม่มีที่อื่น ดังนั้นเราจะใช้ตัวแปร temp2 ของเราซึ่งเราใช้เป็นตัวแปรชั่วคราวที่เราสามารถใช้ได้ภายในรูทีนย่อยที่กำหนด และค่าของมันจะไม่ส่งผลกระทบใดๆ นอกรูทีนย่อยนั้น (เช่น ค่าที่เราให้ไว้ใน ADC_int จะไม่ถูกใช้ทุกที่ อื่น).

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

ผลลัพธ์สุทธิคือเราได้ "ยืม" temp และ temp2 สำหรับการใช้งานชั่วคราว จากนั้นจึงคืนค่าให้เป็นค่าก่อนหน้าเมื่อเราดำเนินการเสร็จสิ้น

นี่คือรูทีนการขัดจังหวะ ADC_int หลังจากทำการเปลี่ยนแปลงนี้:

ADC_int:

ดันอุณหภูมิ; save temp เนื่องจากเราแก้ไขที่นี่ กด temp2; บันทึก temp2 lds temp2, ADCH; โหลดปุ่มกด ldi ZH, สูง (2 * ตัวเลข) ldi ZL, ต่ำ (2 * หมายเลข) cpi temp2, 0 breq return; หากทริกเกอร์เสียงรบกวนไม่เปลี่ยน 7segnumber setkey: lpm temp, Z+; โหลดจากตารางและโพสต์ที่เพิ่มขึ้น clc cp temp2, temp; เปรียบเทียบการกดปุ่มกับตาราง brlo PC+4; ถ้า ADCH ต่ำกว่า ให้ลองใหม่อีกครั้ง lpm 7segnumber, Z; มิฉะนั้น โหลด keyvalue table inc หลัก; เพิ่มจำนวนหลัก rjmp return; และส่งคืน adiw ZH:ZL, 1; เพิ่ม Z rjmp setkey; และกลับไปที่ด้านบนสุด: pop temp2; คืนค่า temp2 pop temp; คืนค่า temp reti

ขอให้สังเกตว่าวิธีการทำงานของสแต็กคือการเปิดครั้งแรกเป็นการปิดครั้งสุดท้าย เหมือนกับกองกระดาษ คุณเห็นว่าในสองบรรทัดแรกของเรา เราผลักค่าของ temp ไปยังสแต็ก จากนั้นเราผลัก temp2 ไปที่สแต็ก จากนั้นเราใช้ค่าเหล่านี้ในรูทีนย่อยสำหรับสิ่งอื่น และสุดท้ายเราคืนค่าพวกมันเป็นค่าก่อนหน้าอีกครั้งโดย ดับ temp2 ก่อน (เนื่องจากเป็นอันสุดท้ายที่ผลักมันอยู่ที่ด้านบนสุดของสแต็กและจะเป็นอันแรกที่เราดึงกลับออก) จากนั้นจึงเปิด temp

จากนี้ไปเราจะใช้วิธีนี้ตลอดไป ครั้งเดียวที่เราจะกำหนดรีจิสเตอร์สำหรับอย่างอื่นที่ไม่ใช่ตัวแปร temp คือเมื่อเราต้องการมันทุกที่ ตัวอย่างเช่น การลงทะเบียนที่เรียกว่า "โอเวอร์โฟลว์" เป็นสิ่งที่เราใช้ในหลาย ๆ ที่ในโปรแกรม ดังนั้นเราจึงต้องการตั้งชื่อให้มัน แน่นอน เรายังสามารถใช้มันได้เหมือนที่ทำกับ temp และ temp2 เนื่องจากเราจะคืนค่ามันหลังจากที่เราทำเสร็จแล้ว แต่นั่นก็จะทำให้สิ่งต่าง ๆ กระฉับกระเฉงมากเกินไป มีการตั้งชื่อด้วยเหตุผล และเราได้กำหนด temp และ temp2 สำหรับงานนั้นแล้ว

ขั้นตอนที่ 6: ฟิลเตอร์โลว์พาสและแอมพลิฟายเออร์แรงดัน

ฟิลเตอร์กรองความถี่ต่ำและแอมพลิฟายเออร์แรงดัน
ฟิลเตอร์กรองความถี่ต่ำและแอมพลิฟายเออร์แรงดัน
ฟิลเตอร์กรองความถี่ต่ำและแอมพลิฟายเออร์แรงดัน
ฟิลเตอร์กรองความถี่ต่ำและแอมพลิฟายเออร์แรงดัน

เพื่อขจัดเสียงรบกวนเล็กน้อยและทำให้แป้นกดของเราทำงานได้ดีขึ้น เราต้องการเพิ่มตัวกรองความถี่ต่ำสองสามตัว สิ่งเหล่านี้กรองสัญญาณรบกวนความถี่สูงและอนุญาตให้สัญญาณความถี่ต่ำผ่าน โดยพื้นฐานแล้ววิธีการทำสิ่งนี้คือเพียงเพิ่มตัวเก็บประจุ 68 pf ระหว่างอินพุตแบบอะนาล็อกและกราวด์ของเรา และตัวเก็บประจุ 0.1 ไมโครฟารัด (เช่น 104) ระหว่างอินเทอร์รัปต์ PD4 (INT0) กับกราวด์ของเรา หากคุณลองเล่นกับสิ่งเหล่านี้ในขณะที่กดปุ่มบนแป้นพิมพ์ คุณจะสามารถเห็นสิ่งที่พวกเขาทำ

ต่อไปเราต้องการสร้างเครื่องขยายแรงดันไฟฟ้า ปรากฎว่าแถวด้านล่างของปุ่มบนแผงปุ่มกด (รวมถึงปุ่มโทรซ้ำ) ทำให้เกิดแรงดันไฟฟ้าต่ำเกินไปที่จะขัดขวางการขัดจังหวะ INT0 พอร์ตแอนะล็อกนั้นไวพอที่จะอ่านค่าแรงดันไฟต่ำจากคีย์เหล่านี้ได้ แต่พินอินเทอร์รัปต์ของเราไม่มีขอบที่เพิ่มขึ้นที่ดีพอที่จะขัดจังหวะเมื่อเรากดคีย์เหล่านั้น ดังนั้นเราจึงต้องการวิธีการบางอย่างเพื่อให้แน่ใจว่าขอบที่เพิ่มขึ้นของแรงดันไฟฟ้าที่ดีนั้นกระทบ PD4 แต่แรงดันต่ำแบบเดียวกันนั้นกระทบ ADC0 นี่เป็นคำสั่งที่ค่อนข้างสูงเนื่องจากสัญญาณทั้งสองมาจากสายเอาต์พุตเดียวกันของปุ่มกดของเรา มีหลายวิธีที่ซับซ้อนในการทำเช่นนี้ แต่เราจะไม่ใช้แป้นพิมพ์อีกต่อไปหลังจากบทช่วยสอนนี้ ดังนั้นเรามารวมวิธีการที่ได้ผล (แทบจะไม่) กัน

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

เมื่อคุณต่อแผงปุ่มกดและเครื่องขยายแรงดันไฟฟ้า เป็นไปได้มากที่ค่าตัวต้านทานแบบเดียวกับที่ฉันใช้จะไม่ทำงาน ดังนั้น คุณจะต้องทำการทดลองเพื่อให้ได้ค่าที่เหมาะกับคุณ

หากคุณดูแผนภาพที่ฉันแนบมากับขั้นตอนนี้ คุณจะเห็นว่าเครื่องขยายแรงดันไฟฟ้าทำงานอย่างไร เราใช้ตัวต้านทานบางตัวและทรานซิสเตอร์สองตัว วิธีการทำงานของทรานซิสเตอร์ (ดูเอกสารข้อมูล!) คือมีแรงดันไฟฟ้าขั้นต่ำที่คุณต้องป้อนให้กับพินฐานบนทรานซิสเตอร์ (พินกลาง) ซึ่งจะทำให้อิ่มตัวและปล่อยให้กระแสไหลระหว่างพินของตัวสะสมและตัวส่ง เข็มหมุด. ในกรณีของทรานซิสเตอร์ 2N3904 ที่เราใช้ที่นี่ แรงดันไฟคือ 0.65V ตอนนี้เรากำลังรับแรงดันจากเอาต์พุตของเราจากปุ่มกด และเราไม่ต้องการเปลี่ยนเอาต์พุตนั้น ดังนั้นเราจะใส่ตัวต้านทานขนาดใหญ่ระหว่างเอาต์พุตจากปุ่มกดกับฐานของทรานซิสเตอร์ตัวแรก (ฉันใช้ 1Mohm) ฉันติดป้ายกำกับว่า R_1 ในไดอะแกรม จากนั้นเราต้องการตั้งค่าตัวแบ่งแรงดันไฟฟ้าเพื่อให้ฐานของทรานซิสเตอร์ "เกือบ" ที่ 0.65 โวลต์อยู่แล้วและมีเพียงเศษเล็กเศษน้อยเท่านั้นที่จะผลักมันขึ้นไปด้านบนและทำให้อิ่มตัว บิตเล็ก ๆ น้อย ๆ นั้นจะมาจากเอาต์พุตของปุ่มกดเมื่อเรากดปุ่ม เนื่องจากปุ่มด้านล่างของปุ่มกดทำให้เกิดแรงดันไฟฟ้าเพียงเล็กน้อย เราจึงต้องอยู่ใกล้กับความอิ่มตัวของสีอยู่แล้วเพื่อให้เพียงพอ ตัวต้านทานตัวแบ่งแรงดันไฟฟ้าจะติดป้าย R_a และ R_b บนไดอะแกรม ฉันใช้ R_a = 1Mohm และ R_b = 560Kohm แต่เกือบจะแน่ใจว่าคุณจะต้องเล่นกับตัวเลขเหล่านี้เพื่อให้เหมาะสมกับการตั้งค่าของคุณคุณอาจต้องการมีกำแพงอยู่ใกล้ ๆ เพื่อกระแทกหัวของคุณและสก๊อตสองหรือสามแก้วในมือ (ฉันอยากจะแนะนำ Laphroaig -- แพง แต่คุ้มค่าถ้าคุณชอบควัน ถ้าสิ่งที่บ้าจริงๆก็ไปเหยือก ของ BV และพักค้างคืน)

ตอนนี้มาดูกันว่าทรานซิสเตอร์จะทำให้เรามีขอบที่เพิ่มขึ้นที่ดีในคีย์ INT0 และสร้างการขัดจังหวะการกดปุ่มของเราได้อย่างไร อันดับแรก มาดูกันว่าจะเกิดอะไรขึ้นเมื่อฉันไม่ได้กดปุ่ม ในกรณีนั้นทรานซิสเตอร์ตัวแรก (ที่มีข้อความว่า T1 ในไดอะแกรม) ปิดอยู่ ดังนั้นจึงไม่มีกระแสไหลระหว่างตัวสะสมและพินอีซีแอล ดังนั้นฐานของทรานซิสเตอร์อีกตัว (ป้าย T2) จะถูกดึงให้สูงและทำให้อิ่มตัวเพื่อให้กระแสไหลระหว่างหมุดของมัน ซึ่งหมายความว่าอีซีแอลของ T2 จะถูกดึงให้ต่ำเนื่องจากเชื่อมต่อกับตัวสะสมซึ่งเชื่อมต่อกับกราวด์ ดังนั้นเอาต์พุตที่ไปที่พินอินเทอร์รัปต์การกด INT0 ของเรา (PD4) จะต่ำและจะไม่มีการขัดจังหวะ

จะเกิดอะไรขึ้นเมื่อฉันกดปุ่ม? ถ้าอย่างนั้น ฐานของ T1 จะสูงกว่า 0.65V (ในกรณีของปุ่มล่างมันแทบจะไม่สูงเลย!) จากนั้นกระแสจะปล่อยให้ไหลซึ่งจะดึงฐานของ T2 ไปที่แรงดันต่ำ และสิ่งนี้จะปิด T2 แต่เราเห็นว่าเมื่อ T2 ปิดอยู่ เอาต์พุตจะถูกดึงให้สูงและด้วยเหตุนี้เราจะรับสัญญาณ 5V ไปที่พิน INT0 ของเราและจะทำให้เกิดการขัดจังหวะ

สังเกตว่าผลลัพธ์สุทธิเป็นอย่างไร ถ้าเรากดคีย์ 1 เราจะได้ 5V ไปที่ PD4 โดยไม่เปลี่ยนเอาท์พุตไปที่ ADC0 อย่างมีนัยสำคัญ และที่สำคัญกว่านั้นแม้ว่าเราจะกด Asterisk, 0, 0, Hash หรือ Redial เราก็ได้สัญญาณ 5V ไปที่ INT0 และด้วย ทำให้เกิดการหยุดชะงัก! นี่เป็นสิ่งสำคัญเนื่องจากถ้าเราเพิ่งไปโดยตรงจากเอาต์พุตของปุ่มกดไปยังพิน INT0 คีย์เหล่านั้นแทบจะไม่มีแรงดันไฟเลยและจะไม่เพียงพอที่จะทริกเกอร์พินอินเทอร์รัปต์นั้น แอมพลิฟายเออร์แรงดันไฟฟ้าของเราแก้ไขปัญหานี้ได้

ขั้นตอนที่ 7: รหัสแสดงผลและวิดีโอ 4 หลัก

นั่นคือทั้งหมดสำหรับบทช่วยสอน 9! ฉันได้แนบรหัสและวิดีโอแสดงการทำงาน

นี่จะเป็นครั้งสุดท้ายที่เราจะใช้ปุ่มกดแบบอนาล็อก (ขอบคุณพระเจ้า) ใช้งานได้ยาก แต่ก็มีประโยชน์มากในการช่วยให้เราเรียนรู้เกี่ยวกับการแปลงแอนะล็อกเป็นดิจิทัล พอร์ตแอนะล็อก อินเทอร์รัปต์ มัลติเพล็กซ์ ตัวกรองสัญญาณรบกวน แอมพลิฟายเออร์แรงดันไฟฟ้า และหลายแง่มุมของการเข้ารหัสแอสเซมบลีจากตารางค้นหาไปจนถึงตัวจับเวลา/ตัวนับ ฯลฯ นั่นเป็นเหตุผลที่เราตัดสินใจใช้ (แถมยังสนุกกับการกวาดล้างสิ่งของอีกด้วย)

ตอนนี้เรากำลังจะดูการสื่อสารอีกครั้งและรับส่วน 7 และจอแสดงผล 4 หลักของเราเพื่ออ่านการทอยลูกเต๋าของเราจากลูกกลิ้งลูกเต๋าในลักษณะเดียวกับที่เราทำกับตัววิเคราะห์การลงทะเบียนของเรา คราวนี้เราจะใช้อินเทอร์เฟซแบบสองสายแทนวิธีการแฮ็กรหัสมอร์สร่วมกัน

เมื่อเรามีการสื่อสารและม้วนกระดาษปรากฏขึ้นบนจอแสดงผล เราก็สามารถสร้างผลิตภัณฑ์ชิ้นแรกในขั้นสุดท้ายของเราได้ คุณจะสังเกตได้ว่าหากไม่มีพอร์ตแอนะล็อกทั้งหมด โค้ดของเราจะสั้นลงอย่างเห็นได้ชัดและอาจอ่านง่ายกว่า

สำหรับผู้ที่มีความทะเยอทะยาน นี่คือ "โครงการ" ที่คุณสามารถลองทำได้ว่าคุณมีความรู้ที่ต้องทำ ณ จุดนี้หากคุณได้อ่านบทช่วยสอนเหล่านี้ทั้งหมดจนถึงจุดนี้:

โครงการ: ทำเครื่องคิดเลข! ใช้จอแสดงผล 4 หลักและปุ่มกดของเรา และเพิ่มการกดปุ่มภายนอกที่จะทำหน้าที่เป็นปุ่ม "Enter" แมปดอกจันกับ "ครั้ง" แฮชเพื่อ "แบ่ง" การเรียกซ้ำเป็น "บวก" และแฟลชเป็น "ลบ" และเขียนกิจวัตรเครื่องคิดเลขที่ทำหน้าที่เหมือนเครื่องคิดเลข "reverse polish" แบบเก่าของ HP ที่วิศวกรทุกคนมี ย้อนกลับไปในวันนั้น เช่น. วิธีทำงานคือคุณป้อนตัวเลขแล้วกด "Enter" สิ่งนี้จะผลักหมายเลขนั้นไปที่สแต็ก จากนั้นคุณป้อนหมายเลขที่สองแล้วกด "enter" ซึ่งจะผลักหมายเลขที่สองไปที่สแต็ก สุดท้ายคุณกดหนึ่งในการดำเนินการเช่น X, /, + หรือ - และการดำเนินการนั้นกับตัวเลขสองตัวบนสุดของสแต็ก แสดงผล และผลักผลลัพธ์ไปยังสแต็กเพื่อให้คุณสามารถใช้งานได้อีกครั้งหากคุณ ชอบ. ตัวอย่างเช่น การเพิ่ม 2+3 คุณจะต้องทำ: 2, "enter", 3, "enter", "+" จากนั้นหน้าจอจะอ่านว่า 5.คุณรู้วิธีใช้ stack, display, keypad, และคุณ มีโค้ดพื้นหลังส่วนใหญ่เขียนไว้แล้ว เพียงเพิ่มปุ่ม Enter และรูทีนย่อยที่จำเป็นสำหรับเครื่องคิดเลข มันซับซ้อนกว่าที่คุณคิดในตอนแรกเล็กน้อย แต่ก็สนุกและทำได้

เจอกันคราวหน้า!

แนะนำ: