İçindekiler:

ATtiny ve ATmega için I2C Bus: 8 Adım
ATtiny ve ATmega için I2C Bus: 8 Adım

Video: ATtiny ve ATmega için I2C Bus: 8 Adım

Video: ATtiny ve ATmega için I2C Bus: 8 Adım
Video: How I2C Communication Works and How To Use It with Arduino 2024, Kasım
Anonim
ATtiny ve ATmega için I2C Veri Yolu
ATtiny ve ATmega için I2C Veri Yolu

Atmel AVR mikro denetleyicilerini seviyorum! Bu Eğitilebilir Kitapta açıklanan Getto Geliştirme Sistemini kurduğumdan beri, özellikle AVR ATtiny2313 ve ATmega168 ile deneyler yapmaktan hiç zevk almadım. Hatta anahtarları giriş olarak kullanma konusunda bir Instructable yazacak kadar ileri gittim ve Getto Geliştirme Sistemi konseptini CPLD'lere genişlettim. Yakın tarihli bir proje sırasında, kontrol değerlerini ayarlamak için birkaç anahtara ihtiyacım vardı. AVR'lerde yeterli G/Ç pini yoktu, bu yüzden bir şeyler düşünmem gerekiyordu. Klavyeli ve ekranlı karmaşık bir giriş sistemini deneyebilirdim ama ATtiny2313'ün kaynakları tükenebilirdi. Neyse ki Atmel, basit bir iki telli arabirimle ek yongalara (bellek veya G/Ç bağlantı noktaları gibi) bağlanabilen bir arabirim ekleyerek bu sorunu aşmanın bir yolunu sağlamıştır. Bu doğru, bir AVR'de sadece iki G/Ç pini kullanarak birçok ek G/Ç pinine ve diğer kaynaklara da erişebiliriz. Bu iki kablolu arayüz resmi olarak Inter-Integrated Circuit bus veya sadece I2C bus olarak bilinir ve NXP tarafından Philips Semiconductors iken icat edilmiştir. Bu Eğitilebilir Tabloyu okuyorsanız, muhtemelen I2C veri yolunu duymuşsunuzdur ve hatta bir PIC veya başka bir mikro denetleyicide kullanmış olabilirsiniz. Kavramsal olarak çok basit olmasına ve AVR'lerdeki donanım kaynakları tarafından desteklenmesine rağmen, I2C veri yolunu kullanmak için yazılım sürücüleri hala gereklidir. Atmel, Uygulama Notları sağlar (bu Talimatta daha sonra bulunan Kaynaklara bakın), ancak bunlar eksiktir ve başka bir AVR cihazıyla iletişim kurmanın ötesinde herhangi bir örnek göstermez. AVR'ler. Bunun yerine, ATtiny2313 ve ATmega168 aygıtları için Atmel sürücülerinin genişletilmiş sürümlerini sağlayacağım, bunları kullanırken geçerli olan gereksinimleri ve kısıtlamaları açıklayacağım ve size I2C aygıtlarının çalışma örneklerini göstereceğim. Bu Eğitilebilir Tablo üzerinde çalıştıktan sonra, AVR projelerinizde I2C veri yolunu başarıyla kullanabileceksiniz. Açıkçası, yalnızca biriyle ilgileniyorsanız, küçük veya MEGA için sürücüleri görmezden gelebilirsiniz. I2C veri yolu hakkında daha fazla bilgi edinmek isteyenler için uygun materyallere bağlantılar sağlayacağım.

Adım 1: Tüm Bu I2C Şeyleri Nedir?

Tüm Bu I2C Şeyleri Nedir?
Tüm Bu I2C Şeyleri Nedir?
Tüm Bu I2C Şeyleri Nedir?
Tüm Bu I2C Şeyleri Nedir?
Tüm Bu I2C Şeyleri Nedir?
Tüm Bu I2C Şeyleri Nedir?
Tüm Bu I2C Şeyleri Nedir?
Tüm Bu I2C Şeyleri Nedir?

I2C veri yolu, birden fazla cihazı birbirine bağlayabilen ve veri alışverişi yapmalarına olanak tanıyan basit, iki telli bir bağlantıdır. En basit biçiminde, birden çok bağımlı aygıtla iletişim kuran bir ana aygıt vardır. Tüm cihazlar, I2C veri yolunun iki kablosuna paralel olarak bağlanır. İki kablo SCL ve SDA olarak bilinir. SCL saat hattıdır ve ana cihaz tarafından kontrol edilir. SDA, çift yönlü veri hattıdır. Verileri aktarmak için master, bir bitlik okuma/yazma bayrağıyla birleştirilmiş bir bağımlı adres gönderir. Bir yazma isteniyorsa, master, adreslenen slave'e veri göndermeye devam edecektir. Bir okuma istenirse, köle veri ile yanıt verecektir. İşlemleri koordine etmek için, SCL ve SDA hatları master ve slave tarafından çeşitli koşulları bildirmek üzere manipüle edilir. Bunlar START, STOP, ACK (onay) ve NAK (onay yok) içerir. Bu koşulların ayrıntıları sürücüler tarafından ele alınır. Aranızdaki gerçek meraklılar, bu Eğitilebilir Yazının sonunda verilen bağlantılarda tüm ayrıntıları öğrenebilirler. Elektrik gereksinimleri oldukça basittir. Master ve slave Vcc için aynı seviyeyi kullanmalı, topraklar bağlı olmalı, SCL ve SDA hatları Vcc'ye çekilmelidir. Çekme dirençlerinin değeri, veriyolundaki toplam kapasitansa dayalı bir hesaplama ile kesin olarak belirlenir, ancak pratikte 1.8K ile 10K arasında herhangi bir değer olabilir. 5.1K ile başlıyorum ve çalışana kadar daha düşük değerler kullanıyorum. Çok sayıda cihazınız veya cihazlar arasında uzun kablo uzunluklarınız olmadığı sürece bu genellikle bir sorun değildir. I2C veriyolundaki nominal veri hızı 100Kbit/saniyedir. 400Kbit/saniye, 1Mbit/saniye ve ötesi hızlar da mümkündür, ancak bu Eğitilebilir Tablodaki sürücüler tarafından desteklenmez. Tüm I2C cihazları 100Kbit/saniye hızında çalışacaktır. ATtiny2313 ve ATmega168'in her biri I2C veri yolunu farklı şekilde uygular. ATtiny2313, SPI veri yolu için de kullanılabilen Evrensel Seri Arabirim (USI) donanımını kullanır. ATmega168, İki Kablolu Arayüz (TWI) olarak bilinen I2C veri yolu için özel donanıma sahiptir. Sürücüler yazıldıktan sonra, bu farklılıklar çoğunlukla kullanıcı için şeffaftır. Önemli bir fark yazılımdadır: ATmega168 I2C sürücüsü, ATtiny2313 için değilken kesintiye dayalıdır. Bu, bir ATmega168 programının I2C veri aktarımlarının gerçekleşmesini beklemesi gerekmediği, yalnızca başka bir aktarım başlatmadan önce veya bir okuma işleminden veri gelene kadar beklemesi gerektiği anlamına gelir. İzlenecek örnekler ve tartışma bunu netleştirmelidir. I2C adresleri 7 bit uzunluğundadır, bu nedenle her birinin benzersiz bir adresi varsa, veri yolunda 127'ye kadar cihaz olabilir. Şekilde gösterildiği gibi, bu 7 bitlik adres bir bit sola kaydırılır ve en az anlamlı bit, adresteki aygıtın bir okuma veya yazma işlemini işaretlemek için kullanılır. Böylece tam köle adresi 8 bitlik bir bayttır. Gerçek adres kısmen cihazda dahili olarak belirlenir ve değiştirilemez (en önemli 4 bit) ve kısmen, yüksek veya düşük olarak bağlanabilen cihaz pinlerine bağlanabilen bitler tarafından belirlenir (3 en az anlamlı bit) belirli bir adres. Kafa karıştırıcı geliyor, ancak bir örnek bunu netleştirecek. PCA8574A veri sayfası, I2C adresinin en önemli dört bitinin her zaman 0111 olacağını gösterir. Sonraki üç bit, AD0, AD1 ve AD2 pinlerindeki ayarlarla belirlenir. Bu pimler, sırasıyla 0 veya 1'i temsil etmek için toprağa veya pozitif voltaj kaynağına (5 volt) bağlanabilir. Bu nedenle, PCA8574 veri sayfasındaki diğer şekilde gösterildiği gibi, olası adres aralığı 38 ila 3F onaltılıktır. Bu nedenle, adres biti ayarlarını değiştirerek, aynı anda 8 PCA8574A'ya kadar I2C veriyolunda olabilir. Her biri yalnızca kendi özel bağımlı adresine yanıt verecektir. Daha fazla G/Ç bağlantı noktasına ihtiyaç duyulursa, PCA8574 kullanılabilir. PCA8574 ve PCA8574A arasındaki tek fark, PCA8574'ün I2C bağımlı adres aralığının 20 ila 27 onaltılık olmasıdır. Belirli bir cihazın adresini belirlemek kafa karıştırıcı olabilir, çünkü bazı veri sayfaları okuma/yazma bitini okuma/yazma bitinin bir parçası olarak kabul eder. adres. Veri sayfasını dikkatlice okuyun ve köle adresinin 7 bit uzunluğunda olacağını unutmayın. Okuma/yazma biti ayrı olarak ele alınmalıdır. Yine, bir örnek yardımcı olacaktır. 24C16 EEPROM için deney yapacağımız veri sayfası, bağımlı adresin ilk (en anlamlı) dört bitinin 1010 olduğunu söylüyor. Sonraki üç bit, A0, A1 ve A2 tarafından belirlenebilir; ancak veri sayfasının daha küçük boyutlu EEPROM'lar olan 24C01 ila 24C08 arasını da kapsadığını unutmayın. Veri sayfasındaki şekil, boyut arttıkça bu adres bitlerinin ayarlarının yok sayıldığını ve 24C16 için tamamen yok sayıldığını göstermektedir. Yani, son üç bit önemli değildir ve 24C16 gerçekten 50 ila 57 onaltılık tüm I2C bağımlı adreslerini kullanır. Slave adreslerinin aralığı aslında 24C16 içindeki farklı bölümleri ele alacaktır. İlk 256 bayt 50h adresinde, sonraki 256 51h'de ve son 256 bayt 57h'de bu şekilde devam eder - toplam 2K bayt için. Bizim de denediğimiz PCF8570 RAM'in adresi bu aralıkta olduğu için 24C16 ve PCF8570 birlikte kullanılamaz.

2. Adım: Bazı I2C Cihazları Sipariş Edin

Artık I2C Bus hakkında biraz bilgi sahibi olduğunuza ve onu kullanmak istediğinize göre, neden bazı I2C cihazlarını denemeleri için sipariş etmeyesiniz ki, yazılımı hazırlarken size doğru yola gelsinler? Uygun cihazlar arasında bir I/ O Arayüz Genişletici (en sevdiğim), bir Statik Ram ve bir EEPROM. Daha pek çok şey var ama bunlar harika bir başlangıç. Kullanacağımız AVR işlemcileri ATtiny2313 ve Atmega168'dir (Arduino'da kullanılır). Bunlarda yeniyseniz, onlar hakkında bilgi edinmek ve Getto Geliştirme Sisteminizi oluşturmak için bu harika Eğitilebilir Yazıya bir göz atın. ATmega168'in bu Eğitilebilir Tablodaki şeması, bu işlemci için Getto Geliştirme Sisteminin nasıl uygulanacağını gösterir. Paralel bağlantı noktası kablosu, ATtiny2313'ünkiyle aynıdır. (Ghetto Development System'in USB versiyonunu denemedim, bu yüzden üzerinde I2C bus'a nasıl erişildiğinden emin değilim. Arduino için aynı.) İşte Digikey parça numaraları. Port Expander:IC I2C I/O GENİŞLETICI 568-4236-5-NDRam:IC SRAM 256X8 W/I2C 568-1071-5-NDEEPROM:IC EEPROM SERİ 16K CAT24C16LI-G-ND

3. Adım: I2C Sürücüleri

Burada I2C veri yolu için sürücü işlevlerinin açıklamaları yer almaktadır. Bunlar, yeni başlayanlar için Atmel Uygulama Notları kullanılarak geliştirilmiştir. Bunu, üzerine inşa edilecek bir temel olarak onlarsız yapamazdım. Geliştirme, WinAVR ve gcc C derleyicisi kullanılarak yapıldı. Her işlemci için saat hızı kısıtlamaları aşağıda açıklanmıştır. Mümkün olan tüm işlemci aroması / saat hızı kombinasyonlarını test edemediğim için, gerçekten test edebildiklerime bağlı kalacağım ve kısıtlamaları ve sınırlamaları belirtmeye çalışacağım. İşte sürücü işlevleri ve bunların nasıl kullanılacağı. Daha fazla ayrıntı ve eksiksiz programlarda kullanılan işlevleri görmek için lütfen örneklere bakın. ATtiny2313 için:Saat Gereksinimi:Sürücüler ATtiny2313 için 1MHz (varsayılan hız) için tasarlanmıştır. Diğer hızlarda koşmak istiyorsanız, sürücülerdeki sabitleri ayarlamanız gerekir. Bunu yapmak için yardıma ihtiyacınız olursa bana e-posta gönderin. Ayrıca Kaynaklar Adımındaki bağlantılardaki Atmel uygulamaları notlarından da bazı ipuçları alabilirsiniz. USI_TWI_Master_Initialise()Bu işlev, I2C modu işlemi için USI donanımını başlatır. Programınızın başlangıcında bir kez arayın. void döndürür ve argüman yoktur. USI_TWI_Get_State_Info()Bu işlev, I2C hata bilgilerini döndürür ve bir I2C işlemi sırasında bir hata meydana gelirse kullanılır. Bu işlev yalnızca bir hata kodu döndürdüğünden, bir hata LED'ini yakmak için TWI_Act_On_Failure_In_Last_Transmission(TWIerrorMsg) işlevini kullanıyorum. Hata kodları USI_TWI_Master.h içinde tanımlanmıştır. Bunu şu şekilde çağırabilirsiniz:TWI_Act_On_Failure_In_Last_Transmission(USI_TWI_Get_State_Info())USI_TWI_Start_Read_Write()Bu fonksiyon I2C cihazlarına tek bayt okumak ve yazmak için kullanılır. Ayrıca birden çok bayt yazmak için kullanılır. Bu işlevi kullanmanın 6 adımı vardır.1)Slave adresini ve gönderilecek veya alınacak veri baytını tutmak için programınızda bir mesaj arabelleği bildirin. unsigned char messageBuf (MESSAGEBUF_SIZE);2)Slave Adresini arabellekteki ilk bayt olarak koyun. Bir bit sola ve VEYA Okuma/Yazma bitinde kaydırın. Okuma/Yazma bitinin Okuma için 1 ve Yazma için 0 olacağına dikkat edin. Bu örnek bir Okuma içindir. messageBuf(0) = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (DOĞRU<<TWI_READ_BIT); 3)Bir Yazma yaparken, yazılacak baytı arabellekteki bir sonraki konuma koyun.4) Mesaj arabelleği ve mesaj boyutu ile birlikte USI_TWI_Start_Read_Write işlevini çağırın.temp = USI_TWI_Start_Read_Write(messageBuf, 2);5) döndürülen değer (bu durumda temp) bir hatanın oluşup oluşmadığını görmek için test edilebilir. Eğer öyleyse, yukarıda tartışıldığı gibi ele alınır. Programlardaki örneklere bakın.6)Bir Okuma istendiyse, okunan bayt arabellekteki ikinci konumda olacaktır. Birden fazla bayt yazılacaksa (örneğin bir bellek aygıtına), bu aynı rutin kullanılabilir. Arabelleği ayarlamak ve rutini çağırmak biraz farklıdır. Arabellekteki ikinci bayt, yazılacak başlangıç bellek adresi olacaktır. Yazılacak veriler sonraki baytlarda olacaktır. Mesaj boyutu, tüm geçerli verileri içeren boyut olacaktır. Yani 6 bayt yazılacaksa, mesaj boyutu 8 olacaktır (bağımlı adres + bellek adresi + 6 bayt veri). USI_TWI_Start_Random_Read() Bu fonksiyon bir I2C cihazından birden fazla bayt okumak için kullanılır, tipik olarak sadece aşağıdakiler için anlamlıdır. bir çeşit hatıra. Bu yordamı kullanmak, iki istisna dışında önceki yordama çok benzer. Okuma/Yazma bitinin ayarı önemli değildir. Bu rutini çağırmak her zaman bir Okuma işlemine neden olacaktır. MesajBoyutu 2 artı okunacak bayt sayısı olmalıdır. Hata oluşmazsa, veriler ikinci konumdan başlayarak arabellekte olacaktır. ATmega168 için:Saat Gereksinimi:The sürücüler, ATmega168 için 4MHz saat hızı için tasarlanmıştır. Örnek kod, bu saat hızının nasıl ayarlanacağını gösterir. Diğer hızlarda koşmak istiyorsanız, sürücülerdeki sabitleri ayarlamanız gerekir. Bunu yapmanız gerekiyorsa bana e-posta gönderin. TWI_Master_Initialise()Bu işlev, I2C modu işlemi için TWI donanımını başlatır. Programınızın başlangıcında bir kez arayın. Void döndürür ve argüman yoktur. Başlattıktan sonra swi() öğesini çağırarak kesintileri etkinleştirdiğinizden emin olun. TWI_Get_State_Info()Bu işlev, I2C hata bilgisini döndürür ve bir I2C işlemi sırasında bir hata meydana gelirse kullanılır. Bu işlev yalnızca bir hata kodu döndürdüğünden, bir hata LED'ini yakmak için TWI_Act_On_Failure_In_Last_Transmission(TWIerrorMsg) işlevini kullanıyorum. Hata kodları TWI_Master.h'de tanımlanmıştır, ancak bir hata LED'inde sinyal vermek için değiştirilmiştir. Ayrıntılar için örnek koda bakın. Bunu şu şekilde çağırabilirsiniz:TWI_Act_On_Failure_In_Last_Transmission(TWI_Get_State_Info())Hata denetiminin, I2C işleminin tamamlandığından emin olarak (aşağıda açıklanan işlev) ve ardından global durum word'ünde biraz test ederek yapıldığını unutmayın. TWI_Start_Read_Write()TWI_Start_Random_Read() iki işlev, yukarıda açıklanan karşılık gelen işlevlerle aynı şekilde çalışır, ancak birkaç istisna dışında. Herhangi bir hata değeri döndürmezler. Okunan veriler arabelleğe aktarılmaz. Bunu yapmak aşağıda açıklanan fonksiyonla yapılacaktır. TWI_Start_Random_Read çağrılırken, messageSize istenen veri bayt sayısı artı bir olmalıdır, iki değil. ATmega168 için I2C sürücüsü kesintiye dayalıdır. Yani, I2C işlemleri başlatılır ve ardından ana rutin çalışmaya devam ederken bağımsız olarak yürütülür. Ana rutin, başlattığı bir I2C işleminden veri istediğinde, verilerin mevcut olup olmadığını kontrol etmelidir. Durum hata kontrolü için de aynıdır. Ana rutin, hataları kontrol etmeden önce I2C işleminin tamamlandığından emin olmalıdır. Sonraki iki işlev bu amaçlar için kullanılır. TWI_Transceiver_Busy() Hataları kontrol etmeden önce bir I2C işleminin tamamlanıp tamamlanmadığını görmek için bu işlevi çağırın. Örnek programlar bunun nasıl kullanılacağını gösterir. TWI_Read_Data_From_Buffer()I2C sürücüsünün alma arabelleğinden mesaj arabelleğine veri aktarmak için bu işlevi çağırın. Bu işlev, verileri aktarmadan önce I2C işleminin tamamlandığından emin olacaktır. Bu işlev tarafından bir değer döndürülürken, hata bitini doğrudan kontrol etmenin daha güvenilir olduğunu düşünüyorum. İşte nasıl arayacağınız. Mesaj Boyutu, istenen veri biti sayısından bir büyük olmalıdır. Veriler, ikinci konumdan başlayarak messageBuf içinde olacaktır.temp = TWI_Read_Data_From_Buffer(messageBuf, messageSize);

Adım 4: Haydi İnşa Edelim

Hadi yapalım!
Hadi yapalım!
Hadi yapalım!
Hadi yapalım!
Hadi yapalım!
Hadi yapalım!
Hadi yapalım!
Hadi yapalım!

I2C Schematics.zip dosyasını indirerek başlayın. Şemaları ve örnek program dosyalarını tutmak için çalışma alanınızda bir I2C klasörü oluşturmak isteyebilirsiniz. Şemaları bu dizine açın. I2C Schematics adlı bir klasör bulacaksınız. Tiny I2C.pdf adlı dosyayı açın. Bu şema, ATtiny2313 Getto Geliştirme Sistemini ve PCA8574A I/O Port Expander'ı (etrafında büyük kesikli kutuya sahiptir) gösterir. Bağlantı Noktası Genişletici devresi bir devre tahtası üzerine kurulmuştur. Bu devrelerin neye benzediğini görmek için fotoğraflara bakın. Gerçekten oldukça basitler. Şemanın ATtiny2313 kısmı, üç yanıp sönen ışığı (LED1, 2 ve 3, artı R4, 5 ve 6) ve buna bağlı bir buton (S1) ile Getto Geliştirme Sistemi'nden başka bir şey değil. ek detay. Bu ayrıntı, I2C bus SCL ve SDA hatlarının bağlanmasına izin vermek için çıkarılabilen jumper'ların (JP4, 5 ve 6) eklenmesidir. Jumper'lar programlama için yerinde olmalı, ardından SCL ve SDA'nın bağlanabilmesi için çıkarılmalıdır. Fotoğraflar, jumperların yerinde olduğunu ve çıkarıldığını gösteriyor. Bu jumperların yerleşimi size kalmış, I2C bus'ı kullanmak istiyorsanız onları Getto Geliştirme Sisteminize koymanız yeterli. I2C veri yolu bağlantısı kesilmeli ve atlama telleri programlama için yerleştirilmelidir. I2C veriyolu için yalnızca JP4 ve JP6 ile gerçekten ilgilenmeniz gerektiğini unutmayın. SPI bus'ı kullanmak isteyeceğinizi düşünüyorsanız JP5'i koyun. PCA8574A I/O Port Expander'ı ekmek tahtasına yerleştirmek çok basittir. Vcc (+5 volt) ve Gnd (toprak) bağlantıları sağlayın ve AD0, 1 ve 2'yi toprağa bağlayın (I2C bağımlı adresini 38 hex yapar). Ardından 4 yanıp sönen ışığı ve 4 DIP anahtarını bağlayın. (DIP anahtarlarınız yoksa, sadece kabloları kullanabilirsiniz. Sinyali açık veya kapalı olarak sırasıyla toprağa bağlayın veya yüzer durumda bırakın.) Son olarak, SDA ve SCL'den çekme dirençlerini (R11 ve 12) Vcc'ye bağlayın. Bunlar 3.3K olarak gösterilir, ancak 1.8K ile 5.1K arasındaki herhangi bir değer çalışmalıdır (belki 10K'ya kadar ama bunu denemedim). ATtiny2313'ü programladıktan sonra atlama tellerini çıkarabilir ve test için SDA ve SCL'yi bağlayabilirsiniz. Şimdi ATmega168 için. Buradaki tek kırışıklık, bu işlemci için bir Getto Geliştirme Sistemi kurmamış olabilirsiniz. Durum buysa, sağladığım şema (MEGA I2C.pdf) size nasıl olduğunu gösterecektir. Bu sadece ATtiny2313 versiyonunun bir permütasyonudur. Önceden plan yaparsanız, programlama kablonuzun her iki sisteme de uyacağından emin olabilirsiniz. Temel fark, C2 ve C3'ün eklenmesidir. Bunların yerleştirilmesi için resimlere bakın, çipe çok yakın olmaları gerekir; bunlardan biri aslında çipin altında. Bunlar, özellikle analogdan dijitale dönüştürücüden gürültünün uzak tutulmasına yardımcı olur. Bu çipte I2C veriyolu için gerekli olmadığından SPI veri yolunu kullanmayı planlamıyorsanız jumper'ları takmanız gerekmez. PCA8754A devre tahtasının değişmeyeceğini unutmayın. Sadece SDA ve SCL'yi bağlayacaksın ve gideceksin! Kolay, ha?

Adım 5: Kodlayalım ve Test Edelim

Kodlayalım ve Test Edelim!
Kodlayalım ve Test Edelim!
Kodlayalım ve Test Edelim!
Kodlayalım ve Test Edelim!
Kodlayalım ve Test Edelim!
Kodlayalım ve Test Edelim!

Sürücüleri ve örnek programları oluşturmanın zamanı geldi. ATtiny2313 ve yeni oluşturduğumuz PCA8574A devre tahtası ile başlayacağız. I2C.zip dosyasını I2C çalışma dizininize indirin ve sıkıştırmasını açın. I2C adlı yeni bir klasörünüz olacak. İçinde USI I2C (ATtiny2313 için) ve TWI I2C (ATmega168 için) bulacaksınız. USI I2C'de I_O Port klasörünü bulacaksınız. Bu klasör ilk örnek programımızın kodunu ve USI I2C sürücülerini içerir. WinAVR'ı kullanarak kodu derleyin ve ATtiny2313'e yükleyin. Derin bir nefes alın ve gücü açın. Beklemeniz gerekenler: Güç açıldığında, ATtiny2313'ün PD6 bağlantı noktasındaki LED 1 iki kez yanıp söner. Düğmeye (S1) basana kadar başka bir şey olmaz. Düğmeye her basıldığında, anahtarlar okunur ve ayarları PCA8574A'ya bağlı LED'lerde görüntülenecektir. Anahtarların değerini değiştirin, düğmeye basın ve LED'ler değişmelidir. İşe yaradığını görmenin heyecanını üzerinizden atana kadar bunu yapmaya devam edin. Eğer (Allah korusun!) işler beklendiği gibi çalışmıyorsa, kablolamanızı dikkatlice kontrol edin. I2C hataları, LED3'te (PD4) yanıp sönmelerle bildirilecektir ve muhtemelen SDA ve SCL'nin doğru pinlere bağlı olduğunu ve doğru şekilde çekildiklerini kontrol etmeniz gerektiği anlamına gelir. Hala çalışmıyorsa, hata ayıklama hakkında bilgi edinmek için bu bölümün geri kalanını okuyun. Şimdi geri dönün ve koda bir göz atalım. USI_I2C_Port.c dosyasını açın. Bu örnek programın kodudur. (USI_TWI_Master.c ve USI_TWI_Master.h sürücüleri içerir - merak etmedikçe onları görmezden gelebilirsiniz.) Örneği kendi I2C uygulamalarınızı yönlendirmek için kullanın. Çoğunlukla program, ayarlar da dahil olmak üzere I2C sürücülerini nasıl başlatacağınızı ve kullanacağınızı gösterir. bağımlı adresi ve mesaj arabelleğinin geri kalanını yukarı ve verileri buradan çıkarmak. Ayrıca düğmeyi nasıl devre dışı bıraktığımı ve while döngüsünü nasıl kurduğumu da göreceksiniz. Programın birkaç detayından bahsetmeye değer. Anahtarlardan gelen verilerin, Port Expander üzerindeki LED'lere yazılmadan önce ters çevrildiğini unutmayın. Ayrıca, düzgün çalışması için Bağlantı Noktası Genişletici üzerindeki giriş bağlantı noktalarının Yüksek olarak yazılması gerektiğini unutmayın. Bu ayrıntılar PCA8574A veri sayfasında açıklanmıştır. Veri sayfalarını her zaman dikkatli bir şekilde okuyun! Daha ilginç olanı, koşullu hata ayıklamanın kullanılmasıdır. Program dosyasının başlangıcına yakın bir yerde //#DEBUG tanımla ifadesi bulunur ve kod boyunca serpiştirilmiş #ifdef DEBUG ifadeleri bulunur. DEBUG tanımlanmadığı sürece (iki eğik çizgi satırı bir yorum yapar ve tanımlanmasını engeller), #ifdef - #endif ifadeleri içindeki kod derlenmeyecektir. Ancak işler beklediğiniz gibi çalışmazsa, kodu #define DEBUG yorumsuz olarak yeniden derleyin ve yeniden yükleyin. Programınızın yürütülmesini takip etmek ve işlerin tam olarak nerede yanlış gittiğini bulmanıza yardımcı olmak için kodunu çözebileceğiniz LED'lerde çok daha fazla yanıp sönme alacaksınız. Aslında, ne olduğunu görmek için bunu denemenizi tavsiye ederim. Göreceğiniz şey, program boyunca yürütme ilerledikçe LED 2'nin (PD5'te) yanıp söneceğidir. Anahtarlardan okunan değer, Port Genişletici LED'lerinde görüntülenmeden önce LED 1'de (PD6) yanıp sönecektir. Bu LED'leri kullanarak programı çalışırken izleyebilmelisiniz. Bundan sonra ATmega168 ile çalışacağız; sadece ATtiny2313 ile ilgileniyorsanız bu bölümü atlayın. Hala benimle? İyi. TWI_I2C klasörüne gidin, çalışma dizininizi IO_Port olarak değiştirin ve TWI_I2C_Port.c dosyasını derleyin ve ATmega168'e yükleyin. ATtiny2313'ten SDA ve SCL hatlarını ayırın ve ATmega168'e bağlayın. Gücü ve toprağı bağlayın ve gücü açın. İşlem aynı olmalı! Heyecan azalana kadar oynayın, sonra koda bakalım. TWI_I2C_Port.c'yi açın. Kod, hata işleme ve kesintiye dayalı sürücüleri barındırma dışında neredeyse aynıdır. İşte farklar: I2C veri yolunun düzgün çalışması için saatin 4MHz'e ayarlanması gerektiğini unutmayın. sei(); ifadesi, I2C sürücülerinin başlatılmasından sonra kesintileri açar. Hataları kontrol etmek için belirli bir durum biti test edilir. Bir okuma sırasında, okunan verileri mesaj arabelleğine aktarmak için TWI_Read_Data_From_Buffer işlevi çağrılmalıdır. Yazma sırasında, hataları kontrol etmeden önce aktarımın tamamlandığından emin olmak için while (TWI_Transceiver_Busy()) kullanılmalıdır. Bu son iki işlev, sürücülerin açıklamasında yukarıda açıklanmıştır. Bunun dışında, kod ATtiny2313 ile hemen hemen aynı. DEBUG, bununla deneme yapmak isterseniz de aynı şekilde çalışır.

Adım 6: I2C Belleği Kullanma

I2C Belleği Kullanma
I2C Belleği Kullanma
I2C Belleği Kullanma
I2C Belleği Kullanma
I2C Belleği Kullanma
I2C Belleği Kullanma
I2C Belleği Kullanma
I2C Belleği Kullanma

Artık bir G/Ç Bağlantı Noktası Genişleticisini okumak ve yazmak için I2C veri yolunu kullanmayı öğrendiğimize göre, hem RAM hem de EEPROM olmak üzere I2C belleklerini kullanmaya geçelim. Temel fark, tek bir I2C komutuyla birden fazla baytın belleklere okunabilmesi veya belleklerden yazılabilmesidir. Bu deneylere hazırlanmak için donanımı biraz değiştirmemiz ve devre tahtası üzerinde birkaç yeni devre oluşturmamız gerekiyor. Bazı bellek değerlerini görüntülemek için kullanacağımız için Port Expander devresini saklayın. DIP anahtarlarını PCA8574A'dan çıkarın ve bu pinlere yanıp sönen ışıklar koyun. Yeterli yanıp sönen ışığınız yoksa, P4'ten P7'ye olanları P0'dan P3'e taşıyın. (Görüntülenecek değerler yeterince küçüktür.) Şimdi şematik I2C Ram.pdf'ye bakın ve PCF8570'i devre tahtasına bağlayın. Resime de bir göz atın. Pim 7'yi Vcc'ye bağladığınızdan emin olun. PCA8574A'dan SDA ve SCL için kabloları çalıştırın. Ek pull-up dirençleri gerekmez. EEPROM ile de ilgileniyorsanız, bu devreyi 24C16 için I2C EEPROM.pdf kullanarak da oluşturun, ancak örneğin ATmega168'i kullandığı konusunda uyarılmalıdır. Bu devre gerçekten çok basit. Yukarıda tartışıldığı gibi, adres bitleri göz ardı edilmelidir. Sadece gücü ve toprağı bağlayın. Ram ile denemeyi bitirmediğimiz için henüz SDA ve SCL'yi bağlamayın. Bellek deneylerimize PCA8574A Port Expander ve PCF8570 Ram'a bağlı ATtiny2313 ile başlayacağız. Program Ram'a bazı sayılar yazacak, sonra onları tekrar okuyacak ve Port Expander'da gösterecek. USI I2C altında çalışma dizininizi RAM olarak değiştirin. USI_I2C_RAM.c'yi derlemek ve indirmek için make dosyasını kullanın. I2C sürücü dosyalarının daha önce kullandıklarımızla aynı olduğunu unutmayın. Gücü bağlayın ve LED 1'de (PD6) tek bir yanıp sönme görmelisiniz. Veriler hafızanın ilk 4 baytına yazılacaktır. Düğmeye basın ve iki bayt geri okunacak ve görüntülenecektir. Bağlantı Noktası Genişletici (P0) üzerinde bir LED ışığı, iki saniyelik bir duraklama, ardından iki LED ışığı (P0 ve P1) görmelisiniz. İki saniye daha duraklayın ve LED'ler kapanmalıdır. Diziyi baştan başlatmak için düğmeye tekrar basın. Hata ayıklama yukarıda anlatılan yönteme benzer. Şimdi koda bir göz atalım. USI_I2C_RAM.c'yi açın. Önceki koda oldukça benzer görünmelidir. Temel farklar, okuma ve yazma belleğinin ayrıntılarıdır. Yazmayı gerçekten yapan çağrıdan önce mesaj arabelleğinin yüklenme biçimine bakın. İlk bayt, okuma/yazma bitinin uygun şekilde ayarlanmış olduğu bağımlı adrestir. Ancak bir sonraki bayt, veri yazmaya başlayacağı bellek adresidir. Ardından belirttiğimiz adresten başlayarak sırayla belleğe yüklenecek olan gerçek veri baytları gelir. Mesaj boyutunu 6 olarak belirtiyoruz. Yani 00 adresinde yazmaya başlıyoruz ve 01, 03, 02 ve 06 değerlerini 00 ile 03 arasındaki hafıza konumlarına yazıyoruz. Hafızadan veriyi geri okumak için USI_TWI_Start_Random_Read fonksiyonunu kullanmalıyız. Mesaj arabelleği, ilk baytta bağımlı adresi ve ikinci baytta başlangıç adresini alır. Ardından, mesaj boyutu, okunacak bayt sayısı artı 2 olarak ayarlanmış işlevi çağırın. Bir okuma ne olursa olsun yapılacağından, okuma/yazma bitinin önemli olmadığını unutmayın. Döndürülen veriler, mesaj arabelleğindeki ikinci konumda başlayacaktır. Veriler okunduktan sonra, Port Expander'da görüntülenmek üzere ters çevrilir ve değerler arasında bir duraklama ile her seferinde bir bayt yazılır. Son olarak, Port Expander LED'leri kapatılır. Port Expander'a yazılanlar, önceki örneklerde yapılanlarla aynıdır. Eğlenmek için, yukarıdaki gibi #define DEBUG ifadesinin yorumunu kaldırabilir ve çok sayıda yanıp sönen LED görebilirsiniz. Başarılı bir deneyden sonra heyecanla dolup taşan ATmega168'e ve bir EEPROM'a geçelim. Çalışma dizininizi TWI I2C altında EEPROM olarak değiştirin. TWI_I2C_EEPROM.c'yi derlemek ve indirmek için make dosyasını kullanın. I2C sürücü dosyalarının daha önce PCA8574A için kullandıklarımızla aynı olduğunu unutmayın. Programı test etmek için ATtiny2313'ün bağlantısını kesin ve ATmega168'i bağlayın. I2C veri yolunu Ram'a bağlı bırakın ve gücü açın. Artık daha fazla veri yazıp okuduğumuz için sonuçlar farklı. PD7'deki LED 1, başlatma sırasında yanıp sönmelidir. Düğmeye basın, veriler bellekten okunacak ve görüntülenecektir. PCA8574 üzerindeki LED'ler şu sırayla yanıp sönmelidir: P1, P0 & P2, (tümü kapalı), P0 & P1, P1 & P2. Son olarak, Port LED'lerinin hepsi sönmelidir. Bunu tekrarlamak için düğmeye tekrar basın. Ah, ama bekleyin, diyorsunuz. Bu program EEPROM için değil mi? Aynı I2C adresindeki bir hafıza cihazına eriştiğimiz için, aynı program hem Ram hem de EEPROM için çalışıyor. Gücü kapatın ve SDA ve SCL'yi Ram'dan EEPROM'a taşıyın ve programı yeniden çalıştırın. Tam olarak aynı şekilde çalışması gerekir. Aynı adresi paylaştıklarından, EEPROM ve Ram'ın I2C veriyoluna aynı anda bağlanamayacağını unutmayın. (Aranızda akıllı olanlar, Ram üzerindeki programlanabilir adres bitlerini değiştirmeyi düşünebilir, ancak bu yine de işe yaramaz. 24C16, Ram için programlanabilecek tüm adres bloğunu kullanır.) Tamam, şu son programa bakalım.. TWI_I2C_EEPROM.c dosyasını açın. Dikkat edilmesi gereken ilk şey, 24C16 EEPROM'un tamamının nasıl ele alınacağını belirttiğimdir. 8 farklı I2C slave adresinde 256 baytlık parçalar halinde erişilebilir. MEMORY_ADDR'nin 50 onaltılık olarak başlangıç adresi olarak nasıl tanımlandığını görün; bu yüzden Ram çalıştı. 24C16'nın diğer bloklarına erişmek istiyorsanız, belirttiğim gibi diğer adresleri kullanın. Belleğe yazmak için nasıl kurduğuma bir bakın. Önce okuma/yazma biti setli bağımlı adres ara belleğe, ardından 00 başlangıç adresi, ardından 16 bayt veriye konur. TWI_Start_Read_Write işlevi, (önceki gibi) mesaj boyutu 18 olarak ayarlanmış veriyi yazmak için çağrılır. Butona basıldığında, verileri geri okumak için TWI_Start_Random_Read ve TWI_Read_Data_From_Buffer kullanırız. Port Expander LED'lerinde her üç bayttan biri görüntülenir. Son olarak, bir sonraki düğmeye basılmasını beklemek için LED'ler kapatılır. Neden 16 bayt yazmayı seçtiğimi merak edebilirsiniz. Veri sayfasını dikkatlice okursanız, daha fazla bayt gönderilse bile 24C16'nın 16 bayt aldığında bir yazma döngüsü yaptığını göreceksiniz. Yani bu kullanmak için güzel bir sayı gibi görünüyordu. Bunu artırmayı seçerseniz, MESSAGEBUF_SIZE boyutunu değiştirmeniz gerekir. Ayrıca TWI_Master.h'deki TWI_BUFFER_SIZE değerini de değiştirmeniz gerekecektir. Bunun nedeni, sürücünün kesme hizmeti yordamı tarafından kullanılmak üzere ileti arabelleğinden verileri kopyalamasıdır. Tebrikler! Artık I2C veri yolunu kendi projelerinizde kullanmaya hazırsınız!

7. Adım: Web Kaynakları

İşte deneyler için kullanılan parçaların veri sayfalarına bağlantılar. Başka bir şey alamazsanız kesinlikle bunları almalısınız. Port ExpanderRamEEPROMBI2C'nin yaratıcısı olan NXP (Philips) tonlarca harika şeye sahip. (URL'lerinde köşeli parantez kullanmayı seviyorlar, bu yüzden onları buraya düzgün bir şekilde ekleyemiyorum. Üzgünüm.] I2C alanına gitmek için Ürünler listesinden Arayüz'ü seçin. Onların I2C sitesine ve sundukları tüm veri sayfalarına ve uygulama notlarına erişim. Özellikle I2C veri yolu açıklaması ve teknik ayrıntılar burada. Atmel'den ATtiny2313 ve ATmega168 veri sayfalarını (veri kitapları?) alın. Atmel uygulama notları burada. AVR310 ve AVR315'e bakın. Kodu da alın. Daha birçok I2C malzemesi için buraya bir göz atın.

8. Adım: Geeks için Notlar

Ayrıntıları öğrenmek isteyen gerçek bir inek için, Atmel Apps Notlarına ve sürücü koduna bakarsanız akılda tutulması gereken bazı şeyler şunlardır:- Bir I2C cihazını adresleme ve komuta etme yöntemi, spesifikasyonun bir parçası değildir! Köle adresi ve okuma/yazma biti dışında, komutlar, modlar vb. belirtilmez ve belirli bir cihaza özeldir. Bunu çok açık hale getirmek için, Atmel örneğinde kullanılan şemanın yalnızca bu örnek için geçerli olduğunu ve hemen hemen standart dışı olduğunu unutmayın.- USI uygulaması TWI uygulamasından birkaç önemli yönden farklıdır. + USI ile saatleme yazılım tarafından sağlanır; TWI ile bir Bit Hızı Üreticisi tarafından sağlanır. + USI yöntemi kesme kullanmaz; TWI yapar. Bu, Mega ailesi (TWI kullanan) birçok başka şey yapabileceğinden ve I2C transferlerine takılmaması gerektiğinden, belirli bir anlam ifade ediyor. USI için kesintiye dayalı bir sürüm kesinlikle mümkündür, bu Eğitilebilir Dosyada uygulanmamıştır. + USI donanımı I2C için optimize edilmemiştir ve yalnızca 8 bitlik aktarımları işleyebilir. Bu, dokuzuncu biti (NACK veya ACK) göndermek için iki transferin gerekli olduğu anlamına gelir. TWI donanımı bunu otomatik olarak halleder. Bu, USI sürücü uygulamasını biraz daha karmaşık hale getirir. + TWI için hata tespiti donanımda işlenir. USI, işleri biraz karmaşıklaştıran bir yazılımla ele alınmasını gerektirir. + TWI donanımı, bağlantı noktasının yapılandırmasını doğrudan kontrol eder. USI donanımı, bağlantı noktası kullanılmadan önce bağlantı noktası bitlerinin yapılandırılmasını gerektirir. Bunu USI için Master_Initialize rutininde göreceksiniz.- Atmel, I2C bus pull-up'ları için AVR port pull-up'larının kullanılmasının mümkün olduğunu iddia ediyor. Bu yaklaşımı işe yarayacak bir yol bulamadım. İki harici direnç kullanmak oldukça basit bir şema gibi görünüyor, bu yüzden buna çok zaman harcamadım.

Önerilen: