ผลต่างระหว่างรุ่นของ "การวัดสัญญาณแอนะล็อกด้วยไมโครคอนโทรลเลอร์"
Chaiporn (คุย | มีส่วนร่วม) |
Jittat (คุย | มีส่วนร่วม) |
||
(ไม่แสดง 16 รุ่นระหว่างกลางโดยผู้ใช้ 3 คน) | |||
แถว 1: | แถว 1: | ||
+ | : ''วิกินี้เป็นส่วนหนึ่งของรายวิชา [[01204223]]'' | ||
+ | |||
== สัญญาณแอนะล็อกและการบันทึกค่า == | == สัญญาณแอนะล็อกและการบันทึกค่า == | ||
− | |||
[[Image:analog-signal.png|150px|thumb|ตัวอย่างสัญญาณแอนะล็อก]] | [[Image:analog-signal.png|150px|thumb|ตัวอย่างสัญญาณแอนะล็อก]] | ||
+ | ข้อมูลที่อ่านจากสภาพแวดล้อมบ่อยครั้งมักจะอยู่ในรูปข้อมูลต่อเนื่อง (continuous data) หรือข้อมูลแอนะล็อก (analog data) ตัวอย่างข้อมูลลักษณะนี้ในชีวิตประจำวันได้แค่อุณหภูมิ ความสว่างของห้อง ความเร็วรถยนต์ น้ำหนัก ส่วนสูง ฯลฯ เมื่อข้อมูลนี้ถูกเปลี่ยนให้เป็นรูปสัญญาณ (เช่นแรงดันไฟฟ้า) เพื่อให้สามารถอ่านและประมวลผลได้โดยวงจรอิเล็คทรอนิคส์หรือไมโครคอนโทรลเลอร์ จะถูกเรียกว่าเป็น [http://en.wikipedia.org/wiki/Analog_signal สัญญาณแอนะล็อก (analog signal)] ดังแสดงในรูปด้านข้าง | ||
+ | <br style="clear: both"/> | ||
+ | [[Image:2-level.png|150px|thumb|การบันทึกข้อมูลแบบดิจิทัล 2 ระดับ (1 บิต)]] | ||
อย่างไรก็ตาม หากเรานำเอาสัญญาณเหล่านี้ป้อนให้กับขาดิจิทัลอินพุทของไมโครคอนโทรลเลอร์ ตัวสัญญาณจะถูกตีความเป็นสองระดับ คือลอจิก 0 หรือ 1 เท่านั้น นั่นหมายถึงถ้าสัญญาณมีค่าแรงดันสูงกว่าค่าหนึ่ง ไมโครคอนโทรลเลอร์จะตีความอินพุทเป็นลอจิก 1 และหากสัญญาณมีแรงดันต่ำกว่านั้นก็จะถูกตีความเป็นลอจิก 0 ดังแสดงในตัวอย่าง | อย่างไรก็ตาม หากเรานำเอาสัญญาณเหล่านี้ป้อนให้กับขาดิจิทัลอินพุทของไมโครคอนโทรลเลอร์ ตัวสัญญาณจะถูกตีความเป็นสองระดับ คือลอจิก 0 หรือ 1 เท่านั้น นั่นหมายถึงถ้าสัญญาณมีค่าแรงดันสูงกว่าค่าหนึ่ง ไมโครคอนโทรลเลอร์จะตีความอินพุทเป็นลอจิก 1 และหากสัญญาณมีแรงดันต่ำกว่านั้นก็จะถูกตีความเป็นลอจิก 0 ดังแสดงในตัวอย่าง | ||
− | + | <br style="clear: both"/> | |
+ | [[Image:1024-level.png|150px|thumb|การบันทึกข้อมูลแบบดิจิทัล 1024 ระดับ (10 บิต)]] | ||
จะเห็นว่าการตีความสัญญาณแอนะล็อกด้วยดิจิทัลลอจิกเพียงสองระดับนั้นทำให้การอ่านค่าสัญญาณมีความหยาบมาก แต่หากเราใช้ขนาดของข้อมูลที่มากกว่า 1 บิตระดับของการตีความก็จะมากขึ้นตามไปด้วยเป็นทวีคูณ ตัวอย่างที่เห็นในรูปเป็นการตีความสัญญาณแอนะล็อกด้วยข้อมูลดิจิทัลขนาด 10 บิต (1024 ระดับ) | จะเห็นว่าการตีความสัญญาณแอนะล็อกด้วยดิจิทัลลอจิกเพียงสองระดับนั้นทำให้การอ่านค่าสัญญาณมีความหยาบมาก แต่หากเราใช้ขนาดของข้อมูลที่มากกว่า 1 บิตระดับของการตีความก็จะมากขึ้นตามไปด้วยเป็นทวีคูณ ตัวอย่างที่เห็นในรูปเป็นการตีความสัญญาณแอนะล็อกด้วยข้อมูลดิจิทัลขนาด 10 บิต (1024 ระดับ) | ||
− | + | <br style="clear: both"/> | |
ไมโครคอนโทรลเลอร์ส่วนใหญ่มักมีวงจรแปลงสัญญาณแอนะล็อกเป็นดิจิทัลอยู่ภายในตัวเรียบร้อยแล้ว ไมโครคอนโทรลเลอร์ ATMega168 ที่เราใช้ก็เช่นกัน ภายในชิปจะมีวงจรแปลงสัญญาณแอนะล็อกเป็นข้อมูลดิจิทัลขนาด 10 บิตที่เขียนโปรแกรมเรียกใช้งานได้ทันที | ไมโครคอนโทรลเลอร์ส่วนใหญ่มักมีวงจรแปลงสัญญาณแอนะล็อกเป็นดิจิทัลอยู่ภายในตัวเรียบร้อยแล้ว ไมโครคอนโทรลเลอร์ ATMega168 ที่เราใช้ก็เช่นกัน ภายในชิปจะมีวงจรแปลงสัญญาณแอนะล็อกเป็นข้อมูลดิจิทัลขนาด 10 บิตที่เขียนโปรแกรมเรียกใช้งานได้ทันที | ||
แถว 17: | แถว 22: | ||
ภายในชิป ATMega168 นั้นจะมีมอดูลแปลงสัญญาณแอนะล็อกเป็นดิจิทัลเพียงแค่ชุดเดียว ดังนั้นกระบวนการเรียกใช้งานจึงมีขั้นตอนดังนี้ | ภายในชิป ATMega168 นั้นจะมีมอดูลแปลงสัญญาณแอนะล็อกเป็นดิจิทัลเพียงแค่ชุดเดียว ดังนั้นกระบวนการเรียกใช้งานจึงมีขั้นตอนดังนี้ | ||
− | # กำหนดค่าให้กับมัลติเพล็กเซอร์ในชิปว่าต้องการดึงสัญญาณอินพุทจากขาใด (ADC0..ADC5) | + | # กำหนดค่าให้กับมัลติเพล็กเซอร์ในชิปว่าต้องการดึงสัญญาณอินพุทจากขาใด (ADC0..ADC5) มาป้อนเข้ากับวงจรแปลงสัญญาณฯ ค่าดังกล่าวต้องถูกเซ็ตให้กับบิต 3..0 ของรีจีสเตอร์ ADMUX |
− | # สั่งเปิดการใช้งานวงจรแปลงสัญญาณฯ | + | # สั่งเปิดการใช้งานวงจรแปลงสัญญาณฯ โดยส่งลอจิก 1 ไปที่บิต ADEN (ADC Enable - บิต 7) ของรีจีสเตอร์ ADCSRA |
− | # สั่งให้วงจรแปลงสัญญาณฯ เริ่มกระบวนการแปลง | + | # สั่งให้วงจรแปลงสัญญาณฯ เริ่มกระบวนการแปลง โดยส่งลอจิก 1 ไปที่บิต ADSC (ADC Start Conversion - บิต 6) ของรีจีสเตอร์ ADCSRA |
− | # รอจนกระทั่งบิต ADSC | + | # รอจนกระทั่งบิต ADSC มีค่าเป็นลอจิกศูนย์ นั่นหมายถึงกระบวนการแปลงได้เสร็จสิ้นแล้ว |
− | # ผลลัพธ์ของการแปลงจะถูกเก็บไว้ในรีจีสเตอร์ ADCL (8 บิตต่ำ) และ ADCH (8 บิตสูง) | + | # ผลลัพธ์ของการแปลงจะถูกเก็บไว้ในรีจีสเตอร์ ADCL (8 บิตต่ำ) และ ADCH (8 บิตสูง) <span style="color: red;">เพื่อให้การอ่านค่าเป็นไปได้อย่างถูกต้องตามกลไกของไมโครคอนโทรลเลอร์ ค่าในรีจีสเตอร์ ADCL ต้องถูกอ่านออกมาก่อน ADCH</span> |
+ | ค่าที่ได้จากการแปลงจะเป็นตามสูตร | ||
+ | :<math>ADC = \frac{V_{IN} \cdot 1024}{V_{REF}}</math> | ||
+ | โดย <math>V_{IN}</math> คือแรงดันที่ขาแอนะล็อกอินพุทที่ถูกเลือก ส่วน <math>V_{REF}</math> คือแรงดันอ้างอิง ซึ่งเราสามารถเลือกแหล่งแรงดันได้โดยการตั้งค่าที่บิต 6 และ 7 ของรีจีสเตอร์ ADMUX ตัวอย่างฟังก์ชันด้านล่างมีการตั้งแหล่งแรงดันอ้างอิงให้เป็นแรงดันที่ขา AREF ซึ่งต่อเข้ากับ VCC จึงมีแรงดันเท่ากับ 5 โวลท์ | ||
== ฟังก์ชันอ่านสัญญาณแอนะล็อก == | == ฟังก์ชันอ่านสัญญาณแอนะล็อก == | ||
เพื่อความสะดวก เราจะสร้างฟังก์ชัน <code>read_adc</code> ขึ้นมาจากกระบวนการข้างต้น ฟังก์ชันนี้รับพารามิเตอร์เป็นหมายเลขขาของพอร์ท C จากนั้นจึงคืนค่าสัญญาณแอนะล็อกที่อ่านได้และแปลงเป็นข้อมูลดิจิทัล 10 บิตเรียบร้อยแล้วกลับออกมา | เพื่อความสะดวก เราจะสร้างฟังก์ชัน <code>read_adc</code> ขึ้นมาจากกระบวนการข้างต้น ฟังก์ชันนี้รับพารามิเตอร์เป็นหมายเลขขาของพอร์ท C จากนั้นจึงคืนค่าสัญญาณแอนะล็อกที่อ่านได้และแปลงเป็นข้อมูลดิจิทัล 10 บิตเรียบร้อยแล้วกลับออกมา | ||
− | + | <syntaxhighlight lang="C"> | |
− | + | uint16_t read_adc(uint8_t channel) | |
− | + | { | |
− | + | ADMUX = (0<<REFS1)|(1<<REFS0) // ระบุให้ใช้ VCC เป็นแรงดันอ้างอิง (Vref) และ | |
− | + | | (0<<ADLAR) // บันทึกผลลัพธ์ชิดขวาในคู่รีจีสเตอร์ ADCH/ADCL | |
− | + | | (channel & 0b1111); // ตั้งค่า MUX เป็นค่า channel | |
− | + | ||
− | + | ADCSRA = (1<<ADEN) // เปิดวงจร ADC | |
− | + | | (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) // ใช้ความเร็ว 1/128 ของคล็อกระบบ | |
− | + | | (1<<ADSC); // สั่งวงจร ADC ให้เริ่มต้นการแปลง | |
− | + | ||
− | + | while ((ADCSRA & (1<<ADSC))) // รอจนบิต ADSC กลายเป็น 0 ซึ่งหมายถึงการแปลงเสร็จสิ้น | |
− | + | ; | |
− | + | ||
− | + | return ADCL + ADCH*256; // ผลลัพธ์ถูกเก็บอยู่ในรีจีสเตอร์ ADCL และ ADCH | |
− | + | // สามารถใช้ return ADC ได้เช่นกัน | |
+ | } | ||
+ | </syntaxhighlight> | ||
== บทความที่เกี่ยวข้อง == | == บทความที่เกี่ยวข้อง == |
รุ่นแก้ไขปัจจุบันเมื่อ 17:59, 12 กุมภาพันธ์ 2563
- วิกินี้เป็นส่วนหนึ่งของรายวิชา 01204223
เนื้อหา
สัญญาณแอนะล็อกและการบันทึกค่า
ข้อมูลที่อ่านจากสภาพแวดล้อมบ่อยครั้งมักจะอยู่ในรูปข้อมูลต่อเนื่อง (continuous data) หรือข้อมูลแอนะล็อก (analog data) ตัวอย่างข้อมูลลักษณะนี้ในชีวิตประจำวันได้แค่อุณหภูมิ ความสว่างของห้อง ความเร็วรถยนต์ น้ำหนัก ส่วนสูง ฯลฯ เมื่อข้อมูลนี้ถูกเปลี่ยนให้เป็นรูปสัญญาณ (เช่นแรงดันไฟฟ้า) เพื่อให้สามารถอ่านและประมวลผลได้โดยวงจรอิเล็คทรอนิคส์หรือไมโครคอนโทรลเลอร์ จะถูกเรียกว่าเป็น สัญญาณแอนะล็อก (analog signal) ดังแสดงในรูปด้านข้าง
อย่างไรก็ตาม หากเรานำเอาสัญญาณเหล่านี้ป้อนให้กับขาดิจิทัลอินพุทของไมโครคอนโทรลเลอร์ ตัวสัญญาณจะถูกตีความเป็นสองระดับ คือลอจิก 0 หรือ 1 เท่านั้น นั่นหมายถึงถ้าสัญญาณมีค่าแรงดันสูงกว่าค่าหนึ่ง ไมโครคอนโทรลเลอร์จะตีความอินพุทเป็นลอจิก 1 และหากสัญญาณมีแรงดันต่ำกว่านั้นก็จะถูกตีความเป็นลอจิก 0 ดังแสดงในตัวอย่าง
จะเห็นว่าการตีความสัญญาณแอนะล็อกด้วยดิจิทัลลอจิกเพียงสองระดับนั้นทำให้การอ่านค่าสัญญาณมีความหยาบมาก แต่หากเราใช้ขนาดของข้อมูลที่มากกว่า 1 บิตระดับของการตีความก็จะมากขึ้นตามไปด้วยเป็นทวีคูณ ตัวอย่างที่เห็นในรูปเป็นการตีความสัญญาณแอนะล็อกด้วยข้อมูลดิจิทัลขนาด 10 บิต (1024 ระดับ)
ไมโครคอนโทรลเลอร์ส่วนใหญ่มักมีวงจรแปลงสัญญาณแอนะล็อกเป็นดิจิทัลอยู่ภายในตัวเรียบร้อยแล้ว ไมโครคอนโทรลเลอร์ ATMega168 ที่เราใช้ก็เช่นกัน ภายในชิปจะมีวงจรแปลงสัญญาณแอนะล็อกเป็นข้อมูลดิจิทัลขนาด 10 บิตที่เขียนโปรแกรมเรียกใช้งานได้ทันที
วงจรแปลงสัญญาณแอนะล็อกเป็นดิจิทัล 10 บิตของ ATMega168
ไมโครคอนโทรลเลอร์เบอร์ ATMega168 รุ่นที่เป็นขา DIP 28 ขานั้นสามารถประมวลผลอินพุทที่เป็นสัญญาณแอนะล็อกผ่านทางขา ADC0 ถึง ADC5 (ซึ่งคือขา PC0 ถึง PC5) เท่านั้น กระบวนการทำงานของการแปลงสัญญาณแอนะล็อกเป็นข้อมูลดิจิทัลเป็นดังรูปด้านล่าง
ภายในชิป ATMega168 นั้นจะมีมอดูลแปลงสัญญาณแอนะล็อกเป็นดิจิทัลเพียงแค่ชุดเดียว ดังนั้นกระบวนการเรียกใช้งานจึงมีขั้นตอนดังนี้
- กำหนดค่าให้กับมัลติเพล็กเซอร์ในชิปว่าต้องการดึงสัญญาณอินพุทจากขาใด (ADC0..ADC5) มาป้อนเข้ากับวงจรแปลงสัญญาณฯ ค่าดังกล่าวต้องถูกเซ็ตให้กับบิต 3..0 ของรีจีสเตอร์ ADMUX
- สั่งเปิดการใช้งานวงจรแปลงสัญญาณฯ โดยส่งลอจิก 1 ไปที่บิต ADEN (ADC Enable - บิต 7) ของรีจีสเตอร์ ADCSRA
- สั่งให้วงจรแปลงสัญญาณฯ เริ่มกระบวนการแปลง โดยส่งลอจิก 1 ไปที่บิต ADSC (ADC Start Conversion - บิต 6) ของรีจีสเตอร์ ADCSRA
- รอจนกระทั่งบิต ADSC มีค่าเป็นลอจิกศูนย์ นั่นหมายถึงกระบวนการแปลงได้เสร็จสิ้นแล้ว
- ผลลัพธ์ของการแปลงจะถูกเก็บไว้ในรีจีสเตอร์ ADCL (8 บิตต่ำ) และ ADCH (8 บิตสูง) เพื่อให้การอ่านค่าเป็นไปได้อย่างถูกต้องตามกลไกของไมโครคอนโทรลเลอร์ ค่าในรีจีสเตอร์ ADCL ต้องถูกอ่านออกมาก่อน ADCH
ค่าที่ได้จากการแปลงจะเป็นตามสูตร
โดย คือแรงดันที่ขาแอนะล็อกอินพุทที่ถูกเลือก ส่วน คือแรงดันอ้างอิง ซึ่งเราสามารถเลือกแหล่งแรงดันได้โดยการตั้งค่าที่บิต 6 และ 7 ของรีจีสเตอร์ ADMUX ตัวอย่างฟังก์ชันด้านล่างมีการตั้งแหล่งแรงดันอ้างอิงให้เป็นแรงดันที่ขา AREF ซึ่งต่อเข้ากับ VCC จึงมีแรงดันเท่ากับ 5 โวลท์
ฟังก์ชันอ่านสัญญาณแอนะล็อก
เพื่อความสะดวก เราจะสร้างฟังก์ชัน read_adc
ขึ้นมาจากกระบวนการข้างต้น ฟังก์ชันนี้รับพารามิเตอร์เป็นหมายเลขขาของพอร์ท C จากนั้นจึงคืนค่าสัญญาณแอนะล็อกที่อ่านได้และแปลงเป็นข้อมูลดิจิทัล 10 บิตเรียบร้อยแล้วกลับออกมา
uint16_t read_adc(uint8_t channel)
{
ADMUX = (0<<REFS1)|(1<<REFS0) // ระบุให้ใช้ VCC เป็นแรงดันอ้างอิง (Vref) และ
| (0<<ADLAR) // บันทึกผลลัพธ์ชิดขวาในคู่รีจีสเตอร์ ADCH/ADCL
| (channel & 0b1111); // ตั้งค่า MUX เป็นค่า channel
ADCSRA = (1<<ADEN) // เปิดวงจร ADC
| (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) // ใช้ความเร็ว 1/128 ของคล็อกระบบ
| (1<<ADSC); // สั่งวงจร ADC ให้เริ่มต้นการแปลง
while ((ADCSRA & (1<<ADSC))) // รอจนบิต ADSC กลายเป็น 0 ซึ่งหมายถึงการแปลงเสร็จสิ้น
;
return ADCL + ADCH*256; // ผลลัพธ์ถูกเก็บอยู่ในรีจีสเตอร์ ADCL และ ADCH
// สามารถใช้ return ADC ได้เช่นกัน
}