I2C veri yolu ile çalışmak için Arduino'ya yönelik Wire kütüphanesi. I2C teorisi, Atmel Servo'dan EEPROM ve step motor kütüphaneleri

Çin'den Atmel EEPROM çipi içeren bir paket aldım. Arduino'ya bağlanmak istiyorum. Ama aslında hazır bir kütüphane kullanmak istemiyorum, bunun yerine bunu kendim çözmek istiyorum. Bu nedenle makale biraz hacimli ve sıkıcı olacağı için onu üç bölüme ayıracağız:

  • I2C arayüz teorisi.
  • EEPROM, mikro devremin (AT24C256) ve bağlantımın açıklamaları.
  • Bellekle çalışmak için bir kütüphane yazmak.

Birinci bölüm, I2C ve “Wire” kütüphanesi.

Seri iletişim protokolü IIC(olarak da adlandırılır I2C- Entegre Devreler arası, çipler arası bağlantı). Philips Semiconductors tarafından 1980'lerin başında kontrol elektroniği için basit bir 8 bitlik dahili iletişim veri yolu olarak geliştirildi. Kullanım hakkı paraya mal olduğundan Atmel Pharma adını verdi TWI ama anlamı değişmez.

Nasıl çalışır?

Veri iletimi için iki çift yönlü veri hattı kullanılır. S.D.A.(Seri Veri) seri veri yolu ve SCL(Seri Saat) saat veri yolu. Her iki otobüs de dirençler tarafından pozitif güç barasına çekilir. Sinyallerin iletilmesi/alınması, hattın 0'a, 1'e basılmasıyla gerçekleştirilir. pull-up dirençlerini kullanarak kendini kurar.

Ağda en az bir ana cihaz var ( Usta), veri aktarımını başlatan ve saat sinyallerini ve köleleri üreten ( Köle), liderin talebi üzerine veri ileten. Her bir köle aygıtının, ana aygıta erişmek için kullanılan benzersiz bir adresi vardır. Elbette Master'ın mikrodenetleyicimiz, kölenin ise hafızamız olduğu açıktır. Ana cihaz veriyoluna basmaya başlar SCL belirli bir saflıkla sıfıra ve lastik S.D.A. Bir veya Sıfır'ı geçerek belirli sayıda tıklama için basın veya bırakın. Veri iletimi START sinyali ile başlar, ardından 8 bit veri iletilir ve 9. bit Slave cihaz veri yoluna basarak baytların alındığını onaylar. S.D.A. eksiye . İletim STOP sinyaliyle sona erer .

Kütüphane "Tel".

I2C veri yolu üzerinden cihazlarla veri alışverişini kolaylaştırmak için Arduino için standart bir kütüphane yazılmıştır. Tel Hangi IDE kitine zaten dahil edilmiştir. Aşağıdaki ana işlevlere sahiptir:

Wire.begin(Adres)Veriyolunu başlatmak ve Master veya Slave cihazı olarak bağlanmak için bir kez çağrılır. Adres belirtilmezse Master cihaz olarak bağlanırız.

Wire.beginTransmission(adres) Verilen adresle I2C bağımlı cihazına aktarıma başlar.

Wire.endTransmission() Slave'e veri aktarımını durdurur. İşlev bir bayt değeri döndürür:

  • 0 — başarı.
  • 1 - veri iletim arabelleğini dolduramayacak kadar uzun.
  • 2 — Bir adres iletirken alınan NACK.
  • 3 - Veri iletimi sırasında alınan NACK.
  • 4 - diğer hatalar.

Wire.write() ana birimden gelen bir talebe yanıt olarak ikincil birimden veri yazar veya ana birimden ikincil öğeye iletim için baytları sıraya koyar. Verileri etkili bir şekilde bir ara belleğe yazar. Arabellek boyutu 32 bayt a (eksi 2 bayt adres, aslında 30 bayt) ve işlev arabelleği geçer Wire.endTransmission().

  • Wire.write(değer)- değer: iletilecek değer, bir bayt.
  • Wire.write(dize)-sicim: iletilecek dize, bayt dizisi.
  • Wire.write(veri, uzunluk)- veri: iletilecek veri dizisi, bayt. uzunluk: aktarılacak bayt sayısı.

Wire.read() Bir köleden bir yöneticiye aktarılan veya bir yöneticiden bir bağımlıya aktarılan bir baytı okur. Dönüş değeri baytı: alınan sonraki bayt.

Bunlar kütüphanenin en temel fonksiyonlarıdır, geri kalanına oyun ilerledikçe bakacağız))

İkinci bölüm, EEPROM.

EEPROM Elektrikle Silinebilir Programlanabilir Salt Okunur Bellek) - elektriksel olarak silinebilir programlanabilir ROM (EEPROM), kalıcı bellek türlerinden biri (PROM ve EPROM gibi). Bu tür hafıza bir milyon defaya kadar silinebilir ve verilerle yeniden doldurulabilir.

Bana Atmel'den 32 kbyte kapasiteli AT24C256 çipli hazır bir EEPROM modülü gönderdiler. Bu mucizeyi anlamak için çalışmamız gerekecek veri Sayfası ki bu çok sıkıcı ve İngilizce. Bu yüzden sana çektiğim eziyetin nihai sonucunu vereceğim.

Özellikler:

  • Alçak gerilim ve standart güç kaynağı. VCC = 1,7V ila 5,5V.
  • 400kHz (1,7V) ve 1MHz (2,5V, 2,7V, 5,0V) saat frekansıyla uyumludur.
  • Dayanıklılık: 1.000.000 Yazma Döngüsü.
  • Dahili olarak 32.768 sayfa x 8 bit olarak düzenlenmiştir.

sonuçlar:

  • W.P.— yazma koruması. Eğer pin GND'ye bağlıysa hafızaya veri yazabilirsiniz.
  • A0…A2— cihaz adresini belirten pinler.
  • Vcc- yiyecek artı.
  • GND- yiyecek eksi.
Bellek adresi:

Üç ayakla tanımlanır A0..A2. Eğer bacak Gnd'ye basılırsa bit değeri 0, Vcc'ye basılırsa 1 olur. Mikro devre şunu kullanır: sekiz bitlik adres, son bit işlemin seçiminden sorumludur. Bit değeri yüksekse okuma işlemi başlatılır, düşükse (sıfır) yazma işlemi başlatılır.

Yani, üç pinin tümü GND'ye basılırsa ve belleğe yazmak istersek, cihaz adresi 10100000 gibi görünecektir (“Wire” kütüphanesinde 7 bitlik bir adres kullanılır, her şeyi bir bit sağa kaydırırız) 01010000 0x50).

Verilerin belleğe yazılması:

Kaydetmek için önce hafızaya dönüyoruz adresteki Write biti ile. Daha sonra iki adet 8 bitlik adres (yani 0x8000 adresimiz var), ardından bir veri baytı ve bir STOP sinyali gönderiyoruz. Bundan sonra, EEPROM kalıcı belleğe dahili olarak senkronize edilmiş bir yazma döngüsü tWR'ye (Yazma Döngü Süresi 5 ms) girer. Tüm giriş sinyalleri
bu kayıt döngüsü sırasında devre dışı bırakılır ve EEPROM yanıt vermiyor, kayıt tamamlanana kadar.

Daha da derine ineriz ve veri sayfasında çipin hafızasının şu şekilde organize edildiğini görürüz: 512 sayfalar 64 bayt Yani komut başına 64 byte'a kadar bilgiyi anında yazabiliyoruz. Bunu yapmak için 64 baytlık bilginin tamamını iletiyoruz ve ancak bundan sonra STOP sinyalini gönderiyoruz.

Veri okuma:

Verileri okumak işleri daha ilginç hale getirir. Bellek üç okuma seçeneğini destekler:

  • Mevcut adresi oku;
  • Rastgele adresi oku;
  • Sıralı okuma;

Bellek, güç kapatılıncaya kadar son yazma adresini hatırlar, böylece adresi belirtmeden son baytı okuyabiliriz.

Rastgele bir adresi okumak için baştan başlamamız gerekir yazma komutu gönder ve okumak istediğimiz adresi iletin ( adresin 8 bitlik iki bölümden oluştuğunu unutmayın). Daha sonra bir okuma komutu gönderin ve gerekli baytı alın, her şeyi STOP komutuyla sonlandırın.

Sıralı okuma mevcut adresten veya rastgele bir adresten gerçekleştirilebilir ve mikrodenetleyici bir STOP sinyali gönderene kadar devam edecektir. Adresin taşması durumunda hafıza sıfırlanacak ve adresleme baştan başlayacaktır.

Artık bir şeyler yazmayı denemenin zamanı geldi:
#katmak // Kütüphaneyi dahil edin #define EEPROM_ADDRESS 0x53 // Bellek adresi word adresini ayarlayın = 0; // byte yazacağımız adres data_send = 170 ; // Data void setup() ( Wire.begin(); // I2C'yi başlat Serial.begin(9600); Serial.print("EEPROM belleğine bayt yaz..."); Serial.println (data_send); Wire. beginTransmission(EEPROM_ADDRESS); // İletimi başlat Wire.write(adres >> 8); Wire.write(adres & 0xFF); // Adresin iki baytını gönder Wire.write(data_send); Wire.endTransmission(); // Aktarımı bitirin ve aktarım durumunu kontrol edin if (status == 0)Serial.println ("Tamam"); ​​// Serial.println("EEPROM belleğinden baytı oku..."); Wire.beginTransmission(EEPROM_ADDRESS); // Veriyi okumak için öncelikle bulunduğu adresi gönderin. Wire.write(adres >> 8); status= Wire.endTransmission(); (status == 0)Serial.println ("Tamam"); ​​// Wire.requestFrom(EEPROM_ADDRESS, (byte)1) aktarımını durdurun; // bir bayt veriyi okumak için bir komut gönderin = 0 ()) // okunacak veri olup olmadığını kontrol edin; . ( veri = Wire.read(); //verileri oku) Serial.println(veri, DEC); ) geçersiz döngü() ( )

Wire.requestFrom(adres, miktar) - Master tarafından köleden bayt talep etmek için kullanılır. Bu baytlar, Available() ve Read() yöntemleri kullanılarak elde edilebilir. Tampon boyutu aynı 32 bayttır.

  • adres : Baytların talep edildiği cihazın 7 bitlik adresi;
  • miktar : talep edilen bayt sayısı;

Wire.available()- read() kullanılarak alınabilecek mevcut bayt sayısını döndürür.

İşte “Merhaba Kelime” dizesinin belleğe yazılmasına ilişkin bir örnek:

#katmak #define EEPROM_ADDRESS 0x53 kelime adresi = 0; char data_send = "Merhaba Kelime"; void setup() ( Wire.begin(); // Serial.begin(9600); Serial.print("EEPROM belleğine bayt yaz..."); Serial.println (data_send); Wire.beginTransmission(EEPROM_ADDRESS); Wire.write(adres >> 8); Wire.write(adres & 0xFF); bayt durumu= Wire.endTransmission(); if (status == 0)Serial.println ("OK"); .println("EEPROM belleğinden baytı oku..."); Wire.beginTransmission(EEPROM_ADDRESS); Wire.write(adres & 0xFF); if (status == 0)Serial.println ("Tamam) "); // Wire.requestFrom(EEPROM_ADDRESS, (byte)10); for (int i=0); i aktarımını durdurun<10 ;i++) { if (Wire.available()) { data = Wire.read(); } Serial.write (data); } } void loop() { }

Bellek organizasyonu:

Veri sayfası bunu belirsiz bir şekilde söylediğinden beri. Bunu pratikte çözmeye çalıştım. Veri sayfası çipin hafızasının şu şekilde organize edildiğini söylüyor: 512 sayfalar 64 bayt Bu ne anlama geliyor? Tek seferde 64 byte'tan fazlasını yazmak istiyorsak, örneğin 0x40 adresinde (adres ikinci sayfanın başıdır), adres sayfa sınırlarını aştığında Çipin dahili sayacı, adresi sayfanın başına sıfırlayacaktır.. Ve fazladan baytlar sayfanın üstüne yazılacak ve orada yazılan veriler silinecektir.

Okuma konusunda böyle bir kısıtlama yoktur; veri sayfası yalnızca adreslerin sonuna ulaştığınızda otomatik olarak başlangıca (adres 0x00) aktarılacağını söylüyor.

Bütün düşündüğüm bu. Elbette EEPROM için hazır bir kütüphane indirebilir ve kendi kütüphanenizi yazabilirsiniz. Önemli olan, temel çalışma prensibini anlamamızdır.

Arduino, basitliği, düşük maliyeti ve genişletme kartlarının çok çeşitli olması nedeniyle mühendisler, ustalar ve öğretmenler tarafından yaygın olarak tanınan standart bir mikrodenetleyicidir. Ana Arduino kartına bağlanan genişletme kartları internete erişmenizi, robotları kontrol etmenizi ve ev otomasyonunu sağlar.

Basit Arduino tabanlı projelerin uygulanması zor değildir. Ancak giriş niteliğindeki eğitimlerde ele alınmayan alanlara girdiğinizde ve projelerinizin karmaşıklığını artırdığınızda, tüm programcıların düşmanı olan bilgi eksikliği sorunuyla hızla karşılaşacaksınız.

Bu kitap çok satan "Arduino'yu Programlamak: Eskizlere Başlarken" kitabının devamı niteliğindedir. Her ne kadar bu kitap Arduino Programlamanın temellerini kısaca özetlese de, okuyucuya Arduino kartlarını programlamanın daha gelişmiş yönlerini tanıtacaktır.

Farklı Arduino modellerinde I2C arayüzü farklı pinlere bağlanır. Örneğin, Uno modeli sırasıyla SDA ve SCL hatları olan A4 ve A5 pinlerini kullanırken, Leonardo modeli D2 ve D3 pinlerini kullanıyor. (SDA ve SCL hatları bir sonraki bölümde daha ayrıntılı olarak anlatılmaktadır.) Her iki modelde de SDA ve SCL hatları AREF kontağının yanında bulunan bloğa da gönderilir (Şekil 7.3).

Masada 7.1, en yaygın Arduino kartı modellerini ve I2C arayüzüne karşılık gelen pinleri listeler.

Pirinç. 7.3. Arduino Uno kartındaki I2C pinleri

Tablo 7.1. Farklı Arduino modellerinde I2C pinleri

Modeli Kişiler Notlar
Uno A4 (SDA) ve A5 (SCL) Kişiler SCL ve SDA olarak imzalanmıştır ve AREF kişisinin yanında bulunur. Bu arayüz hatları aynı zamanda A4 ve A5 pinlerine de gönderilir.
Leonardo D2 (SDA) ve D3 (SCL) Kişiler SCL ve SDA olarak imzalanmıştır ve AREF kişisinin yanında bulunur. Bu arayüz hatları aynı zamanda D2 ve D3 pinlerine de gönderilir.
Mega2560 D20 (SDA) ve D21 (SCL) -
Vadesi dolmuş D20 (SDA) ve D21 (SCL) Due modelinde SDA1 ve SCL1 etiketli ikinci bir I2C pin çifti bulunur.

I2C protokolü

I2C arayüzü üzerinden veri iletmek ve almak için iki hat kullanılır (dolayısıyla ikinci isim - iki telli arayüz, İki Telli Arayüz). Bu iki satıra Seri Saat Hattı (SCL) ve Seri Veri Hattı (SDA) da denir. İncirde. Şekil 7.4 I2C arayüzü üzerinden iletilen sinyalin zamanlama diyagramını göstermektedir.

Pirinç. 7.4. I2C arayüzü aracılığıyla iletilen sinyalin zamanlama diyagramı

Master, SCL hattı üzerinde bir saat darbesi üretir ve iletilecek veri olduğunda, gönderici (master veyaslave) SDA hattını üçüncü durumdan (dijital çıkış moduna) çıkarır ve verileri mantıksal sıfırlar biçiminde gönderir. ve pozitif saat darbeleri sinyali anlarındakiler. Aktarım tamamlandıktan sonra saat çıkışı durdurulabilir ve SDA hattı üçüncü duruma geri döner.

Tel Kitaplığı

Elbette, daha önce anlatılan darbeleri, bitleri kontrol ederek, yani dijital çıkışları yazılımda açıp kapatarak kendiniz oluşturabilirsiniz. Ancak hayatımızı kolaylaştırmak için Arduino yazılımı, tüm senkronizasyon karmaşıklıklarını halleden ve baytlarca veriyi kolayca gönderip almamıza olanak tanıyan bir Wire kütüphanesi içerir.

Wire kütüphanesini kullanmak için öncelikle onu komuta eklemeniz gerekir.

#katmak

I2C başlatma

Çoğu durumda Arduino kartı herhangi bir I2C veriyolunda ana cihaz görevi görür. Arduino'yu master olarak başlatmak için, aşağıda gösterildiği gibi kurulum fonksiyonunda start komutunu vermeniz gerekir:

Bu durumda Arduino'nun master görevi görmesi nedeniyle kendisine bir adres atanmasına gerek olmadığını unutmayın. Kart köle modunda çalışacak şekilde yapılandırıldıysa, 0 ile 127 arasında bir adres atamamız ve bunu I2C veriyolundaki kartı benzersiz şekilde tanımlamak için bir parametre olarak geçirmemiz gerekir.

Master tarafından veri gönderiliyor

I2C veri yolu üzerindeki bir cihaza veri göndermek için öncelikle beginTransmission fonksiyonunu çalıştırmanız ve bu fonksiyona hedef cihazın adresini iletmeniz gerekir:

Wire.beginTransmission(4);

I2C veri yolu üzerindeki cihazlara veri göndermek, aşağıdaki iki örnekte gösterildiği gibi bayt bayt veya karakter dizilerinin tamamıyla yapılabilir:

Wire.send(123); // 123 değerine sahip bir bayt aktarıyoruz

Wire.send("ABC"); // "ABC" karakter dizisinin aktarılması

Aktarım tamamlandığında endTransmission işlevi çağrılmalıdır:

Wire.endTransmission();

Master tarafından veri alınıyor

Bir köleden veri almak için öncelikle requestFrom işlevini çağırarak beklenecek bayt sayısını belirtmeniz gerekir:

Wire.requestFrom(4, 6); // adresi 4 olan cihazdan 6 bayt talep ediyoruz

Bu fonksiyonun ilk argümanı, master'ın veri almak istediği köle aygıtının adresi, ikinci argüman ise almayı beklediği bayt sayısıdır. Yardımcı cihaz daha az bayt aktarabilir, dolayısıyla verinin alınıp alınmadığını ve gerçekte kaç bayt alındığını belirlemek için mevcut fonksiyonun kullanılması gerekir. Aşağıdaki örnek (Wire kütüphanesindeki örnek paketten alınmıştır), ana cihazın alınan tüm verileri nasıl aldığını ve seri port monitörüne nasıl çıkardığını gösterir:

#katmak

Wire.begin(); // i2c veri yoluna bağlanın (ana cihaz için)

// cihaz adresi belirtilmedi)

Seri.begin(9600); // seri port monitörünü başlat

Wire.requestFrom(8, 6); // 8 numaralı köleden 6 bayt talep ediyoruz

while (Wire.available()) ( // köle daha az gönderebilir

char c = Wire.read(); // baytı karakter olarak kabul et

Wire kütüphanesi gelen verileri otomatik olarak arabelleğe alır.

I2C kullanımına örnekler

Herhangi bir I2C cihazının, desteklediği mesajları listeleyen bir teknik açıklamaya sahip olması gerekir. Bu tür açıklamalar, bağımlı cihazlara gönderilecek mesajların oluşturulması ve yanıtlarının yorumlanması için gereklidir. Bununla birlikte, bir Arduino kartına bağlanabilen birçok I2C cihazı için, I2C mesajlarını basit ve kullanışlı işlevlere saran özel kütüphaneler vardır. Aslında, özel bir kütüphanesi olmayan bir cihazla çalışmak zorundaysanız, kendi kütüphanenizi herkesin kullanımına yayınlayın ve kendinize biraz karma puanı kazanın.

Belirli bir cihaz için tam bir destek kitaplığı mevcut olmasa bile, İnternet'te sıklıkla cihazın nasıl kullanılacağını gösteren yararlı kod parçacıkları bulabilirsiniz.

VHF radyo alıcısı TEA5767

Bir I2C cihazıyla etkileşimi gösteren ilk örnek, kitaplığı kullanmaz. Arduino ve TEA5767 modülü arasında gerçek mesajların alınıp verildiği yer burasıdır. Bu modül internetten çok ucuza satın alınabilir, Arduino kartına kolayca bağlanır ve Arduino tarafından kontrol edilen bir VHF alıcısı olarak kullanılır.

En zor aşama cihazı bağlamaktır. Pedler çok küçük ve birbirine çok yakın yerleştirilmiş, pek çok kişi tahtaya bağlanmak için bir adaptör yapmayı veya satın almayı tercih ediyor.

İncirde. Şekil 7.5, modülü Arduino'ya bağlama şemasını göstermektedir.

Pirinç. 7.5. TEA5767 modülünü I2C arayüzü üzerinden Arduino Uno kartına bağlama

TEA5767 modülü veri sayfasını www.sparkfun.com/datasheets/Wireless/General/TEA5767.pdf adresinde bulabilirsiniz. Açıklama pek çok teknik bilgi içeriyor ancak belgeye baktığınızda cihazın tanıdığı mesajların ayrıntılı açıklamasının yer aldığı bir bölüm göreceksiniz. Belgeler, TEA5767'nin 5 bayt uzunluğundaki mesajları kabul ettiğini belirtir. Aşağıda, başlatmanın hemen ardından frekans ayarını gerçekleştiren tam olarak çalışan bir örnek yer almaktadır. Pratikte, örneğin düğmelere ve sıvı kristal ekrana dayalı olarak genellikle biraz farklı bir konfigürasyon mekanizması gerekir.

// taslak_07_01_I2C_TEA5767

#katmak

setFrequency(93.0); //MHz

void setFrequency (değişken frekans)

bayt frekansıH = frekansB >> 8;

Wire.beginTransmission(0x60);

Wire.write(frekansH);

Wire.write(frekansL);

Wire.write(0xB0);

Wire.write(0x10);

Wire.write(0x00);

Wire.endTransmission();

Bu örnekte bizi ilgilendiren kodun tamamı setFrequency fonksiyonundadır. Gerçek bir sayı alır; megahertz cinsinden frekans. Yani, bu projeyi oluşturmak ve denemek istiyorsanız, iyi ve güçlü bir sinyale sahip yerel bir radyo istasyonunun frekansını bulun ve değerini kurulum işlevindeki setFrequency çağrısına ekleyin.

Gerçek bir frekans değerini, beş baytlık bir mesajın parçası olarak gönderilebilecek iki baytlık bir gösterime dönüştürmek için bazı aritmetik işlemlerinin yapılması gerekir. Aşağıdaki parça bu işlemleri gerçekleştirir:

işaretsiz int frekansıB = 4 * (frekans * 1000000 + 225000) / 32768;

bayt frekansıH = frekansB >> 8;

bayt frekansıL = frekansB & 0XFF;

>> komutu bitleri sağa kaydırır, yani >> 8 işlemi yüksek 8 biti düşük 8 bit'e doğru 8 ikili basamak kaydırır. & operatörü, bu durumda en önemli 8 biti sıfırlayacak ve yalnızca en az anlamlı olanları bırakacak olan bit düzeyinde bir AND işlemi gerçekleştirir. Bit işlemlerine ilişkin daha kapsamlı bir tartışma için Bölüm 9'a bakın.

setFrequency fonksiyonundaki kodun geri kalanı, TEA5767 alıcısına atanan 0x60 adresli köleye bir I2C mesajının iletimini başlatır. Daha sonra frekans baytı 2'den başlayarak 5 baytlık seri iletim gerçekleştirilir.

Belgeleri okuduktan sonra, aralığı taramak, bir veya iki ses çıkış kanalını kapatmak ve mono/stereo modunu seçmek gibi farklı mesajlarla kullanılabilen diğer birçok seçeneği öğreneceksiniz.

Ekte bu örneğe geri döneceğiz ve TEA5767 modülüyle çalışmayı kolaylaştırmak için bir Arduino kütüphanesi oluşturacağız.

İki Arduino kartı arasındaki iletişim

İkinci örnekte, biri I2C yöneticisi, diğeri bağımlı olarak görev yapan iki Arduino kartı kullanılıyor. Ana cihaz, ikincil cihaza mesajlar gönderecek ve bu mesajlar seri port monitörüne gönderilecek, böylece devrenin çalıştığını görsel olarak doğrulayabilirsiniz.

Bu örneğin kart bağlantı şeması Şekil 2'de gösterilmektedir. 7.6. Lütfen TEA5767 modülünün I2C hatlarında yerleşik çekme dirençlerine sahip olduğunu unutmayın. Ancak bu durumda, iki Arduino kartı birbirine bağlandığında böyle bir direnç yoktur, bu nedenle 4,7 kOhm nominal değere sahip kendi dirençlerinizi dahil etmeniz gerekecektir (Şekil 7.6).

Pirinç. 7.6. I2C arayüzü aracılığıyla iki Arduino kartını bağlama

Panolara farklı eskizler yüklenmelidir. Her iki çizim de Wire kütüphanesindeki örneklere dahil edilmiştir. Arduino ana kartının programı Dosya->Örnek->Kablo->master_yazar (Dosya-> Örnekler->Kablo->master_yazıcı) menüsünde, yardımcı kart için ise Dosya-> Örnek-> menüsünde bulunur. Kablo->slave_receiver (Dosya ->Örnekler->Kablo->slave_receiver).

Her iki kartı da programladıktan sonra, o kartın çıkışını seri monitörde görmek için köleyi bilgisayara bağlı bırakın ve Arduino ana kartına güç verin.

Ana karttaki bir çizimle başlayalım:

#katmak

Wire.begin(); // i2c veri yoluna bağlanın (ana cihaz için)

// adres belirtilmedi)

Wire.beginTransmission(4); // 4 numaralı cihaza aktarımı başlatıyoruz

Wire.write("x eşittir "); // 5 bayt gönder

Wire.write(x); // 1 bayt gönder

Wire.endTransmission(); // aktarımı durdur

Bu çizim, x'in 1 olduğu gibi bir mesaj üretiyor; burada 1, her yarım saniyede bir artan bir sayıdır. Mesaj daha sonra beginTransmission çağrısında tanımlandığı gibi köle adresi 4'e gönderilir.

Yardımcı taslağın görevi, ana cihazdan bir mesaj almak ve bunu seri port monitörüne göndermektir:

#katmak

Wire.begin(4); // i2c veri yoluna #4 adresiyle bağlanın

Wire.onReceive(receiveEvent); // bir olay işleyicisini kaydedin

Seri.begin(9600); // seri port monitörünü aç

// bu fonksiyon master tarafından her zaman çağrılır

// sonraki veri geldiğinde bu fonksiyon işleyici olarak kaydedilir

// olaylar, bkz. setup()

void getEvent(int HowMany) (

iken (1< Wire.available()) { // цикл по всем принятым байтам, кроме

// son

Seri.print(c); // sembolü yazdır

Seri.println(x); // bir tamsayıyı yazdır

Bu çizimde dikkat edilmesi gereken ilk şey, Wire.begin fonksiyonuna parametre 4'ün iletilmesidir. Bu, I2C veriyolundaki bağımlı cihazın adresini, bu durumda 4'ü belirtir. Bu, ana cihazın göndermek için kullandığı adresle eşleşmelidir. mesajlar.

TAVSİYE

Hepsinin farklı I2C adreslerine sahip olması koşuluyla birçok Arduino köle kartını iki kablolu bir veri yoluna bağlayabilirsiniz.

Yardımcı çizim, ana çizimden farklıdır çünkü ana öğeden mesaj almak için kesintileri kullanır. Mesaj işleyicisinin ayarlanması, kesme rutinleri gibi çağrılan onReceive işlevi tarafından yapılır (Bölüm 3). Herhangi bir gelen mesaj alındığında kullanıcı tanımlı getEvent fonksiyonunun çağrılmasını sağlamak için bu fonksiyona yapılan çağrının kurulum fonksiyonuna yerleştirilmesi gerekir.

AlmaEvent işlevi tek bir parametre alır; okunmaya hazır bayt sayısı. Bu durumda bu sayı dikkate alınmaz. While döngüsü mevcut tüm karakterleri sırayla okur ve bunları seri port monitörüne gönderir. Mesajın sonundaki tek baytlık sayı daha sonra okunur ve port monitörüne gönderilir. Yazmak yerine println kullanmak, bayt değerinin karşılık gelen sayısal kodla birlikte bir karakter yerine sayı olarak yazdırılmasını sağlar (Şekil 7.7).

Pirinç. 7.7. Bir Arduino kartı tarafından diğerinden alınan mesajların I2C arayüzü aracılığıyla port monitörüne gönderilmesi

LED göstergeli panolar

I2C cihazlarının bir diğer geniş yelpazesi çeşitli ekran türleridir. Bu cihazların en tipik temsilcileri Adafruit tarafından üretilen LED matrisler ve yedi segmentli göstergelerdir. Baskılı devre kartına monte edilmiş LED ekranlar ve I2C arayüzünü destekleyen kontrol çipleri içerirler. Bu çözüm, LED ekranı kontrol etmek için Arduino kartında çok sayıda I/O pini kullanma ihtiyacını ortadan kaldırır ve yalnızca iki pin (SDA ve SCL) ile idare etmenize olanak tanır.

Kütüphaneler, tüm I2C etkileşimlerini dış görünüşlerinin arkasına gizleyerek, kütüphaneye dahil edilen bir örnekten alınan aşağıdaki pasajın gösterdiği gibi, üst düzey komutların kullanımına izin verir:

#katmak

#include "Adafruit_LEDBackpack.h"

#include "Adafruit_GFX.h"

Adafruit_8x8matrix matrisi = Adafruit_8x8matrix();

matris.begin(0x70);

matris.drawLine(0, 0, 7, 7, LED_RED);

matris.writeDisplay();

Gerçek zamanlı saat DS1307

Bir diğer yaygın I2C cihazı ise DS1307 gerçek zamanlı saat modülüdür. Bu modül için ayrıca gerçek I2C mesajlarıyla uğraşmak zorunda kalmadan modülle etkileşimi kolaylaştıran kullanışlı ve sağlam bir kitaplık da bulunmaktadır. Kütüphanenin adı RTClib'dir ve https://github.com/adafruit/RTClib adresinde mevcuttur.

Aşağıdaki kod parçacıkları da kitaplıkla sağlanan örneklerden alınmıştır:

#katmak

#include "RTClib.h"

Seri.begin(9600);

if (!RTC.isrunning()) (

Serial.println("RTC ÇALIŞMIYOR!");

// taslağın modüle derlendiği tarih ve saati yazın

RTC.adjust(DateTime(__DATE__, __TIME__));

Şimdi TarihSaat = RTC.now();

Seri.print(şimdi.yıl(), DEC);

Seri.print("/");

Seri.print(şimdi.ay(), DEC);

Seri.print("/");

Seri.print(now.day(), DEC);

Seri.print(" (");

Serial.print(daysOfTheWeek);

Seri.print() ");

Seri.print(now.hour(), DEC);

Seri.print(":");

Seri.print(şimdi.dakika(), DEC);

Seri.print(":");

Seri.print(now.second(), DEC);

Seri.println();

I2C etkileşimlerinin gerçekte nasıl çalıştığını görmek istiyorsanız kütüphane dosyalarına bir göz atmanız yeterli. Örneğin, RTClib kitaplığının kaynak kodu RTClib.h ve RTClib.cpp dosyalarında depolanır. Bu dosyalar kütüphaneler/RTClib klasöründe bulunur.

Örneğin, RTClib.cpp dosyasında now işlevinin tanımını bulabilirsiniz:

DateTime RTC_DS1307::now() (

Wire.beginTransmission(DS1307_ADDRESS);

Wire.endTransmission();

Wire.requestFrom(DS1307_ADDRESS, 7);

uint8_t ss = bcd2bin(Wire.read() & 0x7F);

uint8_t mm = bcd2bin(Wire.read());

uint8_t hh = bcd2bin(Wire.read());

uint8_t d = bcd2bin(Wire.read());

uint8_t m = bcd2bin(Wire.read());

uint16_t y = bcd2bin(Wire.read()) + 2000;

return DateTime(y, m, d, ss, aa, ss);

Wire.read işlevi, değerleri İkili Kodlu Ondalık (BCD) biçiminde döndürür, böylece bunlar bcd2bin kitaplık işlevi kullanılarak baytlara dönüştürülür.

BCD formatında, bir bayt iki adet 4 bitlik yarım parçaya bölünür. Her yarım bayt, iki basamaklı bir ondalık sayının bir basamağını temsil eder. Böylece BCD formatındaki 37 sayısı 0011 0111 olarak temsil edilecektir. İlk dört bit ondalık değer 3'e, ikinci dört bit ise ondalık değer 7'ye karşılık gelir.

Nihayet

Bu bölümde I2C arayüzünü ve bunun Arduino kartları, çevre birimleri ve diğer Arduino kartlarıyla iletişim kurmak için nasıl kullanılacağını öğrendiniz.

Bir sonraki bölümde çevre birimleriyle iletişim kurmak için kullanılan başka bir seri arayüz tipini inceleyeceğiz. denir 1 telli. Bu arayüz I2C kadar yaygın olarak kullanılmamaktadır ancak popüler DS18B20 sıcaklık sensöründe kullanılmaktadır.

I 2 C arayüzüne sahip bir mikro devreye dayalı bir saat yapmam gerekiyordu. RTC çipi sözde. "gerçek zamanlı saat" PCF8583.

Çipin içinde: bir saat, bir alarm saati, bir zamanlayıcı, bir takvim (eğri) ve istediğiniz herhangi bir bilgiyi kaydedebileceğiniz 240 bayt RAM bulunmaktadır. RAM çok kullanışlı bir şeydir, flash belleğin aksine, RAM'in yeniden yazma döngüsü sayısında herhangi bir kısıtlaması yoktur ve bazı verileri ve ayarları ona istediğiniz sıklıkta kaydedebilirsiniz.

Ancak bir sorun vardı - gerçekten kod yazmak istemedim, bu yüzden internette hazır kod bulmaya karar verdim. Daha sonra ortaya çıktığı gibi, onu bulmak "kendi başınaydı". I 2 C ile çalışmanın bir örneğini indirdim, düzelttim ve mikrodenetleyiciyi flaşladım. İşe yaramadı. Kodu karıştırmaya başladım, neden çalışmadığını araştırdım... ve dehşete düştüm!! Bazı durumlarda kayıt, belirli bitlere değil, bağlantı noktasının tamamına aynı anda gerçekleştirildi. Bu nedenle, bağlantı noktasına örneğin bir ekran gibi başka bir şey bağlarsanız, büyük olasılıkla çalışmayacaktır. Ayrıca veri yolundaki verilerin okunması yanlış uygulandı (bir alım sonu koşulu oluşturulmadan veya yalnızca NACK olmadan). Ama bu sorunun yarısı. Asıl sorun farklı. Genellikle kodun yazarı bağlantı noktasına mantıksal bir "1" atar ve bildiğimiz gibi I 2 C veri yolu, SDA ve SCL pinlerini ortak kabloya "çekerek" kontrol edilir. Ve veriyolundaki mantıksal “1” ise güç kaynağının 4,7 kiloohm dirençlerle artıya çekilmesiyle oluşuyor. Bu nedenle, mikro denetleyicinin çıkışı mantıksal "1" olarak ayarlanırsa ve bağımlı cihaz bu çıkışı ortak kabloya "çekerse", o zaman bir "bang-bang" kısa devre meydana gelecektir. Bundan gerçekten hoşlanmadım ve kendi tekerleğimi yeniden icat etmeye ve kendi kitaplığımı, hatta 2 kitaplığı yazmaya karar verdim: biri I 2 C veri yolu ile çalışmak için, diğeri doğrudan PCF8583 gerçek zamanlı çalışmak için saat. Evet bu arada kod .

I 2 C kütüphanesini projeye bağlamak için resimdeki gibi include yoluyla dahil etmeniz ve ayrıca kütüphaneyi proje klasörüne kopyalamanız gerekmektedir.

Bundan sonra, “i2c.h” dosyasını açmanız ve I 2 C veri yolu görevi görecek mikro denetleyicinin pinlerini belirtmeniz gerekir. Varsayılan olarak veri yolu PC0 (SCL) ve PC1 (SDA) pinlerinde yapılandırılmıştır. ). Ve kurulum burada yapılır:

İşte bu, I2C kütüphanesini bağladık, bacakları yapılandırdık ve kütüphane kullanıma hazır. Kullanım örneği:

I2c_init(); // I2C veriyolunu başlat i2c_start_cond(); //i2c_send_byte (0xA0) veriyolunu başlatıyoruz; // veriyolunda asılı kalan cihazın adresi i2c_send_byte (0x10); // cihaza yazılan veri baytı i2c_send_byte (0x10); // cihaza yazdığımız başka bir bayt veri i2c_stop_cond(); // lastikleri durdur

Stop koşulundan sonra I 2 C bus ile her şeyin yolunda olup olmadığını kontrol edebiliriz. Bunun için “i2c_frame_error” değişkenini okumamız gerekiyor. Her şey normalse 0 olacaktır. Veriyolu pinlerinden biri güç kaynağına "yukarı çekilmemişse" ve veriyoluna mantıksal "1" takılmamışsa kütüphane bir hata oluşturur ve şunu yazar: “i2c_frame_error” değişkenine 1 sayısını okuyun ve durma koşulundan sonra “i2c_frame_error” değişkenini okuyun. Aşağıdaki şekilde hata kontrolünün nasıl çalıştığını göstereceğim:

Şimdi PCF8583 gerçek zamanlı saat kütüphanesini bağlayalım. Bunu yapmak için aynı adımları uygulamanız gerekir. "PCF8583.h" dosyasını proje klasörüne kopyalayıp fotoğraftaki gibi include'a ekleyelim:

Hazır. PCF8583 gerçek zamanlı saat kitaplığı bağlanır. Herhangi bir ayar gerektirmediği için çipten saat ve tarihi okumaya hemen başlayabilirsiniz. Lütfen PCF8583 kütüphanesinin I2C kütüphanesini kullanarak çalıştığını unutmayın; dolayısıyla PCF8583 ile çalışmak istiyorsak her iki kütüphaneyi de bağlamamız gerekir!

Kütüphaneyi kullanma örneği (saat ve tarihi yazma ve okuma):

// I2C veriyolunu başlat i2c_init(); // PCF8583 yongasına yazmak için saat ve tarihi hazırlayın PCF_hour=23; // 23 saat PCF_min=59; // 59 dakika PCF_gün=31; // 31. gün PCF_ayı=12; // 12. ay - Aralık PCF_yıl=0; // yıl (0 - artık yıl değil) PCF_weekday=6; // Haftanın 6. günü (Pazar) // Saati ve tarihi PCF8583 yongasına yazın PCF_write_hh_mm_ss(); // PCF8583 yongasından saat ve tarihi okuyun PCF_read_hh_mm_ss(); RAM ile çalışmaya bir örnek (yazma ve okuma): // PCF8583 yongasına yazmak için 5 bayt hazırlayın PCF_data_ram_1=255; // bayt 1 PCF_data_ram_2=255; // bayt 2 PCF_data_ram_3=255; // bayt 3 PCF_data_ram_4=255; // bayt 4 PCF_data_ram_5=255; // bayt 5 // PCF8583 yongasına 5 bayt yazın PCF_write_ram(); // PCF8583 yongasından 5 bayt oku PCF_read_ram();

Mikro devreden okumak daha da kolaydır - sadece işlevi çağırınPCF_ Okumak_ _ mm_ ss() bundan sonra değişkenlerde saat ve tarih görünecek, onları aldığınız yerden. RAM'i okumak için işlevi buna göre kullanırızPCF_ Okumak_ Veri deposu() bundan sonra değişkenlerdeki verileri topluyoruzPCF_ veri_ Veri deposu_ N

Burada, nerede ve neyin saklandığı değişkenlerin bir listesi verilmiştir:

// saat ve tarih PCF_hour=0; // zaman, saat (0'dan 23'e kadar, yazarken ve okurken taşma koruması) PCF_min=0; // zaman, dakika (0'dan 59'a kadar, yazarken ve okurken taşmaya karşı koruma) PCF_sec=0; // zaman, saniye (salt okunur, yazarken 00'a sıfırlanır) PCF_day=0; // gün (1'den 31'e kadar, yazarken ve okurken taşma koruması) PCF_weekday=0 // haftanın günü (0-Pazartesi; 6-Pazar, yazarken ve okurken taşma koruması) PCF_ay=0; // ay (1'den 12'ye kadar, yazarken ve okurken taşmaya karşı koruma) PCF_year=0; // yıl (0 sıçramalı; 1,2,3 sıçramasız, yazarken ve okurken taşma koruması) // RAM PCF_data_ram_1; // Veri (PCF8583 RAM), bayt 1 PCF_data_ram_2; // Veri (PCF8583 RAM), bayt 2 PCF_data_ram_3; // Veri (PCF8583 RAM), bayt 3 PCF_data_ram_4; // Veri (PCF8583 RAM), bayt 4 PCF_data_ram_5; // Veri (PCF8583 RAM), bayt 5

Şimdi size taşma korumasından bahsedeceğim. Diyelim ki mikro devreyi bağlamayı unuttuk. Mikro devreden verileri okuyalım ve... 11111111 baytı veya 255 sayısı okunacaktır. Mesele şu ki, I 2 C veriyolu 2 çekme direncine dayanıyor, bu yüzden bize mantıksal "birler" veriyorlar. mikro devre bağlı değilse. Bu gibi durumlara karşı korunmak için PCF8583 kütüphanesinde saatin 62 saat 81 dakikayı göstermemesini sağlayan bir taşma koruması yaptım... “PCF_overflow” değişkeni okunarak taşma olup olmadığı takip edilebiliyor. 0 ise taşma hatası yoktur. 1 veya daha fazla içeriyorsa taşma hatası var demektir. Tarih ve saat okuma fonksiyonundan sonra “PCF_overflow” değişkenini okumanız gerekmektedir.PCF_ Okumak_ _ mm_ ss()

Açıklık sağlamak için ATmega32 için AVR Studio 6 projesi ektedir. Herhangi bir AVR için yeniden derleyebilirsiniz. Projede ayrıca görsel kontrol için bir ekran da bağladım. Güç uygulandığında mikrodenetleyici 31 Aralık Pazar günü 23 saat 59 dakikayı ayarlar. Ve bir dakika sonra saat 00 saat 00 dakika olur, yani 1 Ocak Pazartesi.

Şimdi size neden bu mikro devrenin "çarpık" takviminden bahsettiğimi anlatacağım. Mesele şu ki, mikro devre mevcut takvim yılını nasıl saklayacağını bilmiyor, yalnızca artık yıl bayrağını saklıyor. Kısacası:
0 – artık yıl
1 – artık yıl değil
2 – artık yıl değil
3 – artık yıl değil

Ve bu şekilde 0-1-2-3-0-1-2-3-0 döngüsünde...

Genel olarak, normal bir takvim oluşturmak için, örneğin aynı PCF8583 RAM'e yazılım hesaplaması ve yılın kaydedilmesini uygulamanız gerekir, ancak bu uygun değildir. Ve asıl mesele şu ki eğer devrenin enerjisi kesilirse ne yazık ki hiç kimse hafızanın üzerine yazamayacak...

Yazının sonuna kısa bir video raporu da ekliyorum. Programlamaya yeni başlayan biriyim diyebilirim, her ne kadar 3 yıldır (azar azar) programlama yapıyor olsam da, kodu kesin olarak yargılamayın, eklemeler, yorumlar varsa yazın, düzeltelim. Herkese mutlu işçilik!

Radyo elemanlarının listesi

Tanım Tip Mezhep Miktar NotMağazanot defterim
MK AVR 8 bit

ATmega32

1 Not defterine
Gerçek Zamanlı Saat (RTC)

PCF8583

1 Not defterine
LCD ekranWH16021

Wire kütüphanesinin açıklaması

Bu kütüphane I2C/TWI cihazlarıyla etkileşime girmenizi sağlar. R3 düzenine (1.0 pin çıkışı) sahip Arduino kartlarında, SDA (veri hattı) ve SCL (saat hattı), AREF pininin yakınındaki pinlerde bulunur. Arduino Due'nin iki I2C/TWI arayüzü vardır: SDA1 ve SCL1, AREF pininin yakınında bulunur ve ek hatlar 20 ve 21 numaralı pinlerde bulunur.

Aşağıdaki tablo TWI pinlerinin farklı Arduino kartlarında nerede bulunduğunu göstermektedir.

Arduino 1.0'dan bu yana, bu kütüphane Stream işlevlerini miras alarak diğer okuma/yazma kütüphaneleriyle uyumlu hale getiriyor. Bu nedenle send() ve get() fonksiyonlarının yerini read() ve write() almıştır.

Not

I2C adreslerinin 7 ve 8 bitlik versiyonları bulunmaktadır. 7 bit cihazı tanımlar ve 8. bit cihazın yazıldığını mı yoksa okunduğunu mu belirler. Wire kütüphanesi 7 bitlik adresler kullanır. 8 bitlik bir adres kullanan bir veri sayfanız veya örnek kodunuz varsa, en az anlamlı biti çevirmeniz (yani değeri bir bit sağa kaydırmanız) gerekir, bu da 0'dan 127'ye kadar bir adres elde edilmesini sağlar. Ancak, 0'dan 127'ye kadar olan adresler 7, ayrılmış oldukları için kullanılmaz, dolayısıyla kullanılabilecek ilk adres 8'dir. SDA/SCL pinlerini bağlarken çekme dirençlerinin gerekli olduğunu unutmayın. Daha fazla ayrıntı için örneklere bakın. MEGA 2560 kartının 20 ve 21 numaralı pinlerinde çekme dirençleri vardır.

Yöntemlerin açıklaması

Wire.begin()

Tanım

Wire kütüphanesini başlatır ve I2C veri yoluna ana veya bağımlı olarak bağlanır. Genellikle yalnızca bir kez çağrılmalıdır.

Sözdizimi

Wire.begin(adres)

Seçenekler

adres: bağımlı cihazın 7 bitlik adresi (isteğe bağlı); belirtilmediği takdirde kart, veri yoluna master olarak bağlanır.

Geri dönüş değeri

Örnek

Yardımcı cihaz örnekleri için onReceive() ve onRequest() yöntemlerine ilişkin örneklere bakın. Ana cihaz örnekleri için diğer yöntemlerin örneklerine bakın. .

Wire.requestFrom()

Tanım

Master tarafından köleden bayt talep etmek için kullanılır. Bu baytlar, Available() ve Read() yöntemleri kullanılarak elde edilebilir.

Bu argüman true ise requestFrom(), istekten sonra bir STOP mesajı göndererek I2C veriyolunu serbest bırakır.

Bu argüman false ise requestFrom(), istekten sonra bir RESTART mesajı gönderir. Veri yolu serbest bırakılmaz, bu da başka bir ana cihazın mesajların arasına girmesini engeller. Bu, bir yöneticinin veri yolunu kontrol ederken birden fazla istek göndermesine olanak tanır.

Sözdizimi

Wire.requestFrom(adres, miktar)

Wire.requestFrom(adres, miktar, durak)

Seçenekler

  • adres: Baytların talep edildiği cihazın 7 bitlik adresi;
  • miktar: talep edilen bayt sayısı;
  • dur: boolean. true istekten sonra bir STOP mesajı gönderir. false istekten sonra bir YENİDEN BAŞLAT mesajı göndererek bağlantıyı aktif tutar.
Geri dönüş değeri

bayt: köleden döndürülen bayt sayısı.

Örnek

Wire.beginTransmission()

Tanım

Verilen adresle I2C bağımlı cihazına aktarımı başlatır. Bundan sonra iletilecek bayt dizisi write() işlevi kullanılarak kuyruğa alınır ve endTransmission() çağrısı kullanılarak iletilir.

Sözdizimi

Wire.beginTransmission(adres)

Seçenekler

adres: Verilerin aktarılması gereken cihazın 7 bitlik adresi.

Geri dönüş değeri

Örnek

Wire.endTransmission()

Tanım

BeginTransmission() yöntemiyle başlatılan yardımcı öğeye iletimi tamamlar ve write() yöntemi tarafından kuyruğa alınan baytları aktarır.

Arduino 1.0.1'den bu yana, belirli I2C cihazlarıyla uyumluluk sağlamak amacıyla requestFrom(), davranışını değiştiren bir boolean veri türü argümanını kabul eder.

Bu argüman true ise, requestFrom() iletimden sonra bir STOP mesajı göndererek I2C veriyolunu serbest bırakır.

Bu argüman false ise, requestFrom() iletimden sonra bir YENİDEN BAŞLAT mesajı gönderir. Veri yolu serbest bırakılmaz, bu da başka bir ana cihazın mesajların arasına girmesini engeller. Bu, bir master'ın veriyolunu izlerken birden fazla iletim göndermesine olanak tanır.

Varsayılan olarak bu argüman doğrudur.

Sözdizimi

Wire.endTransmission()

Wire.endTransmission(durdur)

Seçenekler

dur: boolean. true iletimden sonra bir STOP mesajı gönderir. false iletimden sonra bir YENİDEN BAŞLAT mesajı göndererek bağlantıyı aktif tutar.

Geri dönüş değeri

aktarım durumunu gösteren bayt:

  • 0: başarı;
  • 1: Veriler iletim arabelleğini dolduramayacak kadar uzun;
  • 2: Adres gönderilirken alınan NACK;
  • 3: Veri gönderilirken alınan NACK;
  • 4: diğer hatalar.
Örnek

write() yöntemi için örneğe bakın.

Wire.write()

Tanım

Ana birimden gelen bir isteğe yanıt olarak ikincil birimden veri yazar veya ana birimden ikincil öğeye iletim için baytları kuyruğa alır (beginTransmission() ve endTransmission() çağrıları arasında).

Sözdizimi

Wire.write(değer)

Wire.write(dize)

Wire.write(veri, uzunluk)

Seçenekler

  • değer: aktarılacak değer, bir bayt.
  • dize: iletilecek dize, bir bayt dizisi.
  • veri: aktarılacak veri dizisi, bayt.
  • uzunluk: aktarılacak bayt sayısı.
Geri dönüş değeri

bayt: write() yazılan bayt sayısını döndürür, ancak bu sayının okunması gerekli değildir.

Örnek #include bayt değeri = 0; void setup() ( Wire.begin(); // i2c veriyoluna bağlanın ) void loop() ( Wire.beginTransmission(44); // cihaz #44'e transfer (0x2c) // cihaz adresi Wire'da belirtildi teknik açıklama. write(val); // değeri gönder Wire.endTransmission(); // iletimi durdur val++; // değeri arttır if(val == 64) // eğer 64. değere ulaştıysak (max) val = 0; // baştan başla ) gecikme(500);

Wire.available()

Tanım

read() kullanılarak alınabilecek mevcut bayt sayısını döndürür. Bu yöntemin requestFrom() çağrıldıktan sonra ana sunucuda veya onReceive() işleyicisinin içindeki yardımcı sunucuda çağrılması gerekir.

Sözdizimi

Wire.available()

Seçenekler

Geri dönüş değeri

Okuma için mevcut bayt sayısı.

Örnek

Read() yöntemi için örneğe bakın.

Wire.read()

Tanım

requestFrom() çağrıldıktan sonra ikincil öğeden ana öğeye aktarılan veya ana öğeden ikincil öğeye aktarılan bir baytı okur.

Sözdizimi

Seçenekler

Geri dönüş değeri

bayt: alınan sonraki bayt.

Örnek #include bayt değeri = 0; void setup() ( Wire.begin(); // i2c veri yoluna bağlanın (ana adres isteğe bağlıdır) Serial.begin(9600); // seri bağlantı noktasını çıkış için yapılandırın) void loop() ( Wire.requestFrom(2) , 6); // köle #2'den 6 bayt talep ederken(Wire.available()) // köle istenenden daha azını gönderebilir ( char c = Wire.read(); // baytı Serial.print karakteri olarak kabul et ( c); // karakteri yazdır ) gecikme(500);

Wire.setClock()

Tanım

I2C veri yolu iletişimi için saat frekansını değiştirir. I2C bağımlı birimlerinin minimum çalışma saat frekansı yoktur, ancak genellikle 100 kHz kullanılır.

Sözdizimi

Wire.setClock(saatFrequency)

Seçenekler

ClockFrequency: Saat sinyalinin frekans değeri (hertz cinsinden). Kabul edilen değerler 100000 (standart mod) ve 400000'dir (hızlı mod). Bazı işlemciler ayrıca 10000'i (düşük hız modu), 1000000'i (hızlı artı modu) ve 3400000'i (yüksek hız modu) destekler. Gerekli modun desteklendiğinden emin olmak için işlemcinize özel teknik belgelere bakın.

Geri dönüş değeri

Wire.onReceive()

Tanım

İkincil, ana birimden bir iletim aldığında çağrılacak bir işlevi kaydeder.

Sözdizimi

Wire.onReceive(işleyici)

Seçenekler

işleyici: yardımcı cihaz veri aldığında çağrılması gereken bir işlev; bir parametre int (ana birimden okunan bayt sayısı) almalı ve hiçbir şey döndürmemelidir, yani:

void myHandler(int numBytes)

Geri dönüş değeri

Örnek

#katmak void setup() ( Wire.begin(8); // #8 adresiyle i2c veri yoluna bağlanın Wire.onReceive(receiveEvent); // bir olay işleyicisini kaydedin Serial.begin(9600); // bunun için seri bağlantı noktasını yapılandırın çıktı ) void loop() ( gecikme(100); ) // ana birimden veri alındığında yürütülecek bir işlev // bu işlev bir olay işleyicisi olarak kaydedilir, bkz. setup() void getEvent(int HowMany) ( iken (1< Wire.available()) // пройтись по всем до последнего { char c = Wire.read(); // принять байт как символ Serial.print(c); // напечатать символ } int x = Wire.read(); // принять байт как целое число Serial.println(x); // напечатать число }

Wire.onRequest()

Tanım

Master, köleden veri istediğinde çağrılacak bir fonksiyonu kaydeder.

Sözdizimi

Wire.onRequest(işleyici)

Seçenekler

işleyici: çağrılacak işlev, hiçbir parametre almaz ve hiçbir şey döndürmez, yani:

geçersiz myHandler()

Geri dönüş değeri

Örnek

Slave olarak çalışan Arduino kartının kodu:

#katmak void setup() ( Wire.begin(8); // #8 adresiyle i2c veriyoluna bağlanın Wire.onRequest(requestEvent); // bir olay işleyicisini kaydedin) void loop() ( gecikme(100); ) // ana // veri istediğinde yürütülecek olan işlev // bu işlev bir olay işleyicisi olarak kayıtlıdır, bkz. setup() void requestEvent() ( Wire.write("merhaba "); // bir mesajla yanıtla )