ขอคำปรึกษาเกี่ยวกับ ADC ของ ATmega8 หน่อยครับ พอดีอ่าน datasheet แล้วสงสัยว่าหลังจาก conversion เสร็จแล้วค่าที่อ่านมาได้จะถูกเก็บไว้ที่ ADCH/ADCL ใน ADLAR ถูกไหมครับ และถ้าเราจะนำค่าที่อ่านได้มาใช้ต่อเนี่ย สามารถเขียนโค้ดในลักษณะใดได้บ้างครับ
ปล. ADC ที่จะใช้คือรับค่ามาจาก infrared distance sensor แล้วจะนำค่าที่อ่านได้ที่ระยะต่างๆมาใช้ครับ
Quote from: nutzty on February 05, 2015, 08:09:57 PM
ขอคำปรึกษาเกี่ยวกับ ADC ของ ATmega8 หน่อยครับ พอดีอ่าน datasheet แล้วสงสัยว่าหลังจาก conversion เสร็จแล้วค่าที่อ่านมาได้จะถูกเก็บไว้ที่ ADCH/ADCL ใน ADLAR ถูกไหมครับ และถ้าเราจะนำค่าที่อ่านได้มาใช้ต่อเนี่ย สามารถเขียนโค้ดในลักษณะใดได้บ้างครับ
ปล. ADC ที่จะใช้คือรับค่ามาจาก infrared distance sensor แล้วจะนำค่าที่อ่านได้ที่ระยะต่างๆมาใช้ครับ
ผมใช้แบบโง่ๆ เลยครับ คือ ใช้ Arduino ครับ แล้วเลือกพรอตเป็น ATMEGA8 ครับ เขียนตามตัวอย่างของมันเลย ง่ายดี
ถ้าใช้ arduino มันง่ายก็ใช่ครับ ผมลองใช้แล้ว แต่ตัวงานถูกบังคับให้ใช้ ATmeg8 ครับ
//analog initial
void analog_initial(void){
//Set ADC prescalar to 128 - 125KHz sample rate @ 16MHz
ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
//Set ADC prescalar to 64 - 125KHz sample rate @ 8MHz
//ADCSRA |= (1<<ADPS2)|(1<<ADPS1);
//ADMUX |= (1<<REFS1); //Set ADC reference to 2.56v
ADMUX |= (1<<REFS0); //Set ADC reference to AVCC
//ADMUX |= (1<<ADLAR); //Left adjust ADC result to allow
//ADCSRA |= (1<<ADFR); //Set ADC to Free-Running Mode
ADCSRA |= (1<<ADEN); //Enable ADC
//ADCSRA |= (1<<ADSC); //Start A2D Conversions
}
//analog read
unsigned int analog_read(unsigned char mux_ch){
ADMUX &= 0b11100000;
ADMUX |= mux_ch; //Select ADC Channel ch must be 0-7
ADCSRA |= (1<<ADSC); //Start Single conversion
while(!(ADCSRA&(1<<ADIF))); //Wait for conversion to complete
ADCSRA |= (1<<ADIF); //Clear ADIF by writing one to it
return ADC;
}
Quote from: nutzty on February 05, 2015, 08:09:57 PM
ขอคำปรึกษาเกี่ยวกับ ADC ของ ATmega8 หน่อยครับ พอดีอ่าน datasheet แล้วสงสัยว่าหลังจาก conversion เสร็จแล้วค่าที่อ่านมาได้จะถูกเก็บไว้ที่ ADCH/ADCL ใน ADLAR ถูกไหมครับ และถ้าเราจะนำค่าที่อ่านได้มาใช้ต่อเนี่ย สามารถเขียนโค้ดในลักษณะใดได้บ้างครับ
ปล. ADC ที่จะใช้คือรับค่ามาจาก infrared distance sensor แล้วจะนำค่าที่อ่านได้ที่ระยะต่างๆมาใช้ครับ
ประกาศตัวแปรมารับค่าจาก port ADC ได้เลยครับ
unsigned w_sensor = ADC; // ADC คือ port regidter(16 bit) ประกอบด้วย ADCH(8 bit), ADCL(8bit)
ถ้าใช้ 10 bit หลังจะได้ค่า 0 - 1023
(http://i.imgur.com/I9bhbgV.png)
ปล. ADLAR คือ การกำหนดว่าจะใช้ 10 bit หน้า หรือ 10 bit หลังครับ
Quote from: JENG on February 05, 2015, 10:13:46 PM
//analog initial
void analog_initial(void){
//Set ADC prescalar to 128 - 125KHz sample rate @ 16MHz
ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
//Set ADC prescalar to 64 - 125KHz sample rate @ 8MHz
//ADCSRA |= (1<<ADPS2)|(1<<ADPS1);
//ADMUX |= (1<<REFS1); //Set ADC reference to 2.56v
ADMUX |= (1<<REFS0); //Set ADC reference to AVCC
//ADMUX |= (1<<ADLAR); //Left adjust ADC result to allow
//ADCSRA |= (1<<ADFR); //Set ADC to Free-Running Mode
ADCSRA |= (1<<ADEN); //Enable ADC
//ADCSRA |= (1<<ADSC); //Start A2D Conversions
}
//analog read
unsigned int analog_read(unsigned char mux_ch){
ADMUX &= 0b11100000;
ADMUX |= mux_ch; //Select ADC Channel ch must be 0-7
ADCSRA |= (1<<ADSC); //Start Single conversion
while(!(ADCSRA&(1<<ADIF))); //Wait for conversion to complete
ADCSRA |= (1<<ADIF); //Clear ADIF by writing one to it
return ADC;
}
ไม่ใช่ว่าบรรทัดก่อน return เนี่ย ต้องใส่ 0 ให้ ADIF หรือครับ
Quote from: az on February 05, 2015, 10:14:21 PM
Quote from: nutzty on February 05, 2015, 08:09:57 PM
ขอคำปรึกษาเกี่ยวกับ ADC ของ ATmega8 หน่อยครับ พอดีอ่าน datasheet แล้วสงสัยว่าหลังจาก conversion เสร็จแล้วค่าที่อ่านมาได้จะถูกเก็บไว้ที่ ADCH/ADCL ใน ADLAR ถูกไหมครับ และถ้าเราจะนำค่าที่อ่านได้มาใช้ต่อเนี่ย สามารถเขียนโค้ดในลักษณะใดได้บ้างครับ
ปล. ADC ที่จะใช้คือรับค่ามาจาก infrared distance sensor แล้วจะนำค่าที่อ่านได้ที่ระยะต่างๆมาใช้ครับ
ประกาศตัวแปรมารับค่าจาก port ADC ได้เลยครับ
unsigned w_sensor = ADC; // ADC คือ port regidter(16 bit) ประกอบด้วย ADCH(8 bit), ADCL(8bit)
ถ้าใช้ 10 bit หลังจะได้ค่า 0 - 1023
(http://i.imgur.com/I9bhbgV.png)
ปล. ADLAR คือ การกำหนดว่าจะใช้ 10 bit หน้า หรือ 10 bit หลังครับ
อ๋อ คือหลังจากเลือก ADLAR แล้วก็ค่อยมาดูอีกทีว่า แต่ละแบบค่าที่ถูกแปลงแล้วถูกเก็บไว้ที่ ADCH/ADCL bit ไหนบ้างใช่ไหมครับ เช่น ADLAR = 1 ก็จะแบ่งไปเก็บใน ADCH 8 bit และ ADCL 2 bit แบบนี้เข้าใจถูกไหมครับ
อ่านเพิ่มเติมจาก data sheet เอาคับ ห้ามอ่านแบบผ่านๆนะ ผมเงิบมาแล้วเรื่อง adc ของ avr น่ะ
Quote from: JENG on February 06, 2015, 10:38:53 AM
อ่านเพิ่มเติมจาก data sheet เอาคับ ห้ามอ่านแบบผ่านๆนะ ผมเงิบมาแล้วเรื่อง adc ของ avr น่ะ
คือใน datasheet เนี่ย ผมอ่านแล้วนะ แต่มันงงอ่ะครับ ก็เลยมาถามเอาให้แน่ใจว่าตัวเองเข้าใจถูกแล้วใช่ไหม ตอนนี้กำลังลองเขียนโปรแกรมเพื่อเช็คไปด้วยอีกทีครับ
code ที่แปะเป็น code ที่ใช้งานจริงคับ ยังมีตรงไหนไม่แน่ใจอีกหรือ ;D
Quote from: nutzty on February 05, 2015, 08:27:35 PM
ถ้าใช้ arduino มันง่ายก็ใช่ครับ ผมลองใช้แล้ว แต่ตัวงานถูกบังคับให้ใช้ ATmeg8 ครับ
ATMEGA8 ใช้ Arduino ได้ครับ เลือก Board : Arduino NG order W .... ครับ พอเรา comply แล้วมันจะอยู่ที่ c:\...user...\temp\..... ครับ โดย Folder นี้มันจะมองไม่เห็น ต้องกำหนดที่ window ให้แสดง folder ที่ซ่อนไว้ เราจะได้ file : ???.hex เรา เอาตัวนี้ไปอัดลงบอร์ดเรา ครับ ผมใช้วิธีนี้ครับ
Quote from: JENG on February 07, 2015, 08:55:23 AM
code ที่แปะเป็น code ที่ใช้งานจริงคับ ยังมีตรงไหนไม่แน่ใจอีกหรือ ;D
อยากลองเขียนเองไปด้วยน่ะครับ เขียนเองจะเข้าใจได้มากกว่านั่งอ่านเฉยๆ
Quote from: skytec on February 07, 2015, 10:17:24 AM
Quote from: nutzty on February 05, 2015, 08:27:35 PM
ถ้าใช้ arduino มันง่ายก็ใช่ครับ ผมลองใช้แล้ว แต่ตัวงานถูกบังคับให้ใช้ ATmeg8 ครับ
ATMEGA8 ใช้ Arduino ได้ครับ เลือก Board : Arduino NG order W .... ครับ พอเรา comply แล้วมันจะอยู่ที่ c:\...user...\temp\..... ครับ โดย Folder นี้มันจะมองไม่เห็น ต้องกำหนดที่ window ให้แสดง folder ที่ซ่อนไว้ เราจะได้ file : ???.hex เรา เอาตัวนี้ไปอัดลงบอร์ดเรา ครับ ผมใช้วิธีนี้ครับ
อ้อ ผมลืมไปเลย เดี๋ยวไว้ไปลองประยุกต์ใช้อีกทีครับ
ดาต้าชีทบอกว่า ถ้า ADLAR=1 ค่า ADC จะอยุ่ 10 bit บน
ถ้า ADLAR=จ ค่า ADC จะอยุ่ 10 bit ล่าง
สำคัญคือ ค่า ADC จะยังไม่เปลี่ยนแปลงจนกว่าเราจะอ่านค่า ADCH
ดังนี้เพื่อให้ค่าที่ได้ถูกต้อง เราจึงต้องอ่าน ADCL ก่อน ADCH เสมอ
Quote from: nai102 on February 13, 2015, 12:57:12 AM
สำคัญคือ ค่า ADC จะยังไม่เปลี่ยนแปลงจนกว่าเราจะอ่านค่า ADCH
ดังนี้เพื่อให้ค่าที่ได้ถูกต้อง เราจึงต้องอ่าน ADCL ก่อน ADCH เสมอ
ถ้าอ้างอิง code จากท่าน JENG
ADLAR ค่า default = 0 (10 bit ล่าง)
ซึ่งค่า return ADC; จะได้ค่า 0 - 1023
โดยการ return ADC; สามารถอ่านค่าจาก ADCH,ADCL พร้อมกันในคำสั่งเดียวได้เลยครับ
Quote from: JENG on February 05, 2015, 10:13:46 PM
//analog initial
void analog_initial(void){
//Set ADC prescalar to 128 - 125KHz sample rate @ 16MHz
ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
//Set ADC prescalar to 64 - 125KHz sample rate @ 8MHz
//ADCSRA |= (1<<ADPS2)|(1<<ADPS1);
//ADMUX |= (1<<REFS1); //Set ADC reference to 2.56v
ADMUX |= (1<<REFS0); //Set ADC reference to AVCC
//ADMUX |= (1<<ADLAR); //Left adjust ADC result to allow
//ADCSRA |= (1<<ADFR); //Set ADC to Free-Running Mode
ADCSRA |= (1<<ADEN); //Enable ADC
//ADCSRA |= (1<<ADSC); //Start A2D Conversions
}
//analog read
unsigned int analog_read(unsigned char mux_ch){
ADMUX &= 0b11100000;
ADMUX |= mux_ch; //Select ADC Channel ch must be 0-7
ADCSRA |= (1<<ADSC); //Start Single conversion
while(!(ADCSRA&(1<<ADIF))); //Wait for conversion to complete
ADCSRA |= (1<<ADIF); //Clear ADIF by writing one to it
return ADC;
}
ถ้างั้นจากโค้ดของคุณ JENG ผมก็จะเขียนได้ว่า
int adc_value=0;
adc_value = analog_read(5); //สมมติว่าผมใช้ADC5
ผมก็จะได้ค่า 0-1023 มาเก็บไว้ใบ adc_value ทันทีโดยไม่ต้องไปอ่าน ADCH/ADCL เลยสินะครับ
Quote from: nutzty on February 14, 2015, 07:42:03 PM
ถ้างั้นจากโค้ดของคุณ JENG ผมก็จะเขียนได้ว่า
int adc_value=0;
adc_value = analog_read(5); //สมมติว่าผมใช้ADC5
ผมก็จะได้ค่า 0-1023 มาเก็บไว้ใบ adc_value ทันทีโดยไม่ต้องไปอ่าน ADCH/ADCL เลยสินะครับ
int var. เปลี่ยนเป็น unsigned short ก็พอครับ
การ return ADC; สามารถอ่านค่าจาก ADCH,ADCL พร้อมกันในคำสั่งเดียวได้เลยครับ
;D ขอบคุณครับ
Quote from: az on February 15, 2015, 11:45:02 AM
Quote from: nutzty on February 14, 2015, 07:42:03 PM
ถ้างั้นจากโค้ดของคุณ JENG ผมก็จะเขียนได้ว่า
int adc_value=0;
adc_value = analog_read(5); //สมมติว่าผมใช้ADC5
ผมก็จะได้ค่า 0-1023 มาเก็บไว้ใบ adc_value ทันทีโดยไม่ต้องไปอ่าน ADCH/ADCL เลยสินะครับ
int var. เปลี่ยนเป็น unsigned short ก็พอครับ
การ return ADC; สามารถอ่านค่าจาก ADCH,ADCL พร้อมกันในคำสั่งเดียวได้เลยครับ
ขอบคุณครับ ชัดแจ่มแจ้งแล้ว ตอนเขียนผมใช้ int8u ครับ