ผลต่างระหว่างรุ่นของ "การวัดสัญญาณแอนะล็อกด้วยไมโครคอนโทรลเลอร์"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
แถว 25: แถว 25:
 
# รอจนกระทั่งบิต ADSC มีค่าเป็นลอจิกศูนย์ นั่นหมายถึงกระบวนการแปลงได้เสร็จสิ้นแล้ว
 
# รอจนกระทั่งบิต ADSC มีค่าเป็นลอจิกศูนย์ นั่นหมายถึงกระบวนการแปลงได้เสร็จสิ้นแล้ว
 
# ผลลัพธ์ของการแปลงจะถูกเก็บไว้ในรีจีสเตอร์ ADCL (8 บิตต่ำ) และ ADCH (8 บิตสูง)
 
# ผลลัพธ์ของการแปลงจะถูกเก็บไว้ในรีจีสเตอร์ ADCL (8 บิตต่ำ) และ ADCH (8 บิตสูง)
 +
 +
ค่าที่ได้จากการแปลงจะเป็นตามสูตร
 +
:<math>ADC = \frac{V_{IN} \cdot 1024}{V_{REF}}</math>
 +
โดย <math>V_{IN}</math> คือแรงดันที่ขาแอนะล็อกอินพุทที่ถูกเลือก ส่วน <math>V_{REF}</math> คือแรงดันอ้างอิง ซึ่งเราสามารถเลือกแหล่งแรงดันได้โดยการตั้งค่าที่บิต 6 และ 7 ของรีจีสเตอร์ ADMUX ตัวอย่างฟังก์ชันด้านล่างมีการตั้งแหล่งแรงดันอ้างอิงให้เป็นแรงดันที่ขา AREF ซึ่งต่อเข้ากับ VCC จึงมีแรงดันเท่ากับ 5 โวลท์
  
 
== ฟังก์ชันอ่านสัญญาณแอนะล็อก ==
 
== ฟังก์ชันอ่านสัญญาณแอนะล็อก ==

รุ่นแก้ไขเมื่อ 16:12, 28 สิงหาคม 2552

สัญญาณแอนะล็อกและการบันทึกค่า

ตัวอย่างสัญญาณแอนะล็อก

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

การบันทึกข้อมูลแบบดิจิทัล 2 ระดับ (1 บิต)

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

การบันทึกข้อมูลแบบดิจิทัล 1024 ระดับ (10 บิต)

จะเห็นว่าการตีความสัญญาณแอนะล็อกด้วยดิจิทัลลอจิกเพียงสองระดับนั้นทำให้การอ่านค่าสัญญาณมีความหยาบมาก แต่หากเราใช้ขนาดของข้อมูลที่มากกว่า 1 บิตระดับของการตีความก็จะมากขึ้นตามไปด้วยเป็นทวีคูณ ตัวอย่างที่เห็นในรูปเป็นการตีความสัญญาณแอนะล็อกด้วยข้อมูลดิจิทัลขนาด 10 บิต (1024 ระดับ)

ไมโครคอนโทรลเลอร์ส่วนใหญ่มักมีวงจรแปลงสัญญาณแอนะล็อกเป็นดิจิทัลอยู่ภายในตัวเรียบร้อยแล้ว ไมโครคอนโทรลเลอร์ ATMega168 ที่เราใช้ก็เช่นกัน ภายในชิปจะมีวงจรแปลงสัญญาณแอนะล็อกเป็นข้อมูลดิจิทัลขนาด 10 บิตที่เขียนโปรแกรมเรียกใช้งานได้ทันที

วงจรแปลงสัญญาณแอนะล็อกเป็นดิจิทัล 10 บิตของ ATMega168

ไมโครคอนโทรลเลอร์เบอร์ ATMega168 รุ่นที่เป็นขา DIP 28 ขานั้นสามารถประมวลผลอินพุทที่เป็นสัญญาณแอนะล็อกผ่านทางขา ADC0 ถึง ADC5 (ซึ่งคือขา PC0 ถึง PC5) เท่านั้น กระบวนการทำงานของการแปลงสัญญาณแอนะล็อกเป็นข้อมูลดิจิทัลเป็นดังรูปด้านล่าง

Adc-block.png

ภายในชิป ATMega168 นั้นจะมีมอดูลแปลงสัญญาณแอนะล็อกเป็นดิจิทัลเพียงแค่ชุดเดียว ดังนั้นกระบวนการเรียกใช้งานจึงมีขั้นตอนดังนี้

  1. กำหนดค่าให้กับมัลติเพล็กเซอร์ในชิปว่าต้องการดึงสัญญาณอินพุทจากขาใด (ADC0..ADC5) มาป้อนเข้ากับวงจรแปลงสัญญาณฯ ค่าดังกล่าวต้องถูกเซ็ตให้กับบิต 3..0 ของรีจีสเตอร์ ADMUX
  2. สั่งเปิดการใช้งานวงจรแปลงสัญญาณฯ โดยส่งลอจิก 1 ไปที่บิต ADEN (ADC Enable - บิต 7) ของรีจีสเตอร์ ADCSRA
  3. สั่งให้วงจรแปลงสัญญาณฯ เริ่มกระบวนการแปลง โดยส่งลอจิก 1 ไปที่บิต ADSC (ADC Start Conversion - บิต 6) ของรีจีสเตอร์ ADCSRA
  4. รอจนกระทั่งบิต ADSC มีค่าเป็นลอจิกศูนย์ นั่นหมายถึงกระบวนการแปลงได้เสร็จสิ้นแล้ว
  5. ผลลัพธ์ของการแปลงจะถูกเก็บไว้ในรีจีสเตอร์ ADCL (8 บิตต่ำ) และ ADCH (8 บิตสูง)

ค่าที่ได้จากการแปลงจะเป็นตามสูตร

โดย คือแรงดันที่ขาแอนะล็อกอินพุทที่ถูกเลือก ส่วน คือแรงดันอ้างอิง ซึ่งเราสามารถเลือกแหล่งแรงดันได้โดยการตั้งค่าที่บิต 6 และ 7 ของรีจีสเตอร์ ADMUX ตัวอย่างฟังก์ชันด้านล่างมีการตั้งแหล่งแรงดันอ้างอิงให้เป็นแรงดันที่ขา AREF ซึ่งต่อเข้ากับ VCC จึงมีแรงดันเท่ากับ 5 โวลท์

ฟังก์ชันอ่านสัญญาณแอนะล็อก

เพื่อความสะดวก เราจะสร้างฟังก์ชัน read_adc ขึ้นมาจากกระบวนการข้างต้น ฟังก์ชันนี้รับพารามิเตอร์เป็นหมายเลขขาของพอร์ท C จากนั้นจึงคืนค่าสัญญาณแอนะล็อกที่อ่านได้และแปลงเป็นข้อมูลดิจิทัล 10 บิตเรียบร้อยแล้วกลับออกมา

ฟังก์ชันนี้ถือว่าพารามิเตอร์ channel มีค่าไม่เกิน 4 บิต (0-15) จึงนำไป or เข้ากับรีจีสเตอร์ ADMUX โดยตรง หากมีการส่งค่ามาใน channel มากกว่านี้อาจมีผลกระทบกับบิตอื่น ๆ ของรีจีสเตอร์ ADMUX ซึ่งทำให้กระบวนการทำงานของวงจรแปลงสัญญาณแอนะล็อกผิดพลาดไปได้

uint16_t read_adc(uint8_t channel)
{
    ADMUX = 0b01000000; // เลือกใช้แรงดันอ้างอิงจากขา AREF
    ADMUX |= channel;   // ตั้ง MUX ให้ชี้ไปยัง channel
    ADCSRA = 0b11000110;
    //         ||   -+-
    //         ||    |
    //         ||    +-> ปรับคล็อกของ ADC ให้เป็น 1/64 ของคล็อกระบบ
    //         |+->เริ่มแปลงค่าแอนะล็อกเป็นดิจิทัล
    //         |
    //         +-> Enable ADC

    while ((ADCSRA & (1<<ADSC))) // รอจนบิต ADSC (บิต 6) กลายเป็น 0
        ;
    return ADCL + ADCH*256;  // ผลลัพธ์ถูกเก็บอยู่ในรีจีสเตอร์ ADCL และ ADCH
}

บทความที่เกี่ยวข้อง