Bilindiği üzere analog sinyal, dijital sinyallerden farklı olarak 0 ile 5V arasında dönüştürme çözünürlüğüne göre n kadar değer alabilirler. Yani dijital sinyallerde enerji var ya da yok (1-0) olarak 2 değerden bahsederken, analog sinyalde, enerji şu kadar var gibi binlerce değer üzerinden işlem yapılabilir.
Bu durumu şöyle açıklayalım;
Örneğin bir su depomuz var, bu su deposundan dijital giriş ile değer okurken depoda su var, ya da depoda su yok olarak değer okuyabiliriz. Ancak aynı depodan analog giriş ile değer alırken, depoda şu kadar su var diyerek bir ölçü belirtebiliriz.
Analog giriş ile okuma yaparken iki önemli unsur vardır. Birincisi, dönüştürme aralığı, ikincisi ise dönüştürme çözünürlüğü.
Dönüştürme aralığı PIC ve diğer birçok denetleyiciler için 0 ila 5 volt arasıdır. Çözünürlük ise denetleyiciye göre farklılık gösterebilir. Analog dönüştürme çözünürlüğü 8, 10, 14 ya da 16 bit olabilir. Yani bu da demek oluyor ki 10 bit çözünürlüğündeki dönüştürme işlemi, 5V değerindeki gerilimi 2^10 yani 1023 parçaya böler.
Analog-Dijital dönüştürme sonucunu hesaplamak için ADC = (Vg*Coz)/Vmax şeklinde bir formül yazabiliriz.
Bu formülde;
ADC = Analog-Dijital dönüştürme sonucu
Vg = Girişe uygulanan gerilim
Coz = Analog-Dijital dönüştürme çözünürlüğü
Vmax = Analog girişe uygulanabilecek maksimum gerilimdir
Örneğin analog girişe 2V gerilim uyguladığımızı varsayalım ve 10 bit çözünürlüğünde Analog/Dijital dönüştürme sonucunu hesaplayalım;
10 bitlik en büyük sayının 1023 olduğunu ve girişe uygulayabileceğimiz maksimum voltajın 5V olduğunu biliyoruz. Formülümüzü yazalım;
ADC = (Vg*Coz)/Vmax formülünde bilinenleri yerine koyalım;
ADC=(2*1023)/5 = 409,2 olarak bulunur.
Şimdi PIC denetleyicisi ile ADC (Analog Dijital Converter) işlemini CCS C dilinde inceleyelim;
ADC işlemi için öncelikle analog girişleri aktif etmemiz gerekmektedir. Aksi taktirde denetleyicimiz bu girişleri dijital olarak algılayacaktır.
PIC 16F877a denetleyicimiz için analog giriş pinleri aşağıdaki görselde de görüldüğü üzere RA ve RE portlarında toplam 8 adet bulunur. Analog giriş özelliğine sahip pin isimleri AN harfleri ile belirtilir.
Öncelikle her zaman olduğu gibi denetleyici dosyamızı içe aktarıyoruz ve ardından ADC çözünürlüğünü tanımlıyoruz. Bu çözünürlük denetleyiciye göre farklılık gösterebilir.
1 2 3 |
#include <16F877A.h> // Denetleyici dosyasını içe aktardık #device ADC = 16 // 16 bit çözünürlüklü ADC kullanacağız |
Şimdi Analog – Dijital dönüştürme frekansını belirlemek için bir ayar fonksiyonu kullanacağız. Fonksiyonumuz setup_adc() fonksiyonu olacak. Bu fonksiyonumuz main() fonksiyonu içerisinde tanımlanacaktır. Fonksiyonumuzun alabileceği parametreler aşağıda listelenmiştir.
Ardından yine main fonksiyonumuz içerisinde analog giriş portları ayarlarını yapacağız. Bunun için setup_adc_ports() fonksiyonunu kullanacağız. 16f877A denetleyicisinde bu fonksiyonumuzun alabileceği parametreler aşağıda verilmiştir;
Bu parametreler kullanılan denetleyiciye göre değişiklik gösterebilir. Kullanacağınız denetleyicilerin datasheet dosyalarına bakarak, hangi parametreleri kullanacağınızı öğrenebilirsiniz.
Şimdi setup_adc() fonksiyonu ile dönüştürme frekansımızı belirleyelim ve setup_adc_port() fonksiyonumuzla A portundaki tüm analog girişleri aktif edelim;
1 2 3 4 5 6 7 8 9 10 |
void main() { setup_adc(ADC_CLOCK_DIV_32); setup_adc_ports(AN0_AN1_AN2_AN3_AN4); while(TRUE) { //Kodlar... } } |
Buraya kadar hangi analog girişleri kullanacağımızı ve kaç bit çözünürlüğünde dönüştürme işlemi yapacağımızı tanımladık. Bu noktadan sonra artık analog giriş okumaya başlayabiliriz.
Analog giriş okumada kullanacğımız fonksiyonlarımızdan bir diğeri ise set_adc_channel() fonksiyonudur. Analog kanalları okumadan önce kullanacağımız bu fonksiyon, okunacak kanalı seçmek için kullanılır. Az önce RA portundaki tüm analog destekli pinleri analog giriş olarak tanımlamıştık. Şimdi örneğin AN1 kanalını okumak istersek, bu fonksiyonumuza gireceğimiz parametre “1” değeri olacaktır.
Sözdizimi: set_adc_channel(1) // AN1 analog girişindeki analog değeri okuyacağımızı belirttik
Okuyacağımız analog kanalı yukarıdaki gibi seçtikten sonra analog giriş okuma fonksiyonumuz olan read_adc() fonksiyonu ile, kanaldan analog değeri alacağız.
read_adc() fonksiyonu herhangi bir parametre almaz, bu sebeple fonksiyonun parantezleri arasını boş bırakıyoruz. Ancak fonksiyon geriye 16 bit değerinde bir değer döndüreceği için, bu değeri 16 bitlik bir değişkene atayacağız.
Sözdizimi: int16 bilgi = read_adc() // Analog girişi oku ve okunan değeri 16 bitlik bilgi değişkenine aktar.
Kanal seçip analog değer okumak için kodlarımız şu şekilde olacak;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void main() { // Kullanacağımız analog girişleri belirtiyoruz setup_adc_ports(AN0_AN1_AN2_AN3_AN4); int16 analogBilgi; // Okuduğumuz analog değeri bu değişkene aktaracağız while(TRUE) // Sonsuz döngümüz { set_adc_channel(1); // AN1 numaralı kanaldan okuma yapacağımızı belirttik analogBilgi = read_adc(); // AN! numaralı kanaldan analog değeri oku delay_ms(1000); // 1 saniye bekle } } |
Şimdi yukarıdaki öğrendiğimiz bilgilerle, analog giriş okuma işlemi yapalım:
AN1 girişine bağladığımız potansiyometreyi çevirerek RD portuna bağladığımız ledleri sırasıyla yakıp söndürelim. Kodlarımız aşağıdaki gibi olacak.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <16F877A.h> // Başlık dosyası #FUSES XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NOCPD #device ADC = 10 // 10 bitlik çevirme işlemi yapılacak (0 - 1023 arası) #use delay(crystal=20000000) // 20MHz saat frekansı kullanılacak #use fast_io(d) // d portu yönlendirilecek void main() // ana fonksiyon { setup_adc(adc_clock_div_32); // denetleyici frekansını 1/32'si kullanılacak setup_adc_ports(AN0_AN1_AN2_AN3_AN4); // RA portundaki ADC pinleri aktif int16 analogBilgi; // okunan analog bilgiyi bu değişkende tutacağız set_tris_d(0); // RD portu çıkış olarak yönlendirildi output_d(0); // RD portunun tüm çıkışları sıfırlandı while(true) // Sonsu döngümüz { set_adc_channel(1); // ADC için AN1 kanalını seç analogBilgi = read_adc(); // AN1 kanalını oku ve değişkene aktar delay_ms(10); // 10ms bekle if(analogBilgi <= 128){ output_d(0b00000001); } else if((analogBilgi > 127) && (analogBilgi <= 254)) { output_d(0b00000011); } else if((analogBilgi > 254) && (analogBilgi <= 381)) { output_d(0b00000111); } else if((analogBilgi > 381) && (analogBilgi <= 508)) { output_d(0b00001111); } else if((analogBilgi > 508) && (analogBilgi <= 635)) { output_d(0b00011111); } else if((analogBilgi > 635) && (analogBilgi <= 762)) { output_d(0b00111111); } else if((analogBilgi > 762) && (analogBilgi <= 889)) { output_d(0b01111111); } else if((analogBilgi > 889) && (analogBilgi <= 1023)) { output_d(0b11111111); } } } |
Kodlarımızı denetleyicimize yükledikten sonra, aşağıdaki devreyi kurup çalıştıralım;
Potansiyometre ayarı ile oynayarak ledlerin hareketlerini izleyebilirsiniz.
abi teşekkür ederiz paylaşım için . ancak anlamadığımız yerler var. ADC=10 açıklamasını anlamadım . output_d yazmışsınız ama içine (0b00) gibi bir şey yazmışsınız. yani hem d ye yaz hem b ye yaz gibi olmuş, burayı da anlamadım. saygılar
Merhaba,
ADC=10 kodu Analog – Dijital dönüştürme çözünürlüğünün 10 bit olacağını ayarlamak için kullanılır. Yani analog girişe uygulanan sinyal 5 volt ise, dönüştüme sonucu bize 10 bitlik en yüksek sayı olan 1023 değerini verir. Formülü ise; (5*1023)/5 = 1023’tür. Eğer analog girişe uygulanan sinyal 2 Volt ise dönüştürme sonucu bize (2*1023)/5 = 409,2 sonucunu verir.
Analog dijital dönüştürme formulü:
ADC = (Vg*1023)/Vmax
Formülde;
ADC = Analog-Dijital dönüştürme sonucu
Vmax = Analog girişe uygulanabilecek maximum voltaj
1023 = 10 bit değerindeki en büyük sayı
Vg = Analog girişe uygulanan gerilimdir.
Output_d(0b00000111); koduna gelirsek:
Output_d() = D portuna veri yazacağımızı belirtir.
0b00000111 = binary sayıyı temsil eder. Yani bir sayının başında 0b varsa program onu binary sayı olarak algılar. Eğer 0x varsa, o sayı hexadecimal sayıdır. Eğer sayı başında hiçbir ifade yoksa, o sayı decimal sayıdır.
Output_d(0b00000111); komutunun eşdeğerini yazacak olursak;
output_high(pin_D0);
output_high(pin_D1);
output_high(pin_D2);
output_low(pin_D3);
output_low(pin_D4);
output_low(pin_D5);
output_low(pin_D6);
output_low(pin_D7);
şeklinde olurdu.
Biz yukarıdaki kodların tamamını output_d(0b00000111); komutuyla bir seferde yazmış olduk.
şimdi anladım , teşekkürler
PORTA’nın A0 pinini analog giriş, diğer pinlerini de digital giriş olarak ayarlamak istiyorum. Hangi registerda nasıl bir değişiklik yapmam gerekiyo yardımcı olabilir misiniz
Yukarıdaki kod örneğinde;
setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
yerine
setup_adc_ports(AN0);
yazarsanız, yalnızca A0 pinini Analog Giriş olarak kullanırsınız.
A0 haricindeki diğer ADC pinlerini Dijital Giriş-Çıkış olarak kullanabilirsiniz.
hocam merhaba ;
Vref+ olarak Vdd, Vref- olarak Vss gerilimlerini kullanan, RE0, RE1, ve RE2 pinlerinden
analog değer okuyan, çevrim frekansı focs /2 olan, çevrim sonucunu sola dayalı olarak
yazdıran ADC konfigürasyonunu CCS C fonksiyonlarını kullanmadan saklayıcılara
doğrudan erişerek nasıl yazdırabilirim