ADC3: Single Conversation
Yazı serisindeki bir yazıyı hazırlasam da yayımlamamaya karar verdim. Çünkü Free Running modunda ölçüm yapma ile ilgili olarak hala sebebini tam olarak anlamadığım bazı donanımsal sorunlar yaşadım. Bir ara sakin bir kafa ile oturup o yazıyı bir gözden geçireceğim. Şİmdilik Çoklu kanal ölçüm işlemini FreeRunning yerine Single Converstion modunda yapalım. Tek kanal ve çoklu kanaldan ADC ölçümünü iki ayrı yazı olarak ele almaktansa ikisini de bu yazıda ele alıp konuyu kapatacağım. Çünkü yazı sayısının artması üretkenliğimi düşürüyor.
Aslında yapacağımız işlemlerin FreeRunning modundan pek bir farkı yok. Tek fark ADATE bitinin durumuna müdahale etmeyip, her ölçüm tamamlandığında ADC ölçümünü tekrar başlatmak. Benim gözlemlerime göre Single Conversation modunda yapılan çoklu kanal ölçümleri FreeRunning'e göre daha satabil sonuçlar veriyor.
Her zaman savunduğumuz gibi bu işin temeli veri kitapçıklarını yalayıp yutmaktan geçiyor. Ben burada ne kadar açıklama yaparsam yapayım, dönüp dolaşacağınız yer veri kitapçıkları olacaktır.
ADC ayarlarını önceki iki yazıda yeterince anlatmıştım. ADC'nin daha farklı özellikleri olsa da bunların hepsine bu yazıda değinemeyeceğiz. Örnek vermek gerekirse ADC'yi kurduğumuz bir zamanlayıcı kesmesi ile belirli periyotlarda ölçüm yapması için yapılandırabiliyoruz. Şimdilik ufak adımlarla ilerleyelim. Aşağıdaki kod 1.ADC kanalında ölçüm yapıp sonuçları sonuc isimli değişkene kayıt etmektedir.
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
uint16_t sonuc;
int main(void){
ADCSRA|=(1<<ADEN);//ADC açıldı.
ADCSRA|=(1<<ADPS0)|(1<<ADPS1);//Ön derecelendirici 32 olarak ayarlandı.
ADMUX|=(1<<MUX0);//1. ADC kanalı seçildi.
ADMUX|=(1<<REFS0);//Referans voltajı AVCC olarak ayarlandı.
ADMUX|=(1<<ADLAR);//Ölçüm sonuçları sola dayalı olarak seçildi.
ADCSRA|=(1<<ADSC);//Ölçüm başlatıldı.
/* Replace with your application code */
while(1){
while(!(ADCSRA&(1<<ADIF)));//Ölçüm bitene kadar bekle.
sonuc=(ADCL>>6)|(ADCH<<2);//ölçüm sonuçlarını hesapla.
ADCSRA|=(1<<ADSC);//Ölçüm başlatıldı
}
}
Önceki yazımızdaki yazının başındaki kodu alıp biraz evirip çevirdim. Şuan bu kod tek kanaldan ölçüm yapıyor. ADC hassasiyetiyle oynamak için ön derecelendirici ayarları ile oynayabilirsiniz. Burada ADCSRA yazacındaki ADATE bitininin durumunu koruyarak ADC'yi Single Conversation modunda başlattık. Yani şu anda ADATE biti mantıksal 0 durumunda. Program ADC'nin işini bitirmesini bekliyor ve ölçüm sonuçlarını işliyor. FreeRunning modunda ADC'yi bir kere başlatmamız yeterli idi. Burada ise ADC'yi her ölçümden sonra tekrar başlatmamız gerekiyor.
Çoklu kanal ile ölçüm yarken dikkat etmeniz gereken nokta kanallardan biri ile ölçüm yaparken diğerini boşta bırakmamak. Bu ADC sonuçlarınızın sapıtmasına yol açabilir. Elektronikte yüzen pinler her zaman tehlikelidir. :)
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
uint16_t sonuc;
uint16_t sonuc1;
int main(void){
ADCSRA|=(1<<ADEN);//ADC açıldı.
ADCSRA|=(1<<ADPS0)|(1<<ADPS1);//Ön derecelendirici 32 olarak ayarlandı.
ADMUX|=(1<<MUX0);//1. ADC kanalı seçildi.
ADMUX|=(1<<REFS0);//Referans voltajı AVCC olarak ayarlandı.
ADMUX|=(1<<ADLAR);//Ölçüm sonuçları sola dayalı olarak seçildi.
ADCSRA|=(1<<ADSC);//Ölçüm başlatıldı.
while(!(ADCSRA&(1<<ADIF)));//Ölçüm bitene kadar bekle.
/* Replace with your application code */
while(1){
ADMUX&=~(1<<MUX0);//0. ADC kanalı seçildi.
ADCSRA|=(1<<ADSC);//Ölçüm başlatıldı
while(!(ADCSRA&(1<<ADIF)));//Ölçüm bitene kadar bekle.
sonuc=(ADCL>>6)|(ADCH<<2);//ölçüm sonuçlarını hesapla.
ADMUX|=(1<<MUX0);//1. ADC kanalı seçildi.
ADCSRA|=(1<<ADSC);//Ölçüm başlatıldı
while(!(ADCSRA&(1<<ADIF)));//Ölçüm bitene kadar bekle.
sonuc1=(ADCL>>6)|(ADCH<<2);//ölçüm sonuçlarını hesapla.
}
}
Ölçümlerde sizi en gıcık edecek durum çevresel etkenlerin sisteminizin doğruluğunu aşırı derecede etkileyecek olmasıdır. Bu yüzden ADC'yi düzgün tasarlanmış devreler ile desteklemeniz yerinde bir karar olacaktır. Daha işin bu kısmını tam olarak ben de çözebilmiş değilim. O yüzden bu konuda fazla yorum yapıp sizi yanlış yönlendirmem doğru olmaz. Temelde bakacak olursanız yukarıda vermiş olduğum 1.ADC kanalından ölçüm yapan kod ile 1 ve 0.ADC kanalından ölçüm yapan kod arasında pek bir fark yok.
Her ne kadar yazının fazla kısa olduğunu düşünsem de yazıyı dolduracak konuyla ilgili aklıma başka bir şey gelmediğinden laf salatası yapamıyorum. Bir sonraki yazıda hangi konuya bakarız Allah bilir. :)
Commentaires