PIC ile ADC kullanımı (CC5X için ADC kütüphanesi ile)
Küçük bir devre yapmak istiyorsunuz ve Microchip’in 16 serisi mikro denetleyicilerini kullanacaksınız. Devrenizde ADC ile ölçüm yapmak istiyorsunuz ancak sadece büyük boyutlu ve yüksek kapasiteli denetleyicilerde ADC mevcut (örn.16F877). O zaman harici bir ADC’ye ihtiyacınız var.
ADC’ler sayısal olan dünyanıza, analog değerlerin, işlemcinizin anlayabileceği dilden konuşmasını sağlayan tercümanlardır. Tipik bir ADC, girişe uygulanan voltajın (dönüştürülmek istenilen) bağlanan referans voltajına göre orantısını, sahip olduğu çözünürlük kabiliyetine göre verir. Yani, eğer referans voltajınız 4V ve sizin ADC’ye verdiğiniz voltaj 3V ise, 8 bitlik bir ADC size çıkışta;
4V eğer FF ise
3V ??
doğru orantısından elde edilecek 8bitlik Hexadecimal sayısını üretir.
Çıkış = (3V x FF) / 4V = C0
Sonucunu üretecektir.
ADC0831, 4,5V ile 6.3V voltaj aralığında çalışabilen, 8 bit çözünürlüğe sahip, analog-sayısal dönüştürme süresi 32us olan seri bir analog-sayısal dönüştürücüdür. Bu uygulamada anlatılan ADC0831’in pin diyagramı aşağıdaki gibidir.
Şekil.1. ADC0831 Pin diyagramı
Mux’larla girişleri çoğullanmış bir çok çeşidi bulunmaktadır (0832, 0834, 0838 gibi). Ancak ben bu uygulamada ADC Serisine ufak bir giriş olması maksadıyla sadece tek girişli olan ADC0831’den bahsedeceğim.
ADC0831 için, elektriksel karakteristikleri ve detaylı bilgisi için datasheet’ini inceleyebilirsiniz.
Toplam 3 bacak üzerinden haberleşen bu ADC0831 çok basit bir haberleşme protokolüne sahiptir. ADC0831 ile herhangi bir mikro denetleyicinin tipik bağlantısı Şekil.2’de verilmiştir.
Şekil.2. Tipik ADC0831 bağlantısı
Şekilde GP2D12 IR mesafe sensöründen alınan analog bilgi sayısal biçime dönüştürülmektedir. Önemli olan nokta, ADC’ye verdiğiniz referans voltajıdır. Yukarıda bahsettiğim gibi ADC’nin size üreteceği sonuç girişine verdiğiniz voltajın referans voltajına oranıdır. Zaten fiziksel yapısıda incelenirse, karşılaştırıcılardan oluşan, karşılıaştırıcılardan aldığı 1 bitlik değerleri çıkışa ileten basit bir yapıdır. Vref değeriniz karşılaştırıcıların referans olarak aldığı değerdir. Referans değeri ile sayısal biçime dönüştürmek istediğiniz voltaj değeri karşılaştırılır ve sayısal olarak elde edilen değer çıkışa gönderilir.
Devrede Vref bacağına, 5V’luk gerilim 1k ve 1.5k’lık dirençler üzerinden bölünerek uygulanmıştır.
Yani Vref = (5 x 1.5) / 2.5 = 3V’dur.
Dönüştürücümüz 8bit’lik olduğuna göre girişe uygulanacak olan voltaj 8 bit formatında Vref’değerinin orantısı olacaktır.
Yani eğer GP2D12’den alınan voltaj 3V ise, Vin, Vref’in aynısı olacaktır. Yani buna göre sonuç = FF8 veya 25510 ‘dur.
Eğer GP2D12’den alınan voltaj 1.5V ise, Vin, Vref’in yarısı olacaktır. Yani buna göre sonuç = 7F8 veya 12710 ‘dur.
Gelelim mikro denetleyicinizle ADC’nin haberleşmesine. Toplam 3 bacak üzerinden haberleşen ADC’nin haberleşme zamanlaması Şekil.3’de verilmiştir.
Şekil.3. ADC0831 için haberleşme zamanlaması
İlk olarak mikro denetleyiciden CS bacağı aşağı çekilerek ve Clock darbesi gönderilerek dönüştürme işlemi başlatılır. İkinci clock darbesinden itibaren de 7.bitten başlayarak her clock darbesi ile 1bit sayısal bilgi alınmak üzere, toplam 8bit’lik sayısal bilgi alınır. 10 ve 11inci clock darbesinden sonra işlem tamamlanır.
İşlem sırası şu şekildedir.
1. Chip Select=0
2. Clock=1;
3. Clock=0;
4. Eğer (Data Out = 1) ise Git (4), değil ise Git (5)
5. Clock=1;
6. Clock=0;
7. Alınacak Değerin 7.biti=Data Out
8. Clock=1;
9. Clock=0;
10. Alınacak Değerin 6.biti=Data Out
CC5X C compiler için yazdığım ADC0831 kütüphanesi aşağıda verilmiştir. Bu kütüphane 3 fonksiyondan oluşmaktadır. CC5X Pic C compiler’ın ücretsiz versiyonuna aşağıda verilen linkten ulaşabilirsiniz.
////////////////////////////////////////////////////////////////////////////
////////////////////////Tolga TASTAN ///////////////////////////
////////////////////////////////////////////////////////////////////////////
//////////////////// For CC5X Compilers /////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////// ADC0831 Library ////////////////////////
////////////////////////////////////////////////////////////////////////////
/* This library is written by Tolga Tastan at 06 June 2006. It
could be used in CC5X Pic Compiler. The compiler could be
dowloaded from http://www.bknd.com/cc5x/ address.
What should you do for using these library?
Options and other functions are explained below.
I hope you like this code.
tolga@aadf.net
*/
/////////////////////////////////////////////////////////////////////////////
Functions Operations
—————————————————————–
/////////////////////////////////////////////////////////////////////////////
*/
#pragma bit ADC_CS @ PORTB.7
#pragma bit ADC_CLK @ PORTB.6
#pragma bit ADC_DO @ PORTB.5
#pragma bit ADC_DO_IO @ TRISB.5
#define VREF_VAL 5 //VREF pin voltage value set 5V
//start ADC0831
void init_ADC(void)
{ADC_CS=1;}
//Send clock pulse to ADC
void ADC_clk_pulse()
{
ADC_CLK=1;
Delay1ms(5);
ADC_CLK=0;
Delay1ms(5);
}
//8bit converted value
uns8 get_conversion()
{
uns8 adc_rec_data;
adc_rec_data=0;
ADC_DO_IO=1; //ADC DO pin set input
ADC_CS=0; //chip select line low
Delay1ms(5);
ADC_clk_pulse();
while(1) //wait tri state off
{
if(ADC_DO==0) {break;}
else{nop();}
}
ADC_clk_pulse(); //7.bit received at the end of the clock
Delay1ms(5);
adc_rec_data.7=ADC_DO;
ADC_clk_pulse(); //6.bit received at the end of the clock
Delay1ms(5);
adc_rec_data.6=ADC_DO;
ADC_clk_pulse(); //5.bit received at the end of the clock
Delay1ms(5);
adc_rec_data.5=ADC_DO;
ADC_clk_pulse(); //4.bit received at the end of the clock
Delay1ms(5);
adc_rec_data.4=ADC_DO;
ADC_clk_pulse(); //3.bit received at the end of the clock
Delay1ms(5);
adc_rec_data.3=ADC_DO;
ADC_clk_pulse(); //2.bit received at the end of the clock
Delay1ms(5);
adc_rec_data.2=ADC_DO;
ADC_clk_pulse(); //1.bit received at the end of the clock
Delay1ms(5);
adc_rec_data.1=ADC_DO;
ADC_clk_pulse(); //0.bit received at the end of the cl
ock
Delay1ms(5);
adc_rec_data.0=ADC_DO;
ADC_clk_pulse();
ADC_clk_pulse();
ADC_CS=1;
Delay1ms(5);
return adc_rec_data;
}
//Send 16bit calculated mv value (5000 for 5V)
uns16 get_adc_value(void) //return Vref*1000 for Vin = Vref
{
uns24 adc_voltage;
adc_voltage=0;
adc_voltage = get_conversion();
adc_voltage = adc_voltage * VREF_VAL;
adc_voltage = adc_voltage * 10000; //x1000
adc_voltage = adc_voltage / 0xFF;
adc_voltage = adc_voltage;
return adc_voltage;
}
//return Vref*1000 for Vin = Vref
Kütüphanenin Kullanımı
Kütüphaneyi incelerseniz hangi fonksiyonun nasıl çalıştığına ve ne işe yaradığına ait yorumları bulabilirsiniz. Kütüphanenin çalıştırılması için Pinlerin karşılıkları ve referans değeri kütüphanenin başında ayarlanmalıdır.
#pragma bit ADC_CS @ PORTB.7 //ADC’nin CS bacağı
#pragma bit ADC_CLK @ PORTB.6 //ADC’nin CLK bacağı
#pragma bit ADC_DO @ PORTB.5 //ADC’nin Data input/output bacağı
#pragma bit ADC_DO_IO @ TRISB.5 //ADC’nin Data bacağı için giriş çıkış ayarlanması
#define VREF_VAL 5 //VREF değeri
Fonksiyonların çalışmaları ve işlevleri aşağıda açıklanmıştır.
Fonksiyon ; init_ADC();
init_ADC() fonksiyonu, ana fonksiyonunuzun başında çağrılmalıdır. Sadece CS bacağının 5V’a çekilmesini sağlar.
//start ADC0831
void init_ADC(void)
{ADC_CS=1;}
Fonksiyon ; ADC_clk_pulse();
Clock fonksiyonu işlemciden ADC0831’in CLK bacağına 5ms süresince Mantıksal 1, 5ms süresince Mantıksal 0 gönderir. Gerekli clock prosedürü gerçekleştirilmiş olur.
//Send clock pulse to ADC
void ADC_clk_pulse(void)
{
ADC_CLK=1;
Delay1ms(5);
ADC_CLK=0;
Delay1ms(5);
}
Fonksiyon ; get_conversion()
get_conversion(), fonksiyonu 8 bitlik dönüştürülmüş ADC değerini elde eder. ADC0831 ile yapılması gereken işlemleri gerçekleştirir. (CS’yi aşağı çekme, clockların gönderilmesi ve değerin elde edilmesi).
uns8 get_conversion()
{
uns8 adc_rec_data; //Fonksiyonun sonunda ADC’den alınıp gönderilecek değer
adc_rec_data=0;
ADC_DO_IO=1; //ADC DO pini giriş olarak ayarlanır
ADC_CS=0; //chip select hattı aşağı çekilir
Delay1ms(5);
ADC_clk_pulse();
while(1)
{
if(ADC_DO==0) {break;}
else{nop();}
}
ADC_clk_pulse(); //7.bit Clock darbesinin sonunda alınır
Delay1ms(5);
adc_rec_data.7=ADC_DO; //Gönderilecek 8bitlik değişkene okunan değer yazılır
ADC_clk_pulse(); //6.bit Clock darbesinin sonunda alınır
Delay1ms(5);
adc_rec_data.6=ADC_DO; //Gönderilecek 8bitlik değişkene okunan değer yazılır
ADC_clk_pulse(); //0.bit Clock darbesinin sonunda alınır
Delay1ms(5);
adc_rec_data.0=ADC_DO; //Gönderilecek 8bitlik değişkene okunan son değer yazılır
ADC_clk_pulse(); //10Clock darbesi gönderilir
ADC_clk_pulse(); //11Clock darbesi gönderilir ve dönüştürüp gönderme işlemi tamamlanır
ADC_CS=1;
Delay1ms(5);
return adc_rec_data; //Elde edilen değer fonksiyonun çağrıldığı yere gönderilir
}
Fonksiyon ; get_adc_value(void)
get_adc_value(void) fonksiyonu ise 24’bitlik dönüştürülmüş ve Vref değerine göre orantılanmış 16bitlik çıkışı üretir. Vref değeri kütüphanenin başında tanımlanmıştır. get_conversion() fonksiyonundan elde edilen 8 bitlik değeri yukarıda tanımlanan Vref’e göre doğru orantıyla dönüştürür. Üretilen değer 5 basamaklıdır. İlk basamak Vref’e göre elde edilen değer, diğer 4 basamakta ondalık kısımıdır. 8 bitlik ADC’nin 5V’luk bir referans değeri için tespit edeceği en küçük değişim 0.01953125V‘dur. Buna göre Vin değeri örneğin 3.4132, 4.3123…gibi değerler olabilir.
uns16 get_adc_value(void) //Referansa göre 1000katı olan mv değeri gönderir
{
uns24 adc_voltage;
adc_voltage=0;
adc_voltage = get_conversion(); //8bitlik Conversion değeri istenir
adc_voltage = adc_voltage * VREF_VAL;
adc_voltage = adc_voltage * 10000; //x1000
adc_voltage = adc_voltage / 0xFF;
adc_voltage = adc_voltage;
return adc_voltage; // (Vin*1000*VrefValue)/Vref değeri gönderilir
}
Pic16F628 ve ADC0831 ile örnek voltaj ölçümü uygulaması
Bu örnek uygulamada, Vin girişlerine bağlanan değer (pil olarak bağlanmıştır) Vref=5 ‘e göre hesaplanır ve LCD’de görüntülenir.
Eğer Pic’in ADC ile haberleşmesinde problem tespit edilirse ekranda hata mesajı görüntülenir. Sorunsuz yapılan her ölçümün ardından okunan değer ekranda görüntülenir.
Bağlantılar
Örnek uygulamaya ait hex kodu main-hex
Örnek uygulamaya ait Proteus ISIS’te hazırlanan şematik çizimi sch-dsn (ISIS) CC5x için Pic ADC kütüphanesi adc0831
Not: Dosyaların sonundaki txt eklentisini kaldırın.
Tolga TAŞTAN
tolga@aadf.net