I2C (DS3231) Kullanımı

Endorfin35+

Kayıtsız Üye
Katılım
1 Mayıs 2020
Mesajlar
4,409
I2c konusunda bilgi sahibi olmak istiyorum. Arduino üzerindeki wire.h kütüphanesi işleri kolaylaştırıyor. Ds3231 içinde bir kütüphane var ama ben onu kullanmadan ds3231 ile iletişim kurmak istiyorum.


datasheet e baktığımda ds3231 in ic2 adresinin nerede yazdığını göremedim.

1684780994179.png

Yukarıdaki tabloda registerlar içerisinde saklanan verileri görüyorum. Bu verilere i2c üzerinden nasıl erişeceğim. Örnek bir kod bloğu paylaşmanız mümkün müdür?
 
C++:
byte DS3231::getDate() {
    _Wire.beginTransmission(CLOCK_ADDRESS);
    _Wire.write(0x04);
    _Wire.endTransmission();

    _Wire.requestFrom(CLOCK_ADDRESS, 1);
    return bcdToDec(_Wire.read());
}

bu kodu 3231 in kütüphanesinden aldım. CLOCK_ADDRESS i2c adresi olsa gerek.
 
O datasheet'in 16. sayfasında diagram var

1684781630468.png
 
Slave address oluyor I2C adresi. O bölüm genel ve tüm aygıtlar için aynı.
 
1684783489877.png


"The upper 8 bits, the integer portion, are at location 11h and the lower 2 bits, the fractional portion." Şimdi 11h adresi sıcaklık tam sayı değerini, 12h adresi sıcaklık ondalıklı değerini verir demiş. Tam mantığı anlamasamda şu şekilde okuma yapıyorum.

C++:
#include "Wire.h"

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Serial.println("SICAKLIK");

}

void loop() {

 Wire.beginTransmission(0x68);// ic2 adresi
  Wire.write(0x11);  // register adresi
  Wire.endTransmission();
  Wire.requestFrom(0x68, 1);  // adresini dediğim cihazdan 1 byte iste
  byte gelen_data = Wire.read();  // geleni oku
  Serial.println(gelen_data);
  delay(1000);
}
1684784004671.png
 
Konuyu biraz anladım. Başka zaman aklıma takılan yönleri bu başlık altında sorgulamaya devam edeceğim.
 
Şimdi I2C de bir "slave address" var. Bu her türlü aygıtta önce yazılan bir veri. Sonra da aygıta özgün veri paketi içeriği var. Senin bahsettiğin (yıl, ay, gün, saat vs) gibi registerlerin adresleri veri paketinin içinde. I2C protokolünü ilgileindirmiyor o kısım.
 
O datasheet'in 16. sayfasında diagram var
Ben de bir RTC entegresi kullandığımda işlemcinin üreticisinin I2C için sağladığı I2C_Write() ve I2C_Read() gibi hazır fonksiyonlar kullandım. Bizim bu diyagramı dikkate alarak koda dökmemize gerek var mı ? Yani atıyorum haberleşmeyi başlatmak için SCL hattını lowa çekmek gibi vs.
 
Ben de bir RTC entegresi kullandığımda işlemcinin üreticisinin I2C için sağladığı I2C_Write() ve I2C_Read() gibi hazır fonksiyonlar kullandım. Bizim bu diyagramı dikkate alarak koda dökmemize gerek var mı ? Yani atıyorum haberleşmeyi başlatmak için SCL hattını lowa çekmek gibi vs.

Birçok I2C API var ortalıkta. Arduino'nunki farklı, ST ninki farklı, PIC inkide farklıdır. Önemli olan fiziksel seviyede I2C protokolünü anlamak. Yani programı ilgili API kullanarak yazacaksın, sonra da osiloskop ile sinyallere bakacaksın. Sinyaller bazında herşeyin doğru olduğunu mutlaka teyit edeceksin, yoksa program tamamen yanlış olduğu halde tesadüfen doğru değerler gelebilir. Veya çoğunlukla doğru çalışır bazan doğru çalışmaz.

Osiloskop ile I2C sinyallerini inceleyeceksin, haberleşme frekansının doğru olduğu teyit edeceksin, sinyal yükselme zamanlarının doğru olduğunu teyit edeceksin, I2C adres, R/W ve ACK bitlerini inceleyeceksin. Start ve Stop diziliminin var olduğunu ve zamanlamalarının da doğru olduğunu teyit edeceksin. Bu düzeyde herşey doğru çalışıyorsa API da doğru sonuç verecektir. Vermiyorsa ya programda yada I2C kütüphanesinde bug olduğunu anlamış olursun.
 
Madem I2C genel konusu olacak. Faydalı bir kaç not düşeyim:

1- Wire.begin() fonksiyonunun SDA pini, SCL pini ve haberleşme hızını verebileceğiniz bir türevi var (tüm işlemciler aynı şekilde destekliyor mu emin değilim, ESP32 için çalışıyor):

C:
bool begin(int sda, int scl, uint32_t frequency=0); // returns true, if successful init of i2c bus

Bu sayede I2Cyi öntanımlı olan pinler dışında pinlerden ve istediğiniz saat hızında (aslında maksimum saat hızı) çalıştırabiliyorsunuz.


2-Özellikle 100KHz üzeri frekanslarda pull-up direnci şart ve normalden düşük tercih etmek lazım. Minimum ve maksimum direnç için genellikle MCU veri sayfasında bir formül oluyor ama hat kapasitansı vb öngörmek gerektiğinden @taydin'ın dediği gibi osiloskop ile sinyalin düzgünlüğünü inceleyerek yapmak daha kolay. düzgün pull-up olmayınca veri hızı da düşük seviyede kalabiliyor.
 
Osiloskop ile I2C sinyallerini inceleyeceksin, haberleşme frekansının doğru olduğu teyit edeceksin, sinyal yükselme zamanlarının doğru olduğunu teyit edeceksin, I2C adres, R/W ve ACK bitlerini inceleyeceksin. Start ve Stop diziliminin var olduğunu ve zamanlamalarının da doğru olduğunu teyit edeceksin.
Ben osilaskopta incemek istedim ama başaramadım. Elle stop yaparak zorda olsa yakaladım. İletişim anının ekranda nasıl durdurum?
 
I2C alışverişi "start condition" ile başlar. Burada önce SDA, hemen sonra da SCL de bir düşen kenar oluşturulur. Eğer nispeten güncel bir dijital osiloskobun varsa, zaten protokol çözümleme yapabiliyordur ve hem start condition, hem stop condition, hem belli bir data patterni, hatta cihazın gelişmişliğine göre ACK/NACK durumunda ve başka birçok durumda trigger ürettirebilirsin.

Ama osiloskopta I2C protokol çözümleme yoksa, o zaman SCL nin düşen kenarına trigger tanımlayabilirsin.
 

Çevrimiçi personel

Forum istatistikleri

Konular
6,955
Mesajlar
118,794
Üyeler
2,824
Son üye
selocan32

Son kaynaklar

Son profil mesajları

hakan8470 wrote on Dede's profile.
1717172721760.png
Dedecim bu gul mu karanfil mi? Gerci ne farkeder onu da anlamam. Gerci bunun anlamini da bilmem :gulus2:
Lyewor_ wrote on hakan8470's profile.
Takip edilmeye başlanmışım :D ❤️
Merhaba elektronik tutsakları...
Lyewor_ wrote on taydin's profile.
Merhabalar. Elektrik laboratuvarınız varsa bunun hakkında bir konunuz var mı acaba? Sizin laboratuvarınızı merak ettim de :)
Lyewor_ wrote on taydin's profile.
Merhabalar forumda yeniyim! Bir sorum olacaktı lcr meterler hakkında. Hem bobini ölçen hemde bobin direnci ölçen bir lcr meter var mı acaba?
Back
Top