AVR 24C32 EEPROM Kütüphanesi Kullanımı
Bu makalede bir önceki makalenin devamı olarak 24C32 EEPROM’a yazdığım kütüphaneyi açıklayacağım ve örnek bir kullanımını göstereceğim.
Öncesinde EEPROM ile çok basit yazma ve okuma işlemi yapmıştık. Bu yapılan işlemler iş görür olsa da çoğu zaman EEPROM’a sadece 8 bitlik sayısal veya karakter verilerini yazmayız. Pek çok zaman 16 veya 32 bitlik verileri yazmak gerekir. Öncelikle en büyük eksikliğin bu olduğunu tespit edip buna yönelik bir kütüphane yazmak istedim. İşin donanım tarafını bir önceki uygulamada yeteri kadar tamamlayıp yazılımı geliştirmeye odaklandım. Öncelikle i2c24c32.h dosyasını inceleyerek kütüphaneyi incelemeye başlayalım.
Burada EEPROM_ADDRESS tanımı kullanıcı tarafından değiştirilebilir. Ben aynı entegreyi aynı adres ayarında kullandığım için yine 0x50 adres değerine ayarladım. Fonksiyon tanımlarında 8 bitlik okuma ve yazma fonksiyonlarının yanında 16 ve 32 bitlik okuma ve yazma fonksiyonları yer almaktadır. Şimdi .c dosyasını inceleyerek bunların nasıl çalıştığını görelim.
.c dosyası çok uzun olduğu için parça parça inceleyeceğim. Bu dosyanın tamamını ileri AVR uygulamaları deposunda (AVRADV11…) bulabilirsiniz.
Burada uint16_t tipinde yani 16 bitlik bir adres verisi almaktayız. Yalnız bu adres verisini 16 bit olarak I2C üzerinden yazmamız mümkün değil. O yüzden 8 bitlik iki parçaya bölüp iki ayrı uint8_t tipindeki değişkene atıyoruz.
uint8_t high_byte = address >> 8;
Burada yüksek bayt 8 bit sağa kaydırılmakta yani 16 bitlik verinin baştaki 8 bitlik parçası 8 bitlik değişkene atanmak için 8 bite çevrilmektedir.
uint8_t low_byte = address & 0x00FF;
Burada ise sadece sağdaki 8 bitlik değeri atayacağımız için AND işlemi uygulanmakta ve soldaki 8 bitlik kısım sıfırlanmaktadır. Böylelikle daha önce uygulamada yaptığımız gibi yüksek ve düşük olmak üzere 8 bitlik iki adres verisini bulunduran değişkenimiz olmaktadır.
i2c_start_wait(EEPROM_ADDR+I2C_WRITE);
i2c_write(high_byte);
i2c_write(low_byte);
i2c_write(data);
i2c_stop();
Burada daha önceki uygulamada yazdığımız kodun aynısını yazdık. Tek yaptığımız farklı işlem adres verilerini yazmaya uygun hale getirmektir.
Bu 8 bitlik okuma fonksiyonunda yukarıda olduğu gibi aynı işlem yapılmakta ve adres değeri 8 bitlik iki parçaya bölünmektedir. Bunun devamında ise önceki uygulamada yaptığımız okuma komutları işletilmekte ve fonksiyon olmasından dolayı veri adında bir değişkene bu okuma atılıp bu değer fonksiyondan döndürülmektedir.
Buraya kadar yaptığımız iş önceki uygulamanın kodlarını alıp fonksiyona göre düzenlemekti. Şimdi ise bu temel fonksiyonları kullanarak yazılım bakımından daha gelişmiş fonksiyonlar yapacağız. Öncelikle 16 bitlik yazma ve okuma fonksiyonlarını inceleyelim.
Buradaki yazma fonksiyonu yine adres ve veri değeri almakta fakat bu aldığı veri değeri uint16_t yani 16 bitlik bir değer olmaktadır. Alınan 16 bitlik değer yazmaya uygun hale getirilmek için yukarıda adres değerine yaptığımız işlem gibi iki adet 8 bitlik parçaya bölünmekte ve bu parçalar ayrı değişkenlere aktarılmaktadır. İlk önce yüksek bayt yazılmakta ve ardından adres değeri bir artırılarak düşük bayt yazılmaktadır. Yani eeprom_write_16bit(0, deger) şeklinde fonksiyonu kullanırsak bu fonksiyon 16 bitlik değeri EEPROM’da 0 ve 1 adreslerine yazacaktır. Bu durumda biz yazma işlemi yaparken adresleri üst üste yazılmasını önlemek adına ikişer olarak artırmamız gereklidir.
Okuma fonksiyonunda ise iki ayrı 8 bitlik değişken oluşturup yine yüksek bayt başta olmak üzere sırayla iki baytlık veri okumaktayız. Yalnız bu sefer okuduğumuz veriler 8'er baytlık olduğu için bunları 16 baytlık veriye çevirip geri döndürmemiz gereklidir. O yüzden high_data << 8 diyerek öncelikle yüksek baytı sola 8 bit kaydırıp yeni oluşturduğumuz uint16_t data değişkenine aktarıyoruz. Sonrasında ise maskeleme yöntemiyle son 8 bitte yer alan veriyi aktarıyoruz. Eğer maskeleme yöntemi yerine değer atama yöntemi kullansaydık başta atadığımız değer yok olacaktı. Buna dikkat etmek gereklidir.
Yukarıda ise 32 bitlik yazma fonksiyonunu görmekteyiz. Bit sayısı arttıkça iş karmaşıklaşır gibi görünse de aslında yaptığımız işin hacmi artmaktadır. Burada alınan 32 bitlik veriyi 8'er bitlik 4 ayrı parçaya bölmekteyiz. Sonrasında ise bayt sırasına göre bu verileri yazmaktayız.
Burada ise 16-bitlik okuma fonksiyonunda olduğu gibi önce 8'er bitlik verileri sırasına uygun olarak okuduktan sonra data adında 32 bitlik bir değişken oluşturup bu değişkenin ilgili bitlerine maskeleme yöntemiyle bu değerleri aktarıp sonrasında bu değişkeni geri döndürmekteyiz.
Buraya kadar kütüphane kodlarını bitirdik. Şimdi bunu uygulamada görelim. Bunun için yine Peter Fluery kütüphanelerini kullanmaktayız.
Öncelikle bir 16 bitlik sabit veri yazıp bunu tekrar okutup seri port ekranına yazdırdım. Sonrasında ise aynısını 32 bitlik veri ile denedim. Bunlar uint16_t ve uint32_t olarak geri döndüğü için işaretsiz tamsayı aralığında olabilir. Ben azami değerleri deneyerek doğru çalışıp çalışmadığını gözlemledim.
Görüldüğü gibi kütüphanemiz gayet iyi çalışıyor ve bundan sonra bir uygulama yaparsam bu kütüphaneyi rahatça kullanabilirim. Kendi yazdığınız kütüphaneyi kullanmanın rahatlığı ayrı olmakta. Özellikle gömülü sistemlerde başkasının yazdığı bir kütüphaneye güvenip, incelemeden her yerde kullanmaya çalışmak sizi oldukça üzebilir.