This post is also available in: English (İngilizce)
- I2C Nedir?
- I2C Protokolünün Amacı
- I2C Protokolü için Gerekli Yapının Oluşturulması
- I2C Protokolü Nasıl Çalışır ?
- I2C Protokolü Sonuç
- I2C MikroC Kütüphanesi
- I2C Fonksiyonları
- Fonksiyonların Uygulanması
- Sonuç
- Kütüphane Dosyaları
- Yararlanılan Belgeler
- Güncelleme 27.01.2019 – Uygulamalar sırasında MCP4561 in çalışmasında sorun tespit ettim. Buna göre PIC in RB pinlerinde çalışmıyordu. Sonuç olarak bunun porttaki veri silinmesinden kaynaklandığını anladım. Bunu gidermek için kodlara LAT sistemini ekledim. Dolayısı ile pin tanımlaması yapılırken fazladan “sbit I2C_SDA_VERI at LATB0_bit;” eklemesi yapılması gerekmektedir. ( LAT kısmı sabittir B0 – portb0 anlamına gelir.)
- RTC (DS1307) kullanmam gereken bir projem için I2C protokolüne geçiş yaptım ancak PIC te yerleşik I2C modülü pinleri doluydu bu sebeple modüllerden bağımsız istenen pinde çalışabilen bir I2C protokolü ve kütüphanesi hazırladım.
- Bu kütüphane ile PIC in herhangi 2 pin i kullanılarak iletişim kurulabilir.
- I2C konusu anlatıldıktan sonra kütüphane kullanımı anlatılacaktır.
1- I2C Nedir ?
- I2C 2 adet pin üzerinden iletişim kurmayı sağlayan bir yazılım protokolüdür.
- Philips ( NXP ) firması tarafından oluşturulmuştur.
- Bir entegre yada parça eğer içerisinde I2C sistemi var ise bu protokol ile kullanılabilir yani bir RAM entegresinde I2C yok ise bu protokol ile kullanılamaz.
- I2C protokolünde yönetici MCU lara “master” yönetilen diğer parçalara ise “slave” denir.
Olumlu Yanları | Olumsuz Yanları |
Esnektir, sistem içerisinde bir çok slave ve master/slave parça ekeleyerek istediğiniz gibi geliştirebilirsiniz. | Parça adresleri üretilirken tanımlandıkları için adres çakışması yaşanabilir |
Adrese dayalı seçim yapar , yani fazladan bir CS ( chip select) pinine ihtiyacınız yoktur. | Diğer paralel iletişim sistemlerine göre hızları sınırlıdır |
Bağlantı sadedir, birden fazla parçada kullansanız sadece 2 hat üzerinden bağlantı kurulur | Bazı durumlarda çok fazla pull-up direnci koymak PCB lerde alan sıkıntısına yol açabilir |
Hata tespit sistemi olan ACK ve NACK bulunur. Böylece yapılan işlemin doğru olup olmadığı anlaşılır.(ileride anlatılacak) | |
Hız gözetmeksizin bu protokole sahip tüm parçalar ile çalışır |
2- I2C Protokolünün Amacı
- I2C protokolü normalde çok fazla pin ayrılması gereken parçaların sadece 2 adet pin kullanılarak sürülmesini amaçlar
- I2C protokolünde sadece 2 pin ayrılarak aynı hat üzerine birçok RAM , EEPROM , RTC vb. parça bağlanıp kullanılabilir bu da fazladan pin ihtiyacını ortadan kaldırır.
- I2C protokolünde hat üzerine başka MCU larda bağlanabilir bunlar gerekli zamanlarda hem master hem slave olarak yerini alabilir.
3- I2C Protokolü İçin Gerekli Yapının Oluşturulması
- Temelde fazladan bir devreye gerek yoktur sadece SDA ve SCL uçları dirençler ile pull-up yapılırlar.
- I2C protokolü 4 adet hız aralığına sahiptir.
- 100 kbit/s
- 400 kbit/s
- 1 mbit/s,
- 3,2 Mbit/s hızlarında çalışabilir. Ancak kullanılan parçaların bu hızları desteklemesi gerekmektedir.
- Kullanılacak dirençler için bir hesaplama yolu bulunsa da ben burada artık standartlaşmış değerleri vereceğim, çünkü doğru hesap yapılabilmesi için I2C protokolüne bağlanacak parçalara giden bakır yolların dirençlerinin vs. hesaplanması gerekmektedir.
- Aşağıdaki tablodan kullanılacak hıza uygun pull-up direnç değerleri seçilebilir
Mod Hız Direnç Aralığı Standart Mod 100 Khz 5kΩ – 10kΩ Hızlı Mod 400 Khz 2kΩ – 5kΩ Yüksek Hızlı Mod 3,4 Mhz 1kΩ - I2C protokolü için kullanılacak hattın da çok fazla uzun olmaması gerekmektedir. Bu iletişim protokolü kısa mesafe için uygundur.
4- I2C Protokolü Nasıl Çalışır ?
- I2C protokolü temelde 4 adımdan oluşur bunlar
- START – İletişim başlangıç işareti
- ADRES – İletişim kurulacak parçanın adresinin ve okuma-yazma yapılacağına dair işaret
- DATA – Okunacak yada yazılacak veri trafiğinin başlatılması
- STOP – İletişim durdurulması
- İşlemlerden sonra gelen onay (ACK/NACK) kodu
- Anlatımlarda “1” pin in yükseğe çekilmesi “0” ise aşağı çekilmesi demektir.
4A- I2C “START” İletişim Başlangıç İşareti
- İletişime başlanmadan önce mutlaka START işareti gönderilerek hatta bağlı olan tüm parçalar bekleme konumuna geçirilir.
- START işareti için,
- SCL=1 SDA=1 durumunda iken
- SCL=1 SDA=0 yapılır böylece işaret gönderilmiş olur.
- Dikkat edilmesi gereken nokta START işaretinden sonra iletişimin devamı için SDA=1 yapılacaktır ancak SDA=1 yapılmadan SCL=0 yapılmalıdır aksi halde SCL=1 iken SDA=1 yapılırsa hataya yol açar.
4B- I2C Adres ve İşlem İşareti
- Parçaların adresleri 7 bittir. Yapılacak işlemi belirten veri ise 1 bittir. Yani toplamda 8 bit (1byte) gönderilecektir.
- Buna göre eğer
- Yazma işlemi yapılacaksa 8. bit “0” olmalıdır.
- Okuma işlemi yapılacaksa 8. bit “1” olmalıdır.
- Örnek olarak adres 1001001 ise ve yazma yapılacaksa gönderilecek blok 10010010 olmalıdır
- Adres gönderildikten sonra parçadan onay kodu olan ACK gelir. Bunu 4E maddesinde detaylı açıklayacağım
4C – I2C “DATA” Veri Transferi
- Veriler 8 bit olarak gönderilirler.
- Veri gönderilirken SDA ve SCL konumları aşağıdaki gibidir
- SDA pinine veri yüklenmeden önce mutlaka SCL=0 yapılmalıdır.
- SCL=0 SDA=1 veya 0 şeklinde(SDA gönderilecek bitlere göre ayarlanır)
- SCL=1 yapıldığında SDA da yüklenen veri gönderilmiş olur.
- Her veri gönderildikten sonra (8 bit gönderildiğinde) bize iletişimdeki parçadan onay kodu ACK gelir. Bunu 4E maddesinde detaylı açıklayacağım
- Veri okunurken SDA ve SCL konumları aşağıdaki gibidir
- Veri okumada yazmanın tersi olarak SCL=0 dan SCL=1 yapılır
- Bu durumda SDA pinindeki veriler okunur.
- Her veri okunduğunda ( 8 bit okunduğunda) eğer okumaya devam edeceksek parçaya kendimiz bir onay kodu ACK yollarız eğer okumak son bulacaksa o halde NACK kodu göndeririz böylece parça okuma işleminin sona erdiğini belirtir.
4D- I2C “STOP” İletişim Durdurma İşareti
- STOP durdurma işareti tüm iletişimi sona erdirir.
- STOP işareti için
- SCL=1 SDA=0 durumundan
- SCL=1 SDA=1 durumuna geçildiğinde tüm iletişim sonlandırılır.
- Yine burada dikkat etmemiz gereken nokta pull-up yapıldığından dolayı SDA ve SCL daima 1 konumundadır. SDA=0 da SDA=1 yapmak için önce SDA=0 konumuna gelmeliyiz bu sebeple SDA ayarlanmadan önce daima SCL=0 yapılmalı SDA pini sonradan ayarlanmalıdır.
4E- I2C Onay İşareti (ACK – NACK)
- İletişim kuracağımız parçaya adres veya veri gönderdiğimizde bize onay kodu gönderir. Bu onay kodu ACK (acknowledge) olarak geçer tam terside NACK tır.
- Bu onay geldiğinde SDA pin i normalde pull-up tan dolayı “1” durumunda iken “0” durumuna geçer böylece ACK onay kodu gelmiş olur.
- Veri okumada ise tam tersi olarak okuma yaptıkça biz parçaya ACK göndererek okumanın devam edeceğini bildiririz. En son okuma biteceği zaman 9. bit i 0 yapmak yerine 1 olarak bırakırız böylece NACK gönderilmiş olur ve iletişim durdurulur.
- Bu sebeple adres gönderildiğinde yada veri yazma yapıldığında daima 9. bit kontrol edilir eğer onay kodu gelmez ise tüm işlem iptal edilip yeniden START işareti gönderilerek iletişime yeniden başlanmalıdır.
- Aşağıdaki grafikten tam bir veri iletişimini inceleyelim
- Yukarıda görüldüğü gibi START işaretinden sonra 7 bit adres ve beraberinde yazma yapılacağını bildiren 8. bit gönderilmiş.
- Bu durumdan sonra SCL ile clock gönderilmeye devam eder . 7 bit adres ve 1 bit işlem işaretinden sonra gönderilen clock ile iletişime geçtiğimiz parça SDA pinini sıfıra çekerek ACK yani onay gönderir. Onay gelmez ise iletişim yenilenmelidir. Bu durumdan sonra gönderilecek yada okunacak tüm veriler başta adresi belirtilen parça ile yapılacaktır.
- Adres parça tarafından onaylandı ve yazma yapacağımızı belirtmiştik. Şimdi 8 bit verimizi gönderiyoruz ve yine 9. bitte onay kodunu bekliyoruz parça yine SDA pinini sıfıra çekiyor ve veri yazmanın başarılı olduğunu onaylıyor.
- NOT: Eğer yazma değilde okuma yaparsak ACK kodunu biz oluşturuyoruz yani 8 bit veriyi okuduktan sonra SDA pinini sıfıra çekiyoruz böylece okuma işlemi devam ediyor. Okuma biteceği zaman son okunan 8 bitin ardından bu sefer NACK gönderiyoruz yani SDA yı 1 durumunda bırakıp sadece clock gönderiyoruz böylece parça okuma işleminin bittiğini anlıyor.
- Ardından STOP işareti ile iletişim sonlandırılıyor. İstenirse arka arkaya durmaksızın veri yazılmaya devam edebilir bunda bir kısıtlama yoktur.
- Yazma yaparken birden okuma yapmak istersek yine START işareti ile beraber aynı yolu takip ediyoruz.
- Aşağıda osiloskopta gerçek bir iletişimi görebilirsiniz.
I2C Protokolü Sonuç
- I2C protkolü hakkında bilgi sahibi oldunuz. Yukarıdaki işleyiş genel bir iletişimi anlatmaktadır.
- Her parçanın kendine has iletişim sistemi vardır yani bir I2C RAM e veri yazılacağı zaman kendi adresinden hariç birde verinin yazılacağı bölgenin adresi gönderilir kimi parçalarda direk yazılır içerisinde pointer her veri yazılışta kendiliğinden bir artar yani temel sistem aynı olmak ile beraber işleyişler farklı olabilir bunları parçaların data sheet lerinden bakarak öğrenmelisiniz.
- Yeni eklenen bir özellik olarak bazı parçalar artık 10 bit adrese sahip olabilmektedir. Bunun da ayrıca bir gönderim yöntemi vardır ama bunu şu an kullanmadığım için ezbere eklemek istemedim . İleri ki projelerimde denk gelince gerekli güncellemeyi yapacağım ancak yine bu temel sistem geçerlidir, mevcut sistem ve kütüphane fonksiyonları ile bu işlem yapılabilmektedir fazladan bir eklemeye gerek duyulmamıştır.
- Protokolü öğrendiğinize göre artık MikroC de yazdığım I2C Kütüphanesine geçebiliriz.
I2C MikroC Kütüphanesi
- Bu kütüphane PIC18 lere uygun yazılmıştır. Çok ihtiyaç halinde PIC16 içinde dönüşüm yapılabilir.
- Kütüphanenin amacı PIC in I2C modülünden bağımsız olarak istenen 2 dijital pin ile I2C işlemlerini yapmaktır.
- Genelde I2C kütüphanelerinde START ve RESTART fonksiyonları bulunabilir bu kütüphanede START-BAŞLAT fonksiyonu her iki işlem içinde kullanılmaktadır.
- PIC modülü kullanılan yazılımlarda iletişim hızı fonksiyon ile belirlenmektedir bunun amacı gerekli bekleme süresini PIC o modül içerisinde hesaplamaktadır ancak biz burada modülden bağımsız olduğumuz için gerekli hız ayarı kütüphane dosyası ile beraber verilen .h Header dosyası içerisinden ayarlanmaktadır.
- Hız hesabı yapmak için ;
- 1 khz = 1000 us
- 100 khz = 10 us
- 400 khz = 2,5 us olmalıdır.
- Şimdi fonksiyonları görelim
1- I2C Fonksiyonları
- Fonksiyonlar tüm I2C iletişim ihtiyacını karşılayacak temel fonksiyonlardır.Bunları kullanarak tüm I2C parçaları ile haberleşebilirsiniz.
– I2C_ILETISIM_BASLAT Fonksiyonu
Fonksiyon : void I2C_ILETISIM_BASLAT()
Amacı : I2C iletişimini başlatır aynı zamanda restart yerinede kullanılır
Parametreler : Bulunmuyor
Kullanım Şekli :
I2C_ILETISIM_BASLAT();//I2C iletişimini başlatır
Geri Bildirim : Void tipinde olduğundan geriye herhangi bir değer döndürmez
– I2C_ILETISIM_DURDUR Fonksiyonu
Fonksiyon : void I2C_ILETISIM_DURDUR()
Amacı : İletişimi sonlandırır
Parametre : Bulunmuyor
Kullanım Şekli :
void I2C_ILETISIM_DURDUR()//iletişimi her durumda sonlandırır
Geri Bildirim : Void tipinden olduğundan geriye herhangi bir değer döndürmez
– I2C_VERI_YAZ Fonksiyonu
Fonksiyon : unsigned char I2C_VERI_YAZ(unsigned char veri)
Amacı : Bağlantı kurulan parçaya 8bit veri gönderir
Parametre :
- Veri : Gönderilecek 8bit veri bu parametreye yüklenir
Kullanım Şekli :
I2C_VERI_YAZ(0b01010101)//veri yazma ve iletişimdeki slave cihazın register adresleri bu fonksiyon ile yollanır
Geri Bildirim :
- Geriye 1 değeri döndürüyorsa işlem başarılı demektir
- Geriye 0 değeri döndürüyorsa işlem başarısız demektir
– I2C_VERI_OKU Fonksiyonu
Fonksiyon : unsigned char I2C_VERI_OKU(unsigned char sonlandir)
Amacı : Bağlantı kurulan parçadan 8 bit veri okur
Parametre :
- sonlandir : Okuma yapılırken eğer okuma devam ediyorsa “sonlandır=0” (ACK) yapılır böylece parça okumanın devam edeceğini bilir ancak okuma sonlandırılacaksa son kez okuma yapılırken “sonlandir=1″(NACK) yapılarak okuma işlemi sonlandırılır.
Kullanım Şekli:
I2C_VERI_OKU(1);// bir kez okuma yapılır ve okuma işlemi sonlandırılır
Geri Bildirim:
- Okunan 8 bitlik değeri geriye döndürür
– I2C_ADRES_GONDER Fonksiyonu
Fonksiyon : unsigned char I2C_ADRES_GONDER(unsigned char adres, unsigned char islem)
Amacı : İletişim kurulacak parçanın adresini gönderim bağlantıyı sağlar, ayrıca yapılacak işlemin yazma yada okuma olup olmadığını belirler
Parametre:
- adres : bağlantı kurulacak parçanın 7 bit adresi yazılır. Bu adres parçanın data sheet inde yazmaktadır.
- islem : Yapılacak işlemi belirler
- işlem=0 ise yazma yapılacak demektir
- işlem=1 ise okuma yapılacak demektir
Kullanım Şekli:
I2C_ADRES_GONDER(0b01101000,0);// 7 bit adres gönderildi ve yazma yapılacağı belirtildi I2C_ADRES_GONDER(0b01101000,1);// 7 bit adres gönderildi ve okuma yapılacağı belirtildi
Geri Bildirim :
- Geriye 1 değeri döndürüyorsa işlem başarılı demektir
- Geriye 0 değeri döndürüyorsa işlem başarısız demektir
2- Fonksiyonların Uygulanması
- Aşağıda DS1307 saat entegresi ile yapıtğım basit iletişim örneğini göreceksiniz. Ancak tekrar belirtmek gerekirse her parçanın iletişim kuralı ve sırası farklıdır bu sebeple bu kuralı ilgili parçanın data sheetinden öğrenmelisiniz.
- I2C ile kullandığım her parça içinde ayrıca kütüphane yazıp yayınlayacağım
2A- Pin Tanımlamasının Yapılması
- I2C için hangi pinleri kullanıyorsak bu kısımda onları belirtiyoruz
//I2C Pin Tanımlaması sbit I2C_SDA at RA5_bit; sbit I2C_SCL at RE0_bit; sbit I2C_SDA_VERI at LATA5_bit;//27.01.2019 güncellemesi ile eklendi sbit I2C_SDA_Direction at TRISA5_bit; sbit I2C_SCL_Direction at TRISE0_bit;
2B- İletişim Hızının Belirlenmesi
- Bağlantı hızını .h header dosyasındaki ilgili yerden bekleme süresini arttırıp azaltarak ayarlıyoruz.
- Genel olarak 100kHZ iletişim için 10 değeri uygundur.
#define I2C_ILETISIM_HIZI Delay_us(10);// iletişim hız ayarlaması
2C- I2C Örnek Çalışma
- DS1307 entegresi için hazırladığım çok basit bir çalışma. En azından fikir vermek açısından faydalı olabilir
void main() { unsigned char veri[8];//okunan verilerin yazılması için oluşturulan dizi unsigned char txt[5];//okunan değeri GLCD de yazdırmak için çevrim işlemleri için oluşturuldu unsigned i =0;//onay kontrol koşulu için eklendi ADCON1=13;//PIC in A/D port ayarı CMCON=7;//comparatorler kapatıldı SAP1024_INIT (240,128,6);// sonuçları GLCD de görmek için eklendi I2C_ILETISIM_BASLAT();//iletişim başladı do{i=I2C_ADRES_GONDER(0b01101000,0);}while(i==0);//adres gönderilir ve onay gelip gelmediği denetlenir I2C_VERI_YAZ(0b00000000);//register seçiliyor//ds1307 registeri seçilir I2C_VERI_YAZ(0b10000000);//yazma işlemi yapılır I2C_VERI_YAZ(0b00000000);//yazma işlemi yapılır I2C_VERI_YAZ(0b00000000);//yazma işlemi yapılır I2C_VERI_YAZ(0b00000000);//yazma işlemi yapılır I2C_VERI_YAZ(0b00000000);//yazma işlemi yapılır I2C_VERI_YAZ(0b00000000);//yazma işlemi yapılır I2C_VERI_YAZ(0b00000000);//yazma işlemi yapılır I2C_ILETISIM_DURDUR();//iletişim durdurulur //iletişim tekrar başlatılır ve ds1307 aktif hale getirilir I2C_ILETISIM_BASLAT(); I2C_ADRES_GONDER(0b01101000,0); I2C_VERI_YAZ(0b00000000);//register seçiliyor I2C_VERI_YAZ(0b00000000); I2C_ILETISIM_DURDUR(); // Bu bölümde ds1307 den sürekli saniye verisi ham olarak okunur ve GLCD de yazdırılır while(1) { I2C_ILETISIM_BASLAT(); I2C_ADRES_GONDER(0b01101000,0); I2C_VERI_YAZ(0b00000000);//register seçiliyor I2C_ILETISIM_DURDUR(); I2C_ILETISIM_BASLAT(); I2C_ADRES_GONDER(0b01101000,1); veri[0]=I2C_VERI_OKU(1); I2C_ILETISIM_DURDUR(); ShortToStr(veri[0],txt); SAP1024_YAZI_YAZMA(1,1,txt); delay_ms(1000); } }
Sonuç
- Dersin sonuna geldik I2C kütüphanesi ile sizde kullanacağınız parçalar için kütüphane hazırlayabilirsiniz. Böylece işlemlerinizi daha kolay ve karmaşık hale gelmeden yapabilirsiniz.
- Sorularınızı “Foruma” sorabilirsiniz.
Kütüphane Dosyaları
- I2C MikroC Kütüphanesi- .mcl – (ÜCRETSİZ)
Bağlantıyı Görmek İçin Giriş Yapın ya da Ücretsiz Üye Olun
Yararlanılan Belgeler
- I2C-bus specification and user manual-Ana Kaynak
- (SIO)
- AT03155 Real-Time-Clock Calibration and Compensation
- Eğitim Amaçlı Mikrobilgisayar Sistemleri İçin I2C Seri Haberleşme Protokolü ile Analog Arayüz Tasarımı
- I2C ECE353 Introducton to Mcroprocessor Systems
- I2C _ Android Things
- I2C Noise Glitch Filtering
- I2C Pull Up Resstors – Rhengold HeavyRhengold Heavy
- I2C Tutorial
- I2C_Bus_specification
- I2CBusTechnicalOverview
- Kontrol Sistemlerinde Kullanılan Veri Haberleşmesi Teknolojileri
- MİKROİŞLEMCİ SİSTEMLER
- Serial Communication
- Serial Interfaces SPI, I2C, UART Demystified
- The Essential I2C Tutorial_ All you need to know about I2C.
- Understanding the I2C Bus
- USB & RS232 TO I2CSPI ADAPTOR & CONTROLLER
- USB-I2C HW145-471959
- USB-to-I2C_Hardware_User_Manual
- Using the I2C Bus with HCS12 Microcontrollers
- Using the I2C Interface on the ATmega328P and MC908JL16
- Using the PICmicro® SSP for Slave I2CTM Communication
This post is also available in: English (İngilizce)