- I2C İletişim Protokolü nedir?
- I2C İletişim nasıl çalışır?
- I2C iletişimi nerede kullanılır?
- XC8 Derleyicisini kullanan PIC16F877a ile I2C
- I2C başlık dosyalarını kullanarak programlama:
- Proteus Simülasyonu:
PIC Mikrodenetleyiciler, gömülü projeler için mikroçip tarafından sağlanan güçlü bir platformdur, çok yönlü yapısı, birçok uygulama için yollar bulmasını sağlamıştır ve aşama hala devam etmektedir. PIC eğitimlerimizi takip ediyor olsaydınız, en temellerden başlayarak PIC mikrodenetleyici hakkında geniş bir yelpazede öğretici anlattığımızı fark etmişsinizdir. Şu andan beri, iletişim portalı gibi daha ilginç şeylere girebileceğimiz temel bilgileri ele aldık.
Geniş gömülü uygulamalar sisteminde, hiçbir mikrodenetleyici tüm faaliyetleri tek başına gerçekleştiremez. Bir aşamada, bilgi paylaşmak için diğer cihazlarla iletişim kurması gerekir, bu bilgileri paylaşmak için birçok farklı iletişim protokolü vardır, ancak en çok kullanılanlar USART, IIC, SPI ve CAN'dır. Her iletişim protokolünün kendi avantajı ve dezavantajı vardır. Şimdilik IIC kısmına odaklanalım, çünkü bu eğitimde öğreneceğimiz şey bu.
I2C İletişim Protokolü nedir?
IIC terimi, " Inter Integrated Circuits " anlamına gelir. Normalde I2C veya I kare C olarak veya hatta bazı yerlerde 2 telli arayüz protokolü (TWI) olarak belirtilir, ancak hepsi aynı anlama gelir. I2C, senkronize bir iletişim protokolüdür, yani bilgiyi paylaşan her iki cihaz da ortak bir saat sinyalini paylaşmalıdır. Biri horoz sinyali için, diğeri ise veri göndermek ve almak için kullanılan bilgileri paylaşmak için yalnızca iki tele sahiptir.
I2C İletişim nasıl çalışır?
I2C iletişimi ilk olarak Phillips tarafından tanıtıldı. Daha önce de belirtildiği gibi, iki tele sahip, bu iki tel iki cihaza bağlanacak. Burada bir cihaz ana cihaz olarak adlandırılır ve diğer cihaz köle olarak adlandırılır. İletişim her zaman iki Master ve bir Slave arasında olmalıdır ve olacaktır. I2C iletişiminin avantajı, bir Master'a birden fazla slave'in bağlanabilmesidir.
Tam iletişim, Seri Saat (SCL) ve Seri Veri (SDA) olmak üzere bu iki kablo üzerinden gerçekleşir.
Seri Saat (SCL): Master tarafından üretilen saat sinyalini slave ile paylaşır
Seri Veri (SDA): Verileri Master ve slave arasında ve arasında gönderir.
Herhangi bir zamanda yalnızca kaptan iletişimi başlatabilecektir. Veriyolunda birden fazla slave olduğundan, ana birimin her bir slave'e farklı bir adres kullanarak başvurması gerekir. Ele alındığında, yalnızca o belirli adrese sahip olan merhem, bilgilerle yanıt verirken diğerleri çıkmaya devam eder. Bu şekilde, birden fazla cihazla iletişim kurmak için aynı veri yolunu kullanabiliriz.
I2C iletişimi nerede kullanılır?
I2C iletişimi yalnızca kısa mesafeli iletişim için kullanılır. Akıllı hale getirmek için senkronize bir saat darbesine sahip olduğu için kesinlikle güvenilirdir. Bu protokol, esas olarak bir ana bilgisayara bilgi göndermesi gereken sensör veya diğer cihazlarla iletişim kurmak için kullanılır. Bir mikrodenetleyicinin diğer birçok slave modülle minimum yalnızca kablo kullanarak iletişim kurması gerektiğinde çok kullanışlıdır. Uzun menzilli bir iletişim arıyorsanız RS232'yi denemelisiniz ve daha güvenilir bir iletişim arıyorsanız SPI protokolünü denemelisiniz.
XC8 Derleyicisini kullanan PIC16F877a ile I2C
Bu kadar tanıtım yeterli, içeri girelim ve I2C iletişimi gerçekleştirmek için bir mikro denetleyiciyi nasıl kullanabileceğimizi öğrenelim. Başlamadan önce, bu öğreticinin yalnızca XC8 derleyicisini kullanan PIC16F877a'daki I2C hakkında konuştuğunu açıkça belirtmek gerekir, süreç diğer mikro denetleyiciler için de aynı olacaktır, ancak küçük değişiklikler gerekebilir. Ayrıca, PIC18F serisi gibi gelişmiş mikrodenetleyiciler için derleyicinin kendisinin I2C özelliklerini kullanmak için yerleşik bir kitaplığa sahip olabileceğini, ancak PIC16F877A için buna benzer bir şey olmadığını unutmayın, bu yüzden kendi başımıza bir tane oluşturalım. Burada açıklanan kütüphane, PIC16F877A'nın diğer I2C cihazlarıyla iletişim kurması için kullanılabilecek alt kısımda indirilmek üzere bir başlık dosyası olarak verilecektir.
Her zaman olduğu gibi bir şeye başlamak için en iyi yer veri sayfamızdır. Veri sayfasında I2C ile ilgili ayrıntıları arayın ve hangi kayıtların yapılandırılması gerektiğini kontrol edin. Veri sayfası bunu sizin için zaten yaptığından, ayrıntılı olarak açıklamayacağım. Aşağıda, başlık dosyasında bulunan farklı işlevleri ve programdaki sorumluluklarını açıklayacağım.
void I2C_Initialize ()
Başlatma işlevi, mikro denetleyiciye I2C protokolünü kullanacağımızı söylemek için kullanılır. Bu, SSPCON ve SSPCON2 yazmacında gerekli bitleri ayarlayarak yapılabilir. İlk adım , IIC pinlerini giriş pinleri olarak ilan etmek olacaktır, burada RC3 ve RC4 pinleri I2C iletişimi için kullanılmalıdır, böylece onları giriş pinleri olarak ilan ederiz. Daha sonra, bir MSSP kontrol kayıtları olan SSPCON ve SSPCON2'yi ayarlamalıyız. PIC'yi IIC ana modunda FOSC / (4 * (SSPADD + 1)) saat frekansı ile çalıştırıyoruz. Söz konusu kaydın neden bu şekilde ayarlandığını anlamak için aşağıdaki yorum satırlarında belirtilen veri sayfasının sayfa numaralarına bakın.
Bundan sonra saat frekansını ayarlamalıyız, farklı uygulamalar için saat frekansı değişebilir, bu nedenle kullanıcıdan feq_k değişkeni üzerinden seçim yapıp bunu formüllerimizde SSPADD kaydını ayarlamak için kullanıyoruz.
void I2C_Initialize (const unsigned long feq_K) // IIC'yi ana olarak başlat { TRISC3 = 1; TRISC4 = 1; // SDA ve SCL pinlerini giriş pinleri olarak ayarlayın SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // Saat Hızını Ayarlama pg99 / 234 SSPSTAT = 0b00000000; // pg83 / 234 }
Void I2C_Hold ()
Bir sonraki önemli işlev, mevcut I2C işlemi tamamlanana kadar cihazın yürütülmesini bekletmek için kullanılan I2C_hold işlevidir. Herhangi bir yeni operasyona başlamadan önce I2C operasyonlarının yapılması gerekip gerekmediğini kontrol etmemiz gerekir. Bu, SSPSTAT ve SSPCON2 kayıtlarını kontrol ederek yapılabilir. SSPSTAT, I2C veri yolunun durumu hakkında bilgi içerir.
Program, bir "ve" ve bir "veya" operatörü içerdiğinden biraz karmaşık görünebilir. Olarak kırdığında
SSPSTAT & 0b00000100 SSPCON2 & 0b00011111
Bu , SSPSTAT üzerindeki 2. bitin sıfır olduğundan ve benzer şekilde 0'dan 4'e kadar olan bitlerin SSPCON2'de sıfır olduğundan emin olduğumuz anlamına gelir. Sonra sonucun sıfır olduğunu kontrol etmek için tüm bunları birleştiririz. Eğer sonuç sıfır ise, program bir while döngüsünde kullanıldığından sıfıra ulaşana kadar devam ederse program devam edecektir.
void I2C_Hold () { while ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // IIC'nin işlemde olmadığından emin olmak için kayıtlarda bunu kontrol edin }
Void I2C_Begin () ve void I2C_End ()
I2C veriyolunu kullanarak herhangi bir veri yazarken veya okurken , I2C bağlantısını başlatmalı ve bitirmeliyiz. Bir I2C iletişimine başlamak için SEN bitini ayarlamalıyız ve iletişimi sonlandırmak için PEN durum bitini ayarlamalıyız. Bu bitlerden herhangi birini değiştirmeden önce, yukarıda tartışıldığı gibi I2C_Hold fonksiyonunu kullanarak I2C veriyolunun meşgul olup olmadığını da kontrol etmeliyiz.
void I2C_Begin () { I2C_Hold (); // Programı tut I2C meşgul SEN = 1; // başlayın IIC pg85 / 234 } void I2C_End () { I2C_Hold (); // Programı tut I2C meşgul PEN = 1; // IIC pg85 / 234'ü sonlandır }
Void I2C_Write ()
Yazma işlevi, ana modülden kurtarma modülüne herhangi bir veri göndermek için kullanılır. Bu işlev normalde bir I2C başlatma işlevinden sonra kullanılır ve bunu bir I2C Bitiş işlevi izler. IIC veriyoluna yazılması gereken veriler, değişken verilerden geçirilir. Bu veriler daha sonra I2C veriyolu üzerinden göndermek için SSPBUF tampon yazmacına yüklenir.
Normalde bir veri yazmadan önce bir adres yazılır, bu yüzden yazma işlevini iki kez kullanmanız gerekir, bir kez adresi ayarlamak için ve diğer zaman gerçek verileri göndermek için.
void I2C_Write (işaretsiz veriler) { I2C_Hold (); // Programı tut I2C meşgul SSPBUF = veri; // pg82 / 234 }
imzasız kısa I2C_Read ()
Bilmemiz gereken son işlev, I2C_Read işlevidir. Bu fonksiyon, şu anda I2C veriyolunda bulunan verileri okumak için kullanılır. Otobüse bir değer yazması için bir slave istendikten sonra kullanılır. Alınan değer SSPBUF içinde olacaktır, bu değeri işlemimiz için herhangi bir değişkene aktarabiliriz.
Bir I2C iletişimi sırasında, Ana birim tarafından talep edilen veriyi gönderdikten sonra ikincil birim, onay biti olan başka bir bit gönderecektir, bu bit aynı zamanda iletişimin başarılı olduğundan emin olmak için ana birim tarafından kontrol edilmelidir. Onay için ACKDT bitini kontrol ettikten sonra, ACKEN biti ayarlanarak etkinleştirilmelidir.
işaretsiz kısa I2C_Read (işaretsiz kısa ack) { imzasız kısa gelen; I2C_Hold (); RCEN = 1; I2C_Hold (); gelen = SSPBUF; // SSPBUF I2C_Hold () 'a kaydedilen verileri alın ; ACKDT = (ack) A 0: 1; // ack bitinin alındığını kontrol edin ACKEN = 1; // pg 85/234 geri dönüş; }
Yani, bu işlevler bir I2C iletişimi kurmak ve bir cihazdan veri yazmak veya okumak için yeterli olmalıdır. Ayrıca, I2C iletişiminin gerçekleştirebileceği birçok başka işlev olduğunu da unutmayın, ancak basitlik adına bunları burada tartışmıyoruz. Ürünün tam olarak çalıştığını öğrenmek için her zaman veri sayfasına başvurabilirsiniz.
PIC16F877A I2C iletişimi için başlık dosyasıyla birlikte kodun tamamı bağlantıdan indirilebilir.
I2C başlık dosyalarını kullanarak programlama:
Artık bir I2C iletişiminin nasıl çalıştığını ve bunun için oluşturulan başlık dosyasını nasıl kullanabileceğimizi öğrendiğimize göre, başlık dosyasını kullanacağımız ve I2C satırlarına bazı değerler yazacağımız basit bir program yapalım. Daha sonra bu programı simüle edeceğiz ve bu değerlerin otobüse yazılıp yazılmadığını kontrol edeceğiz.
Her zaman olduğu gibi, program aşağıda gösterildiği gibi Yapılandırma bitlerini ayarlayarak ve saat frekansını 20 MHz'e ayarlayarak başlar.
#pragma config FOSC = HS // Osilatör Seçim bitleri (HS osilatörü) #pragma config WDTE = KAPALI // Watchdog Zamanlayıcı Etkin bit (WDT devre dışı) #pragma config PWRTE = AÇIK // Güç Zamanlayıcı Etkinleştirme biti (PWRT etkin) # pragma config BOREN = ON // Brown-out Reset Enable bit (BOR etkin) #pragma config LVP = OFF // Düşük Voltaj (Tek Kaynak) Devre İçi Seri Programlama Etkinleştirme biti (RB3 dijital G / Ç, HV açık MCLR, programlama için kullanılmalıdır) #pragma config CPD = OFF // Veri EEPROM Hafıza Kodu Koruma biti (Veri EEPROM kod koruması kapalı) #pragma config WRT = OFF // Flash Program Hafızası Yazmayı Etkinleştir bitleri (Yazma koruması kapalı; tüm program hafızası EECON kontrolü tarafından yazılabilir) #pragma config CP = OFF // Flash Programı Bellek Kodu Koruma biti (Kod koruması kapalı) #define _XTAL_FREQ 20000000
Bir sonraki adım, az önce tartıştığımız başlık dosyasını eklemek olacaktır. Başlık dosyası PIC16F877a_I2C.h olarak adlandırılır ve yukarıda tartıştığımız bağlantıdan indirilebilir. Başlık dosyasının proje listenizin başlık dosyasına eklendiğinden emin olun, proje dosya yapınız şöyle görünmelidir
Başlık dosyasının proje dosyanıza eklendiğinden emin olduktan sonra, ana C dosyasına başlık dosyasını ekleyin
#Dahil etmek
While döngüsünün içinde I2C iletişimine I2C veri yoluna birkaç rastgele değer yazmaya başlayacağız ve ardından I2C iletişimini sonlandıracağız. Seçtiğim rastgele değerler D0, 88 ve FF. İstediğiniz herhangi bir değeri girebilirsiniz. Ancak simülasyonumuzda doğrulayacağımız için bu değerleri hatırlayın.
while (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __delay_ms (1000); }
Programın tamamı sayfanın altında bulunabilir, onu kullanabilir veya buradan programın tam zip dosyasını indirebilirsiniz. Programı aldıktan sonra derleyin ve simülasyona hazırlanın.
Proteus Simülasyonu:
Proteus, I2C veri yolundaki verileri okumak için kullanılabilen I2C hata ayıklayıcı adında güzel bir araca sahiptir, bu yüzden onu kullanarak bir devre oluşturalım ve verilerin başarıyla yazılıp yazılmadığını kontrol edelim. Tam devre şeması aşağıda gösterilmiştir
Mikrodenetleyiciye çift tıklayarak programımız tarafından oluşturulan hex dosyasını yükleyin. Ardından programı simüle edin. I2C veriyolu hakkındaki tüm bilgileri görüntüleyen bir pencere açılır göreceksiniz. Programımızın penceresi aşağıda gösterilmiştir.
Yazılmakta olan verilere yakından bakarsanız, onların programımızda yazdığımızla aynı olduklarını fark edebilirsiniz. Değerler D0, 88 ve FF'dir. Değerler her 1 saniyede bir yazılır, bu nedenle zaman da aşağıda gösterildiği gibi güncellenir. Mavi ok, master'dan slave'e yazıldığını gösterir, aksi takdirde ters yöne işaret eder. Gönderilen verilere daha yakından bir bakış aşağıda gösterilmektedir.
Bu, I2C'nin neler yapabileceğine dair bir fikirdir, ayrıca birden fazla cihaza veri okuyabilir ve yazabilir. Gelecek eğitimlerimizde I2C protokolü ile çalışan çeşitli modülleri arayüzleyerek I2C hakkında daha fazla bilgi vereceğiz.
Umarım projeyi anladınız ve ondan faydalı bir şeyler öğrenmişsinizdir. Herhangi bir şüpheniz varsa, bunları aşağıdaki yorum bölümüne gönderin veya teknik yardım için forumları kullanın.
Tam kod aşağıda verilmiştir; Tüm kodun bulunduğu başlık dosyalarını buradan indirebilirsiniz.