นี่คือการกวดวิชาที่ 9 ของเราในการ เรียนรู้ไมโครคอนโทรลเลอร์ PIC ใช้ MPLAB XC8 จนถึงตอนนี้เราได้ครอบคลุมบทช่วยสอนพื้นฐานมากมายเช่นการเริ่มต้นใช้งาน MPLABX, ไฟ LED กะพริบพร้อม PIC, ตัวจับเวลาใน PIC, การเชื่อมต่อ LCD, การเชื่อมต่อ 7 ส่วนเป็นต้นหากคุณเป็นผู้เริ่มต้นอย่างแท้จริงโปรดดูรายการบทช่วยสอน PIC ทั้งหมดที่นี่ และเริ่มเรียนรู้
ในบทช่วยสอนนี้เราจะได้เรียนรู้วิธีใช้ ADC กับไมโครคอนโทรลเลอร์ PIC PICF877A ของเรา. โครงการไมโครคอนโทรลเลอร์ส่วนใหญ่จะเกี่ยวข้องกับ ADC (ตัวแปลงอนาล็อกเป็นดิจิตอล) เนื่องจากเป็นวิธีที่ใช้มากที่สุดวิธีหนึ่งในการอ่านข้อมูลจากโลกแห่งความเป็นจริง เซ็นเซอร์เกือบทั้งหมดเช่นเซ็นเซอร์อุณหภูมิเซ็นเซอร์ฟลักซ์เซ็นเซอร์ความดันเซ็นเซอร์กระแสไฟฟ้าเซ็นเซอร์วัดแรงดันลูกข่างเครื่องวัดความเร่งเซ็นเซอร์ระยะทางและเซ็นเซอร์หรือตัวแปลงสัญญาณที่รู้จักเกือบทุกตัวจะสร้างแรงดันไฟฟ้าแบบอะนาล็อก 0V ถึง 5V ตามการอ่านของเซ็นเซอร์ ตัวอย่างเช่นเซ็นเซอร์อุณหภูมิอาจให้ 2.1V เมื่ออุณหภูมิ 25C และสูงถึง 4.7 เมื่ออุณหภูมิ 60C เพื่อให้ทราบอุณหภูมิของโลกแห่งความเป็นจริง MCU จะต้องอ่านแรงดันขาออกของเซ็นเซอร์อุณหภูมินี้และเชื่อมโยงกับอุณหภูมิโลกแห่งความเป็นจริง ดังนั้น ADC จึงเป็นเครื่องมือในการทำงานที่สำคัญสำหรับโปรเจ็กต์ MCU และมาเรียนรู้วิธีใช้งานบน PIC16F877A ของเรา
ตรวจสอบบทความก่อนหน้าของเราเกี่ยวกับการใช้ ADC ในไมโครคอนโทรลเลอร์อื่น ๆ:
- วิธีใช้ ADC ใน Arduino Uno
- การสอน Raspberry Pi ADC
- การเชื่อมต่อ ADC0808 กับไมโครคอนโทรลเลอร์ 8051
ADC ในไมโครคอนโทรลเลอร์ PIC PIC16F877A:
ADC มีให้เลือกหลายประเภทและแต่ละประเภทมีความเร็วและความละเอียดของตัวเอง ADC ประเภทที่พบบ่อยที่สุด ได้แก่ แฟลชการประมาณต่อเนื่องและซิกม่าเดลต้า ประเภทของ ADC ใช้ใน PIC16F877A จะเรียกว่าเป็น ADC ประมาณเนื่องหรือ SAR ในระยะสั้น มาเรียนรู้เกี่ยวกับ SAR ADC กันก่อนที่จะเริ่มใช้งาน
ADC ประมาณแบบต่อเนื่อง: SAR ADC ทำงานโดยใช้ความช่วยเหลือของตัวเปรียบเทียบและการสนทนาเชิงตรรกะ ADC ประเภทนี้ใช้แรงดันอ้างอิง (ซึ่งเป็นตัวแปร) และเปรียบเทียบแรงดันไฟฟ้าขาเข้ากับแรงดันอ้างอิงโดยใช้ตัวเปรียบเทียบและความแตกต่างซึ่งจะเป็นเอาต์พุตดิจิตอลจะถูกบันทึกจากบิตที่สำคัญที่สุด (MSB) ความเร็วของการเปรียบเทียบขึ้นอยู่กับความถี่สัญญาณนาฬิกา (Fosc) ที่ PIC ทำงาน
ตอนนี้เรารู้พื้นฐานบางอย่างเกี่ยวกับ ADC แล้วให้เปิดแผ่นข้อมูลของเราและเรียนรู้วิธีใช้ ADC บน PIC16F877A MCU ของเรา PIC ที่เราใช้มี 10-bit 8-channel ADC ซึ่งหมายความว่าค่าเอาต์พุตของ ADC ของเราจะเป็น 0-1024 (2 ^ 10) และมี 8 พิน (ช่อง) บน MCU ของเราซึ่งสามารถอ่านแรงดันไฟฟ้าแบบอะนาล็อกได้ ค่า 1024 ได้มาโดย 2 ^ 10 เนื่องจาก ADC ของเราคือ 10 บิต หมุดแปดตัวที่สามารถอ่านแรงดันไฟฟ้าแบบอะนาล็อกจะกล่าวถึงในแผ่นข้อมูล ลองดูภาพด้านล่าง
ช่องอนาล็อก AN0 ถึง AN7 ถูกไฮไลต์ไว้สำหรับคุณ เฉพาะพินเหล่านี้เท่านั้นที่จะสามารถอ่านแรงดันไฟฟ้าแบบอนาล็อกได้ ดังนั้นก่อนที่จะอ่านแรงดันไฟฟ้าขาเข้าเราต้องระบุในรหัสของเราว่าต้องใช้ช่องใดในการอ่านแรงดันไฟฟ้าขาเข้า ในบทช่วยสอนนี้เราจะใช้ช่อง 4 กับโพเทนชิออมิเตอร์เพื่ออ่านแรงดันไฟฟ้าอะนาล็อกที่ช่องนี้
โมดูล A / D มีรีจิสเตอร์สี่ตัวซึ่งต้องกำหนดค่าเพื่ออ่านข้อมูลจากพินอินพุต การลงทะเบียนเหล่านี้คือ:
• A / D ผลการลงทะเบียนสูง (ADRESH)
• A / D ผลการลงทะเบียนต่ำ (ADRESL)
•ทะเบียนควบคุม A / D 0 (ADCON0)
•ทะเบียนควบคุม A / D 1 (ADCON1)
การเขียนโปรแกรมสำหรับ ADC:
โปรแกรมสำหรับใช้กับ ADC PIC ไมโครคอนโทรลเลอร์เป็นเรื่องง่ายมากเราก็ต้องเข้าใจทั้งสี่คนนี้ลงทะเบียนแล้วอ่านแรงดันไฟฟ้าแบบอนาล็อกใด ๆ จะง่าย ตามปกติเริ่มต้นบิตการกำหนดค่าและเริ่มต้นด้วย void main ()
ภายใน หลักเป็นโมฆะ () เรามีการเริ่มต้น ADC ของเราโดยใช้การลงทะเบียน ADCON1 และ ADCON0 ลงทะเบียน การลงทะเบียน ADCON0 มีบิตต่อไปนี้:
ในการลงทะเบียนนี้เราต้องเปิดโมดูล ADC โดยสร้าง ADON = 1 และเปิด A / D Conversion Clock โดยใช้บิต ADCS1 และ ADCS0 ส่วนที่เหลือจะไม่ได้รับการตั้งค่าในตอนนี้ ในโปรแกรมของเรานาฬิกาแปลง A / D ถูกเลือกเป็น Fosc / 16 คุณสามารถลองความถี่ของคุณเองและดูว่าผลลัพธ์เปลี่ยนแปลงไปอย่างไร รายละเอียดที่สมบูรณ์มีอยู่ในหน้าของแผ่นข้อมูล 127 ดังนั้น ADCON0 จะเริ่มต้นดังต่อไปนี้
ADCON0 = 0b01000001;
ตอนนี้การลงทะเบียน ADCON1 มีบิตต่อไปนี้:
ในการลงทะเบียนนี้เราต้องสร้างรูปแบบผลลัพธ์ A / D เลือกบิตสูงโดย ADFM = 1 และทำให้ ADCS2 = 1 เพื่อเลือก Fosc / 16 อีกครั้ง ส่วนบิตอื่น ๆ ยังคงเป็นศูนย์เนื่องจากเราได้วางแผนที่จะใช้แรงดันอ้างอิงภายใน รายละเอียดที่สมบูรณ์มีอยู่ในแผ่นข้อมูลหน้า 128 ดังนั้น ADCON1 เราจะตั้งค่าดังนี้
ADCON1 = 0x11000000;
หลังจากเริ่มต้นโมดูล ADC ภายในฟังก์ชันหลักของเราแล้วให้เข้าสู่ while loop และเริ่มอ่านค่า ADC หากต้องการอ่านค่า ADC ขั้นตอนต่อไปจะต้องมีการติดตาม
- เริ่มต้นโมดูล ADC
- เลือกช่องอนาล็อก
- เริ่ม ADC โดยทำให้ Go / Done สูง
- รอให้บิต Go / DONE ต่ำลง
- รับผลลัพธ์ ADC จาก ADRESH และ ADRESL register
1. เริ่มต้นโมดูล ADC:เราได้เรียนรู้วิธีการเริ่มต้น ADC แล้วดังนั้นเราจึงเรียกสิ่งนี้ว่าฟังก์ชันด้านล่างนี้เพื่อเริ่มต้น ADC
ฟังก์ชัน void ADC_Initialize () เป็นดังนี้
โมฆะ ADC_Initialize () {ADCON0 = 0b01000001; // ADC ON และ Fosc / 16 ถูกเลือก ADCON1 = 0b11000000; // เลือกแรงดันอ้างอิงภายใน}
2. เลือกช่องอนาล็อก:ตอนนี้เราต้องเลือกช่องที่เราจะใช้เพื่ออ่านค่า ADC มาสร้างฟังก์ชันสำหรับสิ่งนี้เพื่อที่เราจะเปลี่ยนระหว่างแต่ละช่องภายในลูป while ได้ง่าย
ADC_Read int ที่ไม่ได้ลงชื่อ (ช่องถ่านที่ไม่ได้ลงชื่อ) {// **** การเลือกช่อง ** /// ADCON0 & = 0x11000101; // การล้าง Bits การเลือกช่อง ADCON0 - = channel << 3; // การตั้งค่า Bits ที่ต้องการ // ** การเลือกช่องเสร็จสมบูรณ์ *** ///}
จากนั้นช่องที่จะเลือกจะได้รับภายในช่องตัวแปร ในบรรทัด
ADCON0 & = 0x1100101;
การเลือกช่องก่อนหน้า (ถ้ามี) จะถูกล้าง ซึ่งทำได้โดยใช้บิตและโอเปอเรเตอร์“ &” บิต 3, 4 และ 5 ถูกบังคับให้เป็น 0 ในขณะที่บิตอื่น ๆ ถูกปล่อยให้อยู่ในค่าก่อนหน้า
จากนั้นช่องที่ต้องการจะถูกเลือกโดยการเลื่อนหมายเลขช่องไปทางซ้ายสามครั้งและตั้งค่าบิตโดยใช้บิตหรือโอเปอเรเตอร์“ -”
ADCON0 - = ช่อง << 3; // การตั้งค่า Bits ที่ต้องการ
3. เริ่ม ADC โดยทำให้ Go / Done สูงขึ้นเล็กน้อย:เมื่อเลือกช่องสัญญาณแล้วเราจะต้องเริ่มการแปลง ADC โดยทำให้บิต GO_nDONE สูง
GO_nDONE = 1; // เริ่มต้นการแปลง A / D
4. รอให้บิต Go / DONE ต่ำลง: บิต GO / DONE จะอยู่ในระดับสูงจนกว่าการแปลง ADC จะเสร็จสมบูรณ์ดังนั้นเราต้องรอจนกว่าบิตนี้จะต่ำอีกครั้ง ซึ่งสามารถทำได้โดยใช้ while loop
ในขณะที่ (GO_nDONE); // รอให้การแปลง A / D เสร็จสมบูรณ์
5. รับผลลัพธ์ ADC จากการลงทะเบียน ADRESH และ ADRESL:เมื่อบิต Go / DONE ต่ำลงอีกครั้งหมายความว่าการแปลง ADC เสร็จสมบูรณ์ ผลลัพธ์ของ ADC จะเป็นค่า 10 บิต เนื่องจาก MCU ของเราเป็น MCU 8 บิตผลลัพธ์จึงถูกแบ่งออกเป็น 8 บิตบนและ 2 บิตล่าง ผลลัพธ์ 8 บิตบนจะถูกเก็บไว้ในรีจิสเตอร์ ADRESH และ 2 บิตล่างจะถูกเก็บไว้ในรีจิสเตอร์ ADRESL ดังนั้นเราต้องเพิ่มสิ่งเหล่านี้ในการลงทะเบียนเพื่อรับค่า ADC 10 บิตของเรา ผลลัพธ์นี้ส่งคืนโดยฟังก์ชันดังที่แสดงด้านล่าง:
กลับ ((ADRESH << 8) + ADRESL); // ส่งคืนผลลัพธ์
ฟังก์ชั่นที่สมบูรณ์ซึ่งใช้ในการเลือกช่อง ADC ทริกเกอร์ ADC และส่งคืนผลลัพธ์จะแสดงที่นี่
ADC_Read int ที่ไม่ได้ลงชื่อ (ช่องถ่านที่ไม่ได้ลงชื่อ) {ADCON0 & = 0x11000101; // การล้าง Bits การเลือกช่อง ADCON0 - = channel << 3; // การตั้งค่า Bits __delay_ms ที่ต้องการ (2); // เวลาในการได้มาเพื่อชาร์จตัวเก็บประจุ GO_nDONE = 1; // เริ่มต้นการแปลง A / D ในขณะที่ (GO_nDONE); // รอให้การแปลง A / D กลับมาสมบูรณ์ ((ADRESH << 8) + ADRESL); // ส่งคืนผลลัพธ์}
ตอนนี้เรามีฟังก์ชั่นที่จะใช้การเลือกช่องเป็นอินพุตและส่งคืนค่า ADC ให้เรา ดังนั้นเราจึงสามารถเรียกใช้ฟังก์ชันนี้ได้โดยตรงภายใน while loop ของเราเนื่องจากเรากำลังอ่านแรงดันอนาล็อกจากช่อง 4 ในบทช่วยสอนนี้การเรียกใช้ฟังก์ชันจะเป็นดังนี้
ผม = (ADC_Read (4)); // เก็บผลลัพธ์ของ adc ไว้ใน“ i”
เพื่อให้เห็นภาพผลลัพธ์ของ ADC ของเราเราจำเป็นต้องมีโมดูลการแสดงผลบางประเภทเช่น LCD หรือ 7-segment ในบทช่วยสอนนี้เรากำลังใช้การแสดงผล 7 ส่วนเพื่อตรวจสอบผลลัพธ์ หากคุณต้องการทราบวิธีใช้ 7-segment กับ pic ให้ทำตามบทแนะนำที่นี่
รหัสที่สมบูรณ์ ได้รับด้านล่างและกระบวนการที่ยังจะมีการอธิบายใน วิดีโอ ที่สิ้นสุด
การติดตั้งและทดสอบฮาร์ดแวร์:
ตามปกติจำลองรหัสโดยใช้ Proteus ก่อนที่จะไปกับฮาร์ดแวร์ของเราจริงแผนผังของโครงการแสดงไว้ด้านล่าง:
การเชื่อมต่อของโมดูลการแสดงผลเจ็ดส่วน 4 หลักกับไมโครคอนโทรลเลอร์ PIC นั้นเหมือนกับโครงการก่อนหน้านี้เราเพิ่งเพิ่มโพเทนชิออมิเตอร์ไปที่พิน 7 ซึ่งเป็นช่องอนาล็อก 4 โดยการเปลี่ยนหม้อแรงดันไฟฟ้าที่แปรผันจะถูกส่งไปยัง MCU ซึ่งจะถูกอ่านโดยโมดูล ADC และแสดงบนโมดูลการแสดงผล 7 ส่วน ตรวจสอบบทช่วยสอนก่อนหน้านี้เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับการแสดงผล 7 ส่วน 4 หลักและการเชื่อมต่อกับ PIC MCU
ที่นี่เราได้ใช้บอร์ดไมโครคอนโทรลเลอร์ PICเดียวกันกับ ที่เราสร้างขึ้นในบทแนะนำการกระพริบ LED หลังจากตรวจสอบการเชื่อมต่อแล้วให้อัปโหลดโปรแกรมไปยัง PIC และคุณจะเห็นผลลัพธ์เช่นนี้
ที่นี่เราได้อ่านค่า ADC จากหม้อและแปลงเป็นแรงดันไฟฟ้าจริงโดยการทำแผนที่เอาต์พุต 0-1024 เป็น 0-5 โวลต์ (ดังแสดงในโปรแกรม) จากนั้นค่าจะแสดงบน 7 ส่วนและตรวจสอบโดยใช้มัลติมิเตอร์
ตอนนี้เราพร้อมที่จะใช้เซ็นเซอร์อนาล็อกทั้งหมดที่มีอยู่ในตลาดแล้วลองทำดูและหากคุณมีปัญหาใด ๆ ตามปกติให้ใช้ส่วนความคิดเห็นเรายินดีที่จะช่วยเหลือคุณ