สารบัญ:
- ขั้นตอนที่ 1: กำจัดปุ่มกด 1
- ขั้นตอนที่ 2: กำจัดปุ่มกด 2
- ขั้นตอนที่ 3: กำจัดปุ่มกด 3
- ขั้นตอนที่ 4: ต่อสายปุ่มกด
- ขั้นตอนที่ 5: ต่อปุ่มกดเข้ากับตัววิเคราะห์ของคุณ
- ขั้นตอนที่ 6: เราควรตั้งค่าสวิตช์สลับแบบใด
- ขั้นตอนที่ 7: เขียนตัวจัดการขัดจังหวะ
- ขั้นตอนที่ 8: แมปค่าการกดแป้น
- ขั้นตอนที่ 9: โค้ดและวิดีโอสำหรับเวอร์ชัน 1
- ขั้นตอนที่ 10: รหัสสำหรับเวอร์ชัน 2
- ขั้นตอนที่ 11: เราจะกำจัดปุ่มได้อย่างไร เวอร์ชัน 3
- ขั้นตอนที่ 12: รหัสและวิดีโอสำหรับเวอร์ชันการทำงาน
วีดีโอ: บทช่วยสอน AVR Assembler 7: 12 ขั้นตอน
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:02
ยินดีต้อนรับสู่บทช่วยสอน 7!
วันนี้เราจะมาแสดงวิธีการไล่คีย์แพดก่อน แล้วจึงแสดงวิธีใช้พอร์ตอินพุตแบบอนาล็อกเพื่อสื่อสารกับปุ่มกด เราจะดำเนินการโดยใช้อินเทอร์รัปต์และสายเดี่ยวเป็นอินพุต เราจะต่อแผงปุ่มกดเพื่อให้การกดแต่ละครั้งส่งแรงดันไฟฟ้าที่ไม่ซ้ำกันไปยังอินพุตแบบอะนาล็อก ซึ่งจะทำให้เราสามารถแยกแยะความแตกต่างของแรงดันไฟฟ้าที่คีย์ถูกกดได้ จากนั้นเราจะส่งออกตัวเลขที่กดไปยังเครื่องวิเคราะห์การลงทะเบียนของเราเพื่อแสดงว่าทุกอย่างกำลังเกิดขึ้นตามที่ควรจะเป็น มีข้อผิดพลาดจำนวนหนึ่งที่คุณสามารถพบเจอได้เมื่อใช้ Analog to Digital Converter (ADC) ใน ATmega328p ดังนั้นเราจะ ทำตามขั้นตอนสองสามขั้นตอนเพื่อพยายามหาวิธีหลีกเลี่ยง เราจะเห็นด้วยว่าเหตุใดการใช้ตัวแปลงแอนะล็อกเป็นดิจิทัลจึงไม่ใช่วิธีที่ดีที่สุดในการควบคุมแป้นพิมพ์ แม้ว่าจะใช้พอร์ตบนไมโครคอนโทรลเลอร์น้อยกว่า ในบทช่วยสอนนี้ คุณจะต้อง:
- ปุ่มกด คุณสามารถซื้อหนึ่งอันหรือคุณสามารถทำสิ่งที่ฉันทำและไล่ออก
- ส่วนหัวหญิง 2 อันสำหรับปุ่มกด (ถ้าคุณกำลังไล่อย่างใดอย่างหนึ่ง)
- สายต่อ
- เขียงหั่นขนม
- 4 1 ตัวต้านทาน Kohm
- 1 15 ตัวต้านทาน Kohm
- 1 3.3 ตัวต้านทาน Kohm
- ตัวต้านทาน 180 โอห์ม 1 ตัว
- ตัวต้านทาน 1 680 โอห์ม
- มัลติมิเตอร์แบบดิจิตอล
- เครื่องวิเคราะห์ของคุณจากบทช่วยสอน 5
คุณอาจต้องการข้ามสองสามขั้นตอนแรกหากคุณมีปุ่มกดอยู่แล้วและไม่จำเป็นต้องไล่ตาม
นี่คือลิงค์ไปยังคอลเลกชันที่สมบูรณ์ของบทช่วยสอน AVR assembler ของฉัน:
ขั้นตอนที่ 1: กำจัดปุ่มกด 1
นานมาแล้ว เมื่อแม้แต่ปู่ย่าตายายของคุณยังเป็นเด็ก ผู้คนเคยใช้อุปกรณ์ที่ดูแปลก ๆ เหล่านี้ ซึ่งเสียบสายยาวเข้ากับผนังเพื่อสื่อสารระหว่างกัน พวกเขาถูกเรียกว่า "โทรศัพท์" และมักจะเป็นสิ่งพลาสติกราคาถูกที่สร้างเสียงที่น่ารำคาญเมื่อมีคนโทรหาคุณ ไม่ว่าในกรณีใด อุปกรณ์เหล่านี้มีแป้นกดซึ่งมีสายแบบเรียบง่ายและง่ายต่อการค้นหาและมีปุ่มพิเศษ 2 ปุ่ม ("โทรซ้ำ" และ "แฟลช") จากแป้นกดที่คุณสามารถซื้อเพื่อนำไปใช้ใหม่ได้ เป็น "ปุ่มลูกศร", "ปุ่มเมนู" หรืออย่างอื่น ดังนั้นเราจะเริ่มต้นด้วยการไล่คีย์แพดออกจากโทรศัพท์เครื่องเก่า ขั้นแรก ให้หยิบโทรศัพท์ขึ้นมา (ฉันใช้ GE หนึ่งเครื่องตามที่แสดงในรูปภาพ) แล้วแงะออกจากกันเพื่อให้เห็นสายไฟ จากนั้นใช้สิ่วแล้วดึงลูกบิดพลาสติกเล็กๆ ที่ถือแผงปุ่มกดไว้และถอดปุ่มกดออก
ขั้นตอนที่ 2: กำจัดปุ่มกด 2
ตอนนี้ใช้เลื่อย PVC แล้วตัดพลาสติกจากรอบ ๆ รูกุญแจแล้วตัดรอบขอบเพื่อให้ได้ความลึกที่เหมาะสมโดยเหลือแผงปุ่มกดบาง ๆ
จากนั้นใส่แผงปุ่มกดกลับเข้าไปใหม่โดยใช้หมุดเล็กๆ ที่ยังคงอยู่หลังจากที่คุณตัดส่วนบนออกในขั้นตอนสุดท้าย และใช้หัวแร้งเพื่อดันเตารีดร้อนเข้าไปในรูหมุดแต่ละอัน ซึ่งจะทำให้พลาสติกละลายและกระจายไปทั่ว ด้านล่างของปุ่มกดสร้าง "ปุ่ม" ใหม่ ซึ่งจะยึดปุ่มกดไว้เหมือนเดิม
ฉันชอบไล่ล่าลำโพงทั้งสามตัว และบางทีอาจจะเป็นอย่างอื่น เช่น สวิตช์และของที่ไม่ใช่บนบอร์ด อย่างไรก็ตาม ครั้งนี้ฉันจะไม่ไปไล่ล่าสวิตช์และสิ่งของต่างๆ เพราะเรามีเป้าหมายอื่นในขณะนี้ นอกจากนี้ยังมี IC เชิงเส้น TA31002 อยู่ในนั้นซึ่งเป็นเสียงกริ่งโทรศัพท์ แผ่นข้อมูลสามารถค้นหาได้ง่ายและดาวน์โหลดทางออนไลน์โดยระบุพินเอาต์และคุณสมบัติต่างๆ ดังนั้นฉันจะปล่อยให้มันบัดกรีไปที่บอร์ดก่อนแล้วค่อยเล่นกับมันในภายหลัง ฉันต้องการเชื่อมต่อกับออสซิลโลสโคปและดูว่าฉันสามารถรับสัญญาณอะไรได้บ้าง อาจจะทำกริ่งประตูด้วยก็ได้ ใครจะรู้.
อย่างไรก็ตาม เมื่อคุณทำลายโทรศัพท์และกำจัดชิ้นส่วนเสร็จแล้ว เราจะทำแผงปุ่มกดของเราให้เสร็จ
ขั้นตอนที่ 3: กำจัดปุ่มกด 3
ใช้ไส้ตะเกียงที่บัดกรีแล้วถอดสายแพออกจากด้านล่างของปุ่มกด ตรวจสอบให้แน่ใจว่ารูในแผงวงจรนั้นชัดเจน จากนั้นติดส่วนหัวของตัวเมียสองตัวเข้ากับบอร์ดที่มีรู คุณอาจต้องตัดส่วนหัวของคุณเพื่อให้เป็นส่วนหัวแบบ 4 พิน
เมื่อต่อเข้ากับส่วนหัวแล้ว คุณสามารถต่อสายเข้ากับเขียงหั่นขนม ใช้มัลติมิเตอร์ และทดสอบคีย์โดยติดมัลติมิเตอร์บนหมุดสุ่มและวัดความต้านทาน ซึ่งจะทำให้คุณสามารถแมปคีย์ได้ เป็นการยากที่จะดูว่าคีย์เชื่อมต่อกับเอาต์พุตอย่างไรโดยดูที่วงจร แต่ถ้าคุณใช้มัลติมิเตอร์คุณสามารถเสียบเข้ากับหมุดสองตัวใดก็ได้แล้วกดปุ่มจนกว่าคุณจะเห็นตัวเลขบนหน้าจอแทนวงจรเปิด. นี่จะเป็นพินเอาต์สำหรับคีย์นั้น
แมปคีย์ทั้งหมดกับพินเอาต์พุตในลักษณะนี้
ขั้นตอนที่ 4: ต่อสายปุ่มกด
ตอนนี้ทำตามแผนภาพการเดินสายและต่อแป้นพิมพ์เข้ากับเขียงหั่นขนมของคุณ
วิธีการทำงานคือเราจะใส่ 5V ไว้ทางด้านซ้ายมือและด้านขวาไปที่ GND พินแรกทางด้านขวาในไดอะแกรมจะเข้าไปในพินอะนาล็อกตัวแรกของเราบนไมโครคอนโทรลเลอร์ Atmega328p เมื่อไม่มีการกดปุ่ม สัญญาณจะเป็น 0V และเมื่อกดปุ่มต่าง ๆ แต่ละปุ่ม อินพุตที่พอร์ตอนาล็อกจะอยู่ในช่วงระหว่าง 0V ถึง 5V โดยมีปริมาณแตกต่างกันขึ้นอยู่กับว่ากดปุ่มใด เราเลือกค่าตัวต้านทานเพื่อให้แต่ละเส้นทางมีความต้านทานที่แตกต่างจากที่เหลือ พอร์ตแอนะล็อกบนไมโครคอนโทรลเลอร์ใช้สัญญาณแอนะล็อกและแบ่งออกเป็น 1024 ช่องสัญญาณต่างๆ ระหว่าง 0V ถึง 5V ซึ่งหมายความว่าแต่ละช่องมีความกว้าง 5V/1024 = 0.005 V/ช่อง = 5 mV/ช่อง ดังนั้นพอร์ตแอนะล็อกจึงสามารถแยกแยะแรงดันไฟฟ้าขาเข้าได้ตราบเท่าที่ต่างกันมากกว่า 5 mV ในกรณีของเรา เราได้เลือกค่าตัวต้านทานเพื่อให้การกดแป้นสองครั้งใดๆ ส่งสัญญาณแรงดันไฟฟ้าที่ต่างกันไปมากกว่านี้ ดังนั้นไมโครคอนโทรลเลอร์จึงควรตัดสินใจได้ง่าย ๆ ว่าแป้นใดถูกกด ปัญหาใหญ่คือทั้งระบบมีเสียงดังมาก ดังนั้นเราจะต้องเลือกช่วงแรงดันไฟฟ้าเพื่อแมปกับการกดปุ่มแต่ละปุ่ม แต่เราจะพูดถึงเรื่องนี้ในภายหลัง
ขอให้สังเกตว่าเราสามารถควบคุมปุ่มกด 14 ปุ่มได้โดยใช้เพียงสายอินพุตเดียวไปยังคอนโทรลเลอร์ นั่นเป็นหนึ่งในแง่มุมที่เป็นประโยชน์ของอินพุตแบบอะนาล็อก
ตอนนี้ ความพยายามครั้งแรกของเราในการควบคุมแป้นกดคือการให้ปุ่มกดทำให้เกิดการขัดจังหวะ รูทีนย่อยอินเตอร์รัปต์จะอ่านพอร์ตอินพุตแบบอะนาล็อกและตัดสินใจว่าคีย์ใดถูกกด จากนั้นจะส่งออกหมายเลขนั้นไปยังรูทีนย่อยตัววิเคราะห์การลงทะเบียนของเรา ซึ่งจะแสดง ค่าคีย์เป็นไบนารีบน LED 8 ดวงที่เราตั้งค่าไว้ในบทช่วยสอน 5
ขั้นตอนที่ 5: ต่อปุ่มกดเข้ากับตัววิเคราะห์ของคุณ
รูปภาพแสดงให้เห็นว่าเราต้องการต่อสายปุ่มกดกับไมโครคอนโทรลเลอร์อย่างไร เพื่อให้เราสามารถเห็นผลลัพธ์บนหน้าจอเครื่องวิเคราะห์ของเรา โดยพื้นฐานแล้วเราเพียงแค่ต่อเอาต์พุตจากปุ่มกดไปยัง PortC pin 0 ซึ่งเรียกอีกอย่างว่า ADC0 บน ATmega328P
อย่างไรก็ตาม มีสิ่งเพิ่มเติมสองสามอย่าง เรากำลังจะไปต่อสายปุ่มกับ PD2 เช่น. นำสายไฟจากราง 5V ของคุณไปที่ปุ่ม และจากอีกด้านหนึ่งของปุ่มไปยัง PD2 และสุดท้าย เราต้องการถอดพิน AREF ออกจากราง 5V ของเราและปล่อยให้ไม่ได้เชื่อมต่อ เราสามารถใส่ตัวเก็บประจุดีคัปปลิ้ง 0.1 ไมโครฟารัดถ้าเราต้องการ นี่คือตัวเก็บประจุเซรามิกที่มี 104 เขียนอยู่ สองหลักแรกคือตัวเลข และหลักสุดท้ายคือกำลัง 10 เราคูณมันเพื่อให้ได้คำตอบเป็น picofarads (pico หมายถึง 10^-12) ดังนั้น 104 หมายถึง 10 x 10^4 picofarads ซึ่งเหมือนกับ 100 นาโนฟารัด (นาโนหมายถึง 10^-9) ซึ่งเท่ากับ 0.1 ไมโครฟารัด (ไมโครหมายถึง 10^-6) อย่างไรก็ตาม ทั้งหมดนี้จะทำให้พิน AREF เสถียรเมื่อเราสามารถใช้เป็นพินอ้างอิงได้
เราต้องการตัวต้านทาน 1 Mohm ระหว่าง PD2 กับกราวด์ด้วย เราจะตั้งค่า PD2 เป็นพินเอาต์พุตที่ 0V และเราจะทริกเกอร์ที่ขอบบวกที่พินนั้น เราต้องการให้ขอบหายไปทันทีเมื่อเราปล่อยปุ่ม ดังนั้นเราจะใส่ตัวต้านทานแบบ "ดึงลง" นี้
เหตุผลที่เราต้องการปุ่มนั้นเป็นเพราะเราต้องการทริกเกอร์ตัวแปลงอนาล็อกเป็นดิจิตอลของเราออกจากพิน INT0 บนชิป ซึ่งก็คือ PD2 ด้วย ในที่สุด เราต้องการให้การกดแป้นทั้งสองทริกเกอร์ ADC และยังให้อินพุตที่จะแปลงโดยไม่ต้องมีปุ่มแยกต่างหาก แต่เนื่องจากวิธีการจับเวลา เราจะเริ่มต้นด้วยการมีปุ่มแยกต่างหากเพื่อเรียก ADC และเมื่อเรารีดทั้งหมด บั๊กออกและมั่นใจว่าทุกอย่างทำงานอย่างถูกต้อง จากนั้นเราจะจัดการกับปัญหาเรื่องเสียงและจังหวะเวลาที่มาพร้อมกับการทริกเกอร์จากการกดปุ่มเดียวกับที่เราต้องการอ่าน
ดังนั้น สำหรับตอนนี้ วิธีการทำงานคือ เราจะกดปุ่มค้างไว้ จากนั้นกดปุ่มเพื่อเรียก ADC จากนั้นปล่อย และหวังว่าค่าไบนารีของปุ่มที่เรากดจะแสดงขึ้นบนเครื่องวิเคราะห์
ลองเขียนโค้ดที่จะทำมันให้สำเร็จ
ขั้นตอนที่ 6: เราควรตั้งค่าสวิตช์สลับแบบใด
เรามาคิดกันก่อนว่าเราจะเขียนโค้ดนี้อย่างไรเพื่อให้คอนโทรลเลอร์สามารถอ่านอินพุตจากปุ่มกดและแปลงเป็นค่าตัวเลขที่สอดคล้องกับปุ่มที่กด เราจะใช้ Analog to Digital Converter (ADC) ที่สร้างขึ้นใน Atmega328p เราจะใช้ AREF เป็นแรงดันอ้างอิง และเอาต์พุตปุ่มกดของเราจะเชื่อมต่อกับ PortC0 หรือ PC0 โปรดทราบว่าพินนี้เรียกอีกอย่างว่า ADC0 สำหรับ Analog-to-Digital Converter 0 อาจเป็นความคิดที่ดีสำหรับคุณที่จะอ่านหัวข้อ 12.4 เกี่ยวกับการขัดจังหวะสำหรับ ATmega328P และบทที่ 24 บน Analog-to-Digital Converter ก่อนที่เราจะได้รับ เริ่มต้นหรืออย่างน้อยก็มีส่วนเหล่านั้นพร้อมสำหรับการอ้างอิง ในการตั้งค่าไมโครคอนโทรลเลอร์เพื่อให้รู้ว่าจะทำอย่างไรกับสัญญาณอินพุตแบบอะนาล็อกและวิธีโต้ตอบกับโปรแกรมของเราก่อนอื่นเราต้องตั้งค่า ADC ต่างๆ บิตการลงทะเบียนที่เกี่ยวข้อง สิ่งเหล่านี้เทียบเท่ากับสวิตช์สลับแบบเก่าบนคอมพิวเตอร์เครื่องแรก คุณพลิกสวิตช์เปิดหรือปิด หรือย้อนกลับไปไกลกว่านั้น คุณจะเสียบสายเคเบิลระหว่างเต้ารับหนึ่งกับอีกเต้ารับเพื่อที่อิเล็กตรอนที่ไปถึงทางแยกบนถนนจะพบว่าประตูบานหนึ่งปิดและอีกบานหนึ่งเปิดออกโดยบังคับให้มันไปตามเส้นทางอื่นในเขาวงกตของ วงจรจึงทำงานเชิงตรรกะที่แตกต่างกัน เมื่อเขียนโค้ดในภาษาแอสเซมบลี เราสามารถเข้าถึงฟังก์ชันเหล่านี้ของไมโครคอนโทรลเลอร์ได้อย่างใกล้ชิด ซึ่งเป็นหนึ่งในสิ่งที่น่าสนใจในการดำเนินการตั้งแต่แรก มันเป็น "ลงมือทำ" มากกว่าและน้อยกว่านั้นมาก "เบื้องหลัง" อย่างที่เคยเป็นมา ดังนั้นอย่าคิดว่าการตั้งค่าการลงทะเบียนเหล่านี้เป็นงานที่น่าเบื่อ นี่คือสิ่งที่ทำให้ภาษาแอสเซมบลีน่าสนใจ! เราได้รับความสัมพันธ์ส่วนตัวอย่างมากกับการทำงานภายในและตรรกะของชิป และทำให้มันทำในสิ่งที่เราต้องการได้อย่างแท้จริง ไม่มากและไม่น้อยไปกว่านี้ ไม่มีวงจรนาฬิกาที่สูญเปล่า ดังนั้นนี่คือรายการสวิตช์ที่เราจำเป็นต้องตั้งค่า:
- ปิดบิต ADC ลดพลังงาน PRADC ซึ่งเป็นบิต 0 ของการลงทะเบียน PRR เนื่องจากหากบิตนี้เปิดอยู่ จะเป็นการปิด ADC การลงทะเบียนลดกำลังไฟฟ้าเป็นวิธีหนึ่งในการปิดสิ่งต่าง ๆ ที่ใช้พลังงานเมื่อคุณไม่ต้องการใช้ เนื่องจากเราใช้ ADC เราจึงต้องการให้แน่ใจว่าจะไม่ปิดใช้งานในลักษณะนี้ (ดูกรมควบคุมโรค หน้า 46)
- เลือกช่องสัญญาณอนาล็อกเป็น ADC0 โดยปิด MUX3…0 ในการลงทะเบียน ADC Multiplexer Selection (ADMUX) (ดูตาราง 24-4 หน้า 249) ซึ่งจะถูกปิดโดยค่าเริ่มต้น ดังนั้นเราจึงไม่จำเป็นต้องทำเช่นนี้ อย่างไรก็ตาม ฉันรวมไว้ด้วยเพราะหากคุณเคยใช้พอร์ตอื่นที่ไม่ใช่ ADC0 คุณจะต้องสลับสวิตช์เหล่านี้ตามลำดับ การผสมผสานที่หลากหลายของ MUX3, MUX2, MUX1, MUX0 ทำให้คุณสามารถใช้พอร์ตแอนะล็อกใดๆ เป็นอินพุตของคุณ และคุณยังสามารถเปลี่ยนแปลงสิ่งเหล่านี้ได้ทันที หากคุณต้องการดูสัญญาณแอนะล็อกต่างๆ จำนวนมากพร้อมกัน
- ปิด REFS0 และ REFS1 บิตในการลงทะเบียน ADMUX เพื่อที่เราจะใช้ AREF เป็นแรงดันอ้างอิงแทนการอ้างอิงภายใน (ดูหน้า 248)
- เปิดบิต ADLAR ใน ADMUX เพื่อให้ผลลัพธ์ "ปรับซ้าย" เราจะพูดถึงตัวเลือกนี้ในขั้นตอนต่อไป
- ตั้งค่าบิต ADC0D ใน Digital Input Disable Register (DIDR0) เพื่อปิดอินพุตดิจิตอลเป็น PC0 เรากำลังใช้พอร์ตนั้นสำหรับอินพุตแบบอะนาล็อก ดังนั้นเราอาจปิดอินพุตดิจิทัลสำหรับพอร์ตนั้นด้วย
- ตั้งค่า ISC0 และ ISC1 ใน External Interrupt Control Register A (EICRA) เพื่อระบุว่าเราต้องการทริกเกอร์บนขอบที่เพิ่มขึ้นของสัญญาณแรงดันไฟฟ้าไปยังพิน INT0 (PD2) ดูหน้า 71
- ล้างบิต INT0 และ INT1 ใน External Interrupt Mask Register (EIMSK) เพื่อระบุว่าเราไม่ได้ใช้การขัดจังหวะบนพินนี้ หากเราต้องเปิดใช้งานการขัดจังหวะบนพินนี้ เราจะต้องมีตัวจัดการการขัดจังหวะที่ที่อยู่ 0x0002 แต่เราจะตั้งค่ามันแทนเพื่อให้สัญญาณบนพินนี้ทริกเกอร์การแปลง ADC ซึ่งความสมบูรณ์จะถูกจัดการโดยการแปลง ADC ให้เสร็จสิ้นการขัดจังหวะที่ ที่อยู่ 0x002A. ดูหน้า 72
- ตั้งค่าบิต ADC Enable (ADEN) (บิต 7) ในการควบคุม ADC และการลงทะเบียนสถานะ A (ADCSRA) เพื่อเปิดใช้งาน ADC ดูหน้า 249
- เราสามารถเริ่มการแปลงครั้งเดียวโดยการตั้งค่า ADC start conversion bit (ADSC) ทุกครั้งที่เราต้องการอ่านสัญญาณแอนะล็อก อย่างไรก็ตาม สำหรับตอนนี้ เราอยากให้มันอ่านโดยอัตโนมัติเมื่อใดก็ตามที่มีคนกดปุ่ม ดังนั้นเราจะเปิดใช้งาน ADC แทน Autotrigger Enable (ADATE) บิตในการลงทะเบียน ADCSRA เพื่อให้การเรียกทำงานโดยอัตโนมัติ
- นอกจากนี้เรายังตั้งค่าบิต ADPS2..0 (บิต AD Prescalar) เป็น 111 เพื่อให้นาฬิกา ADC เป็นนาฬิกา CPU หารด้วยปัจจัย 128
- เราจะเลือกแหล่งที่มาของ ADC ที่ทริกเกอร์ให้เป็น PD2 ซึ่งเรียกอีกอย่างว่า INT0 (External Interrupt Request 0) เราทำได้โดยสลับบิตต่างๆ ในการลงทะเบียน ADCSRB (ดูตาราง 24-6 ในหน้า 251) เราเห็นตามตารางที่เราต้องการปิด ADTS0, ADTS1 เปิดและ ADTS2 ปิดเพื่อให้ ADC จะเรียกใช้พินนั้น สังเกตว่าถ้าเราต้องการสุ่มตัวอย่างพอร์ตแอนะล็อกอย่างต่อเนื่องเช่นถ้าเรากำลังอ่านสัญญาณแอนะล็อกอย่างต่อเนื่อง (เช่นการสุ่มตัวอย่างเสียงหรือบางอย่าง) เราจะตั้งค่านี้เป็นโหมดวิ่งฟรี วิธีที่เราใช้การตั้งค่าทริกเกอร์บน PD2 จะทริกเกอร์การอ่าน ADC ของพอร์ตอะนาล็อก PC0 โดยไม่ทำให้เกิดการขัดจังหวะ การขัดจังหวะจะเกิดขึ้นเมื่อการแปลงเสร็จสิ้น
- เปิดใช้งานบิต ADC Interrupt Enable (ADIE) ในการลงทะเบียน ADCSRA เพื่อที่ว่าเมื่อการแปลงแอนะล็อกเป็นดิจิทัลเสร็จสมบูรณ์ จะสร้างอินเทอร์รัปต์ซึ่งเราสามารถเขียนตัวจัดการการขัดจังหวะและวางไว้ที่.org 0x002A
- ตั้งค่าบิต I ใน SREG เพื่อเปิดใช้งานการขัดจังหวะ
แบบฝึกหัดที่ 1: ตรวจสอบให้แน่ใจว่าคุณได้อ่านส่วนที่เกี่ยวข้องในแผ่นข้อมูลสำหรับการตั้งค่าแต่ละอย่างข้างต้น เพื่อให้คุณเข้าใจว่าเกิดอะไรขึ้นและจะเกิดอะไรขึ้นหากเราเปลี่ยนเป็นการตั้งค่าอื่น
ขั้นตอนที่ 7: เขียนตัวจัดการขัดจังหวะ
ในขั้นตอนสุดท้าย เราเห็นว่าเราได้ตั้งค่าเพื่อให้ขอบที่เพิ่มขึ้นที่ตรวจพบบน PD2 จะทริกเกอร์การแปลงแอนะล็อกเป็นดิจิทัลบน PC0 และเมื่อการแปลงนี้เสร็จสิ้น จะมีการขัดจังหวะ ADC Conversion Complete ตอนนี้เราต้องการทำอะไรกับการขัดจังหวะนี้ หากคุณตรวจสอบตารางที่ 12-6 ในหน้า 65 คุณจะเห็นรายการการขัดจังหวะที่เป็นไปได้ เราได้เห็นการขัดจังหวะ RESET ที่ที่อยู่ 0x0000 และ Timer/Counter0 Overflow ขัดจังหวะที่ที่อยู่ 0x0020 ในบทช่วยสอนก่อนหน้านี้ ตอนนี้เราต้องการดูการขัดจังหวะของ ADC ซึ่งเราเห็นตามตารางอยู่ที่ที่อยู่ 0x002A ดังนั้นในตอนต้นของรหัสภาษาแอสเซมบลีของเรา เราจะต้องมีบรรทัดที่เขียนว่า:
.org 0x002Arjmp ADC_int
ซึ่งจะข้ามไปยังตัวจัดการการขัดจังหวะของเราที่มีป้ายกำกับ ADC_int เมื่อใดก็ตามที่ ADC เสร็จสิ้นการแปลง ดังนั้นเราควรเขียนตัวจัดการขัดจังหวะของเราอย่างไร วิธีการทำงานของ ADC คือการคำนวณต่อไปนี้:
ADC = วิน x 1024 / Vref
ให้เราดูว่าเกิดอะไรขึ้นถ้าฉันกดปุ่ม "โทรซ้ำ" บนแป้นพิมพ์ ในกรณีนั้น แรงดันไฟบน PC0 จะเปลี่ยนเป็นค่าบางค่า เช่น 1.52V และเนื่องจาก Vref อยู่ที่ 5V เราจึงจะได้:
ADC = (1.52V) x 1024 / 5V = 311.296
ดังนั้นมันจึงแสดงเป็น 311 หากเราต้องการแปลงกลับเป็นแรงดันไฟฟ้า เราจะกลับการคำนวณ เราไม่จำเป็นต้องทำเช่นนี้เนื่องจากเราไม่สนใจแรงดันไฟฟ้าจริงเพียงในการแยกแยะระหว่างพวกเขา เมื่อการแปลงเสร็จสิ้น ผลลัพธ์จะถูกเก็บไว้ในหมายเลข 10 บิตในการลงทะเบียน ADCH และ ADCL และเราได้ทำให้มันถูก "ปรับซ้าย" ซึ่งหมายความว่า 10 บิตเริ่มต้นที่บิต 7 ของ ADCH และลงไปที่ บิต 6 ของ ADCL (มีทั้งหมด 16 บิตในรีจิสเตอร์ทั้งสองนี้ และเราใช้เพียง 10 รายการเท่านั้น นั่นคือ 1024 ช่องสัญญาณ) เราสามารถให้ผลลัพธ์ "ถูกปรับ" ได้หากต้องการโดยการล้างบิต ADLAR ในการลงทะเบียน ADMUX เหตุผลที่เราเลือกการปรับด้านซ้ายเป็นเพราะสัญญาณของเราห่างกันมากพอที่ตัวเลขสองหลักสุดท้ายของหมายเลขช่องจะไม่เกี่ยวข้องและ อาจเป็นแค่เสียงรบกวน ดังนั้นเราจะแยกแยะการกดปุ่มโดยใช้ตัวเลข 8 ตัวบนเท่านั้น กล่าวคือ เราจะต้องดูที่ ADCH เท่านั้นเพื่อดูว่าปุ่มใดถูกกด ดังนั้นตัวจัดการการขัดจังหวะของเราควรอ่านตัวเลขจาก ADCH ลงทะเบียน แปลงตัวเลขนั้นเป็นค่าปุ่มกด แล้วส่งค่านั้นไปยัง LED ตัววิเคราะห์การลงทะเบียนของเรา เพื่อให้เราสามารถตรวจสอบได้ว่าการกด "9" จะทำให้ไฟ LED ที่ตรงกับ "00001001" สว่างขึ้น ก่อนที่เราจะไปนั้น แม้ว่าเราต้องดูก่อนว่าจะแสดงอะไรใน ADCH เมื่อเรากดปุ่มต่างๆ ลองเขียนตัวจัดการขัดจังหวะอย่างง่าย ๆ ที่เพิ่งส่งเนื้อหาของ ADCH ไปยังจอแสดงผลของตัววิเคราะห์ นี่คือสิ่งที่เราต้องการ:
ADC_int:lds analyzer, ADCH;โหลดค่าของ ADCH ลงในเครื่องวิเคราะห์ของเรา EIFR, 0; ล้างแฟล็กอินเตอร์รัปต์ภายนอกเพื่อให้พร้อมที่จะกลับไปอีกครั้ง
ถึงตอนนี้ คุณควรจะสามารถคัดลอกโค้ดจากตัววิเคราะห์ของเราในบทช่วยสอนที่ 5 และเพิ่มการขัดจังหวะนี้และการตั้งค่าการสลับและเรียกใช้ได้ แบบฝึกหัดที่ 2: เขียนโค้ดและเรียกใช้ ดูว่าคุณได้รับ ADCH ที่แสดงบนหน้าจอเครื่องวิเคราะห์ของคุณ ลองกดปุ่มเดิมหลายๆ ครั้ง คุณได้รับค่าเดียวกันใน ADCH เสมอหรือไม่
ขั้นตอนที่ 8: แมปค่าการกดแป้น
สิ่งที่เราต้องทำตอนนี้คือแปลงค่าใน ADCH เป็นตัวเลขที่สอดคล้องกับคีย์ที่กด เราทำสิ่งนี้โดยเขียนเนื้อหาของ ADCH สำหรับการกดแต่ละครั้ง จากนั้นแปลงเป็นตัวเลขทศนิยมเหมือนที่ฉันทำในภาพ ในรูทีนการจัดการอินเตอร์รัปต์ของเรา เราจะพิจารณาค่าช่วงทั้งหมดตามการกดแต่ละครั้ง เพื่อให้ ADC จับคู่ทุกสิ่งในช่วงนั้นกับการกดแป้นที่กำหนด
แบบฝึกหัดที่ 3: ทำ ma-p.webp
นี่คือสิ่งที่ฉันได้รับจากฉัน (ของคุณน่าจะแตกต่างออกไปมาก) สังเกตว่าฉันได้ตั้งค่าช่วงของค่าสำหรับการกดแต่ละครั้ง
ADC_int:; ตัววิเคราะห์ขัดจังหวะภายนอก handlerclr; เตรียมพร้อมสำหรับตัวเลขใหม่ปุ่ม H, ADCH; ADC อัปเดตเมื่ออ่าน ADCH clccpi buttonH, 240brlo PC+3; ถ้า ADCH ใหญ่กว่า แสดงว่าเป็น 1ldi analyzer, 1; ดังนั้นโหลดตัววิเคราะห์ด้วยผลตอบแทน 1rjmp; และส่งคืน clccpi buttonH, 230; ถ้า ADCH ใหญ่กว่า เครื่องวิเคราะห์ 2brlo PC+3ldi, 2rjmp return clccpi buttonH, 217brlo PC+3ldi analyzer, 3rjmp return clccpi buttonH, 203brlo PC+3ldi analyzer, 4rjmp return clccpi buttonH, 187brlo PC+3ldi analyzer, 5rpijmp buttonH return 155brlo PC+3ldi analyzer, 6rjmp return clccpi buttonH, 127brlo PC+3ldi analyzer, 255; เราจะตั้งค่าแฟลชเป็น onrjmp return clccpi buttonH ทั้งหมด, 115brlo PC+3ldi analyzer, 7rjmp return clccpi buttonH, 94brlo PC+3ldi analyzer, 8rjmp return clccpi buttonH, 62brlo PC+3ldi analyzer, 9rjmp return clccpi buttonH, 37brlo PC+3ldi analyzer 0b11110000; เครื่องหมายดอกจันคือครึ่งบนของ onrjmp return clccpi buttonH, 28brlo PC+3ldi analyzer, 0rjmp return clccpi buttonH, 17brlo PC+3ldi analyzer, 0b00001111; เครื่องหมายแฮชคือครึ่งล่าง onrjmp return clccpi buttonH, 5brlo PC+3ldi analyzer, 0b11000011; การโทรซ้ำคือ 2rjmp return ldi analyzer ด้านบน 2 ด้านล่าง, 0b11011011; มิฉะนั้น เกิดข้อผิดพลาด return:reti
ขั้นตอนที่ 9: โค้ดและวิดีโอสำหรับเวอร์ชัน 1
ฉันได้แนบรหัสของฉันสำหรับไดรเวอร์ปุ่มกดรุ่นแรกนี้แล้ว ในส่วนนี้คุณต้องกดปุ่มแล้วกดปุ่มเพื่อให้ ADC อ่านอินพุตจากปุ่มกด สิ่งที่เราอยากได้คือไม่มีปุ่ม แต่สัญญาณที่จะทำการแปลงมาจากการกดปุ่มแทน แบบฝึกหัดที่ 3: รวบรวมและอัปโหลดโค้ดนี้แล้วลองใช้งาน คุณอาจต้องเปลี่ยนเกณฑ์การแปลงต่าง ๆ เพื่อให้สอดคล้องกับแรงดันการกดของคุณเนื่องจากอาจแตกต่างจากของฉัน จะเกิดอะไรขึ้นหากคุณพยายามใช้อินพุตจากแป้นกดทั้งสำหรับ ADC0 และพินอินเทอร์รัปต์ภายนอกแทนที่จะใช้ปุ่ม ฉันจะแนบวิดีโอแสดงการทำงานของไดรเวอร์การกดแป้นเวอร์ชันแรกของเราด้วย คุณจะสังเกตเห็นว่า ในรหัสของฉันมีส่วนเริ่มต้น Stack Pointer มีรีจิสเตอร์หลายตัวที่เราอาจต้องการพุชและป๊อปจากสแต็กเมื่อเราจัดการกับตัวแปรและสิ่งที่ไม่ใช่ และยังมีรีจิสเตอร์ที่เราอาจต้องการบันทึกและกู้คืนในภายหลัง ตัวอย่างเช่น SREG เป็นรีจิสเตอร์ที่ไม่ได้ถูกเก็บรักษาไว้ระหว่างอินเตอร์รัปต์ ดังนั้นแฟล็กต่างๆ ที่ตั้งค่าและล้างอันเป็นผลมาจากการดำเนินการอาจเปลี่ยนแปลงได้หากมีการขัดจังหวะเกิดขึ้นตรงกลางของบางสิ่ง ดังนั้นจึงเป็นการดีที่สุดถ้าคุณกด SREG ไปยังสแต็กที่จุดเริ่มต้นของตัวจัดการการขัดจังหวะ จากนั้นดึงออกอีกครั้งที่ส่วนท้ายของตัวจัดการการขัดจังหวะ ฉันได้วางไว้ในโค้ดเพื่อแสดงวิธีการเริ่มต้นและเพื่อคาดการณ์ว่าเราต้องการมันอย่างไรในภายหลัง แต่เนื่องจากเราไม่สนใจว่าจะเกิดอะไรขึ้นกับ SREG ระหว่างการขัดจังหวะในโค้ดของเรา ฉันจึงไม่ได้ใช้สแต็กสำหรับสิ่งนี้ แจ้งให้ทราบด้วย ที่ฉันใช้การดำเนินการกะเพื่อตั้งค่าบิตต่างๆ ในรีจิสเตอร์เมื่อเริ่มต้น ตัวอย่างเช่นในบรรทัด:
อุณหภูมิ ldi (1<
คำสั่ง "<<" ในบรรทัดแรกของโค้ดด้านบนคือการดำเนินการกะ โดยพื้นฐานแล้วจะใช้เลขฐานสอง 1 ซึ่งก็คือ 0b00000001 และเลื่อนไปทางซ้ายตามจำนวน ISC01 นี่คือตำแหน่งของบิตที่ชื่อ ISC01 ในการลงทะเบียน EICRA เนื่องจาก ISC01 เป็นบิต 1 หมายเลข 1 จึงถูกเลื่อนไปทางซ้าย 1 ตำแหน่งเพื่อให้เป็น 0b00000010 ในทำนองเดียวกัน ISC00 ที่สองคือบิต 0 ของ EICRA ดังนั้นการเลื่อนหมายเลข 1 จึงเป็นศูนย์ตำแหน่งทางด้านซ้าย หากดูอีกครั้งที่ไฟล์ m328Pdef.inc ที่คุณดาวน์โหลดในบทช่วยสอนแรกและใช้ evrr มาตั้งแต่นั้น คุณจะเห็นว่าเป็นเพียงรายการคำสั่ง ".equ" ที่ยาวเหยียด คุณจะพบว่า ISC01 เท่ากับ 1 แอสเซมเบลอร์แทนที่ทุกอินสแตนซ์ของมันด้วย 1 ก่อนที่จะเริ่มประกอบอะไรเลย พวกเขาเป็นเพียงชื่อสำหรับบิตการลงทะเบียนเพื่อช่วยให้มนุษย์สามารถอ่านและเขียนโค้ดได้ ตอนนี้ เส้นแนวตั้งระหว่างการดำเนินการกะทั้งสองด้านบนเป็นการดำเนินการ "หรือ" แบบลอจิคัล นี่คือสมการ:
0b00000010 | 0b00000001 = 0b00000011
และนี่คือสิ่งที่เรากำลังโหลด (โดยใช้ "ldi") ลงใน temp เหตุผลที่ผู้คนใช้วิธีนี้ในการโหลดค่าลงในรีจิสเตอร์คืออนุญาตให้ใช้ชื่อบิตแทนตัวเลขได้ และทำให้โค้ดอ่านง่ายขึ้นมาก นอกจากนี้ยังมีเทคนิคอื่นๆ อีกสองวิธีที่เราใช้ เราใช้คำแนะนำ "ori" และ "andi" สิ่งเหล่านี้ช่วยให้เราสามารถ SET และ CLEAR บิตตามลำดับโดยไม่ต้องเปลี่ยนบิตอื่น ๆ ในรีจิสเตอร์ ตัวอย่างเช่น เมื่อฉันใช้
อุณภูมิ (1
อุณหภูมิ "หรือ" นี้ด้วย 0b00000001 ซึ่งวาง 1 ในบิตที่ศูนย์และปล่อยให้ส่วนที่เหลือทั้งหมดไม่เปลี่ยนแปลง เมื่อเราเขียน
อุณหภูมิและอุณหภูมิ 0b11111110
สิ่งนี้จะเปลี่ยนอุณหภูมิบิตที่ศูนย์เป็น 0 และทำให้ส่วนที่เหลือทั้งหมดไม่เปลี่ยนแปลง
แบบฝึกหัดที่ 4: คุณควรอ่านโค้ดและทำความเข้าใจแต่ละบรรทัด คุณอาจพบว่ามันน่าสนใจที่จะหาวิธีที่ดีกว่าในการทำสิ่งต่างๆ และเขียนโปรแกรมที่ดีกว่า มีหลายร้อยวิธีในการเขียนโค้ดของสิ่งต่างๆ และฉันค่อนข้างมั่นใจว่าคุณสามารถหาวิธีที่ดีกว่าของฉันได้ คุณอาจพบข้อผิดพลาดและการละเว้น (ห้ามสวรรค์!) ในกรณีนั้นฉันอยากจะได้ยินเกี่ยวกับพวกเขาเพื่อที่จะได้แก้ไข
โอเค ทีนี้มาดูกันว่าเราจะกำจัดปุ่มฟุ่มเฟือยนั้นได้ไหม…
ขั้นตอนที่ 10: รหัสสำหรับเวอร์ชัน 2
วิธีที่ง่ายที่สุดในการกำจัดปุ่มคือการเอาออกทั้งหมด ลืมอินพุตไปที่ PB2 และเพียงแค่เปลี่ยน ADC เป็น "โหมดวิ่งฟรี"
กล่าวอีกนัยหนึ่งเพียงแค่เปลี่ยนการลงทะเบียน ADCSRB เพื่อให้ ADTS2, ADTS1 และ ADTS0 เป็นศูนย์ทั้งหมด
จากนั้นตั้งค่าบิต ADSC ใน ADCSRA เป็น 1 ซึ่งจะเริ่มการแปลงครั้งแรก
ตอนนี้อัปโหลดไปยังไมโครคอนโทรลเลอร์ของคุณแล้วคุณจะพบว่าตัวเลขที่ถูกต้องปรากฏขึ้นบนจอแสดงผลในขณะที่คุณกดปุ่มและเฉพาะเมื่อคุณกดปุ่มเท่านั้น เนื่องจาก ADC กำลังสุ่มตัวอย่างพอร์ต ADC0 และแสดงค่าอย่างต่อเนื่อง เมื่อคุณปล่อยนิ้วออกจากปุ่ม "การเด้งของปุ่ม" จะทำให้ค่าสุ่มสองสามค่าเกิดขึ้นอย่างรวดเร็วมาก จากนั้นจะกลับสู่อินพุต 0V ในรหัสของเราเรามี 0V นี้ปรากฏเป็น 0b11011011 (เนื่องจากการกดปุ่ม `0' กำลังใช้ค่าที่แสดง 0b00000000 อยู่แล้ว)
นี่ไม่ใช่วิธีแก้ปัญหาที่เราต้องการ แต่ด้วยเหตุผลสองประการ อันดับแรกเราไม่ต้องการกดปุ่มค้างไว้ เราต้องการกดหนึ่งครั้งและให้ตัวเลขแสดงขึ้น (หรือใช้ในโค้ดใหม่ในบทช่วยสอนในภายหลัง) ประการที่สอง เราไม่ต้องการสุ่มตัวอย่าง ADC0 อย่างต่อเนื่อง เราต้องการให้อ่านเพียงครั้งเดียว แปลง แล้วเข้าสู่โหมดสลีปจนกว่าการกดปุ่มใหม่จะทำให้เกิด Conversion ใหม่ โหมดการวิ่งฟรีจะดีที่สุดถ้าสิ่งเดียวที่คุณต้องการให้ไมโครคอนโทรลเลอร์ทำคืออ่านอินพุตแบบอะนาล็อกอย่างต่อเนื่อง เช่น หากคุณต้องการแสดงอุณหภูมิแบบเรียลไทม์หรือบางอย่าง
เลยมาหาทางออกอื่นกัน…
ขั้นตอนที่ 11: เราจะกำจัดปุ่มได้อย่างไร เวอร์ชัน 3
มีหลายวิธีที่เราจะดำเนินการต่อไปได้ ขั้นแรก เราสามารถเพิ่มฮาร์ดแวร์เพื่อกำจัดปุ่มได้ ตัวอย่างเช่น เราอาจลองใส่ทรานซิสเตอร์ในวงจรที่บรรทัดเอาต์พุตของการกดแป้น เพื่อให้กระแสไฟไหลออกจากเอาต์พุตเล็กน้อยและส่งพัลส์ 5V ไปยังพินอินเทอร์รัปต์ PD2
อย่างไรก็ตาม อย่างน้อยก็อาจมีเสียงดังเกินไป และที่แย่ที่สุดก็คือไม่มีเวลาเพียงพอสำหรับการอ่านการกดปุ่มที่แม่นยำ เนื่องจากแรงดันไฟขาออกของปุ่มกดจะไม่มีเวลาคงที่ก่อนที่จะอ่านค่า ADC
ดังนั้นเราจึงควรคิดหาโซลูชันซอฟต์แวร์ สิ่งที่เราต้องการจะทำคือเพิ่มการขัดจังหวะบนพิน PD2 และเขียนตัวจัดการการขัดจังหวะสำหรับมันซึ่งเรียกการอ่านพินปุ่มกดเพียงครั้งเดียว กล่าวอีกนัยหนึ่ง เรากำจัดการขัดจังหวะอัตโนมัติของ ADC และเพิ่มการขัดจังหวะภายนอกที่เรียก ADC ภายใน ด้วยวิธีนี้สัญญาณในการอ่าน ADC จะเกิดขึ้นหลังจากสัญญาณ PD2 เกิดขึ้นแล้ว และอาจทำให้มีเวลามากพอที่จะรักษาเสถียรภาพของแรงดันไฟฟ้าที่ถูกต้องก่อนที่จะอ่านและแปลงพิน PC0 เราจะยังคงมีการขัดจังหวะการทำให้สมบูรณ์ของ ADC ซึ่งส่งผลลัพธ์ไปยังเครื่องวิเคราะห์ที่แสดงในตอนท้าย
มีเหตุผล? มาทำกันเลย…
ดูรหัสใหม่ที่แนบมา
คุณเห็นการเปลี่ยนแปลงต่อไปนี้:
- เราได้เพิ่ม rjmp ที่ที่อยู่.org 0x0002 เพื่อจัดการกับการขัดจังหวะภายนอก INT0
- เราเปลี่ยนการลงทะเบียน EIMSK เพื่อระบุว่าเราต้องการขัดจังหวะบน INT0 pin
- เราเปลี่ยนพิน ADATE ในการลงทะเบียน ADCSRA เพื่อปิดใช้งานการเรียกอัตโนมัติ
- เรากำจัดการตั้งค่า ADCSRB เนื่องจากไม่เกี่ยวข้องเมื่อ ADATE ปิดอยู่
- เราไม่ต้องรีเซ็ตการตั้งค่าสถานะทริกเกอร์ภายนอกอีกต่อไป เนื่องจากรูทีนการขัดจังหวะ INT0 จะทำสิ่งนี้โดยอัตโนมัติเมื่อเสร็จสิ้น ก่อนหน้านี้เราไม่มีรูทีนการขัดจังหวะ เราเพิ่งทริกเกอร์ ADC ออกจากสัญญาณที่พินนั้น ดังนั้นเราจึงต้องทำ ล้างธงนั้นด้วยมือ
ตอนนี้ในตัวจัดการการขัดจังหวะ เราเพียงแค่เรียกการแปลงเดียวจาก ADC
แบบฝึกหัดที่ 5: เรียกใช้เวอร์ชันนี้และดูว่าเกิดอะไรขึ้น
ขั้นตอนที่ 12: รหัสและวิดีโอสำหรับเวอร์ชันการทำงาน
ดังที่เราเห็นในเวอร์ชันที่แล้ว การขัดจังหวะของปุ่มทำงานได้ไม่ดีนัก เนื่องจากอินเทอร์รัปต์ถูกทริกเกอร์บนขอบที่เพิ่มขึ้นเพื่อตรึง PD2 จากนั้นตัวจัดการการขัดจังหวะจะเรียกการแปลง ADC อย่างไรก็ตาม ADC จะอ่านค่าแรงดันไฟฟ้าก่อนที่มันจะเสถียรและอ่านเรื่องไร้สาระ
สิ่งที่เราต้องการคือการทำให้เกิดการหน่วงเวลาระหว่างการขัดจังหวะบน PD2 และการอ่าน ADC บน PC0 เราจะทำเช่นนี้โดยเพิ่มตัวจับเวลา/ตัวนับ การขัดจังหวะการล้นของตัวนับ และรูทีนการหน่วงเวลา โชคดีที่เรารู้วิธีการทำเช่นนี้จากบทช่วยสอน 3 แล้ว! ดังนั้นเราจะเพียงแค่คัดลอกและวางรหัสที่เกี่ยวข้องจากที่นั่น
ฉันได้ให้รหัสผลลัพธ์และวิดีโอแสดงการทำงาน
คุณจะสังเกตเห็นว่าการอ่านไม่แม่นยำอย่างที่หวัง อาจเป็นเพราะหลายแหล่ง:
- เรากำลังแตะจากเอาต์พุตแรงดันไฟฟ้าของปุ่มกดเพื่อทริกเกอร์บน PD2 ซึ่งส่งผลต่อการอ่านใน PC0
- เราไม่รู้จริงๆ ว่าต้องหน่วงเวลานานแค่ไหนหลังจากทริกเกอร์เพื่อให้ได้ค่าการอ่านที่ดีที่สุด
- การแปลง ADC ใช้เวลาสองสามรอบจึงจะเสร็จสมบูรณ์ ซึ่งหมายความว่าเราไม่สามารถยิงอย่างรวดเร็วบนปุ่มกดได้
- อาจมีเสียงรบกวนในปุ่มกดเอง
- ฯลฯ…
ดังนั้น แม้ว่าเราจะจัดการเพื่อให้แป้นพิมพ์ทำงานได้ และตอนนี้เราสามารถใช้ในแอปพลิเคชันได้โดยใช้ค่าการกดแป้นในลักษณะอื่น แทนที่จะส่งออกไปยังจอแสดงผลของตัววิเคราะห์ มันยังไม่ถูกต้องนักและน่ารำคาญมาก นั่นเป็นเหตุผลที่ฉันคิดว่าวิธีที่ดีที่สุดในการวางสายแผงปุ่มกดคือเพียงแค่ติดแต่ละเอาต์พุตจากแผงปุ่มกดลงในพอร์ตอื่น และตัดสินใจว่าปุ่มใดถูกกดโดยพอร์ตใดที่มองเห็นแรงดันไฟฟ้า ที่ง่าย รวดเร็ว และแม่นยำมาก
อันที่จริง มีเหตุผลเพียงสองประการว่าทำไมคนๆ หนึ่งถึงต้องการขับปุ่มกดในแบบที่เราทำที่นี่:
- ใช้เพียง 2 พินบนไมโครคอนโทรลเลอร์ของเราแทน 8
- เป็นโครงการที่ยอดเยี่ยมในการแสดงแง่มุมต่างๆ ของ ADC บนไมโครคอนโทรลเลอร์ ซึ่งแตกต่างจากสิ่งมาตรฐานที่คุณสามารถหาได้ เช่น การอ่านอุณหภูมิ โพเทนชิโอมิเตอร์ เป็นต้น ฉันต้องการตัวอย่างการอ่านค่าเดี่ยวที่ทริกเกอร์และการทริกเกอร์พินภายนอกโดยอัตโนมัติ แทนที่จะเรียกใช้โหมด CPU-gobbling ฟรี
อย่างไรก็ตาม นี่เป็นแบบฝึกหัดสุดท้ายสำหรับคุณ:
แบบฝึกหัดที่ 6: เขียนตัวจัดการการขัดจังหวะการแปลง ADC ใหม่อีกครั้งเพื่อใช้ตารางค้นหา เช่น. เพื่อทดสอบค่าแอนะล็อกกับรายการแรกในตาราง และถ้ามันใหญ่กว่า ค่านั้นจะส่งกลับจากการขัดจังหวะ หากไม่เป็นเช่นนั้น ค่า Z จะเพิ่มทีละรายการในตารางและแยกย่อยกลับไปที่การทดสอบอีกครั้ง วิธีนี้จะทำให้โค้ดสั้นลงและล้างรูทีนการขัดจังหวะและทำให้ดูดีขึ้น (ฉันจะให้วิธีแก้ปัญหาที่เป็นไปได้ในขั้นตอนต่อไป) แบบฝึกหัดที่ 7: เชื่อมต่อปุ่มกดของคุณกับ 8 พินบนไมโครคอนโทรลเลอร์และเขียนไดรเวอร์อย่างง่ายสำหรับมันและสัมผัสว่ามันดีแค่ไหน คุณนึกถึงวิธีสองสามวิธีในการทำให้วิธีการของเราทำงานได้ดีขึ้นหรือไม่
นั่นคือทั้งหมดสำหรับการกวดวิชานี้ ฉันได้แนบเวอร์ชันสุดท้ายพร้อมพอยน์เตอร์ เมื่อเราเข้าใกล้เป้าหมายสุดท้ายมากขึ้น เราจะใช้แป้นพิมพ์อีกครั้งในบทช่วยสอนที่ 9 เพื่อแสดงวิธีควบคุมการแสดงผลเจ็ดส่วนด้วยแป้นพิมพ์ (และสร้างสิ่งที่น่าสนใจที่ใช้ปุ่มพิเศษบนแป้นพิมพ์ของโทรศัพท์) จากนั้นเราจะทำ เปลี่ยนไปใช้การควบคุมสิ่งต่าง ๆ ด้วยการกดปุ่มแทน (เนื่องจากวิธีการนั้นเหมาะกับผลิตภัณฑ์ขั้นสุดท้ายที่เรากำลังสร้างด้วยบทช่วยสอนเหล่านี้) และเราจะวางแผงปุ่มกดไว้
เจอกันคราวหน้า!
แนะนำ:
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 6: 3 ขั้นตอน
บทช่วยสอน AVR Assembler 6: ยินดีต้อนรับสู่บทช่วยสอน 6! บทช่วยสอนวันนี้จะสั้นซึ่งเราจะพัฒนาวิธีง่ายๆ ในการสื่อสารข้อมูลระหว่าง atmega328p หนึ่งกับอีกพอร์ตหนึ่งโดยใช้สองพอร์ตเชื่อมต่อกัน จากนั้นเราจะนำลูกกลิ้งลูกเต๋าจากบทช่วยสอนที่ 4 และการลงทะเบียน
AVR Assembler บทช่วยสอน 8: 4 ขั้นตอน
AVR Assembler บทช่วยสอน 8: ยินดีต้อนรับสู่บทช่วยสอน 8!ในบทช่วยสอนสั้น ๆ นี้ เราจะเปลี่ยนจากการแนะนำแง่มุมใหม่ๆ ของการเขียนโปรแกรมภาษาแอสเซมบลี เพื่อแสดงวิธีย้ายส่วนประกอบการสร้างต้นแบบของเราไปยัง "พิมพ์แล้ว" แผงวงจร. NS
บทช่วยสอน AVR Assembler 9: 7 ขั้นตอน
บทช่วยสอน AVR Assembler 9: ยินดีต้อนรับสู่บทช่วยสอน 9. วันนี้เราจะแสดงวิธีควบคุมทั้งการแสดงผล 7 ส่วนและการแสดงผล 4 หลักโดยใช้รหัสภาษาแอสเซมบลี ATmega328P และ AVR ในการดำเนินการนี้ เราจะต้องใช้ความหลากหลายในการใช้ stack