PIC Programlama – 10 – EEPROM

Merhabalar, doktora yeterlik sınavı dolayısıyla ara verdiğim blog yazılarıma, yeterlik aşamasını geçtiğimden dolayı devam ediyorum 😀 PIC16F84A ile ilgili, geriye kalan son bir iki konuyu da irdeleyeceğimiz bu yazıda, ana gündemimiz EEPROM olacak.

“EEPROM nedir?” sorusuna yanıt arayanlar için WIKIPEDIA sayfasında yeterli bilgi olduğunu belirtmek isterim. Kısaca özetlemek gerekirse EEPROM, elektriksel olarak yazılıp silinebilen, kalıcı bir bellek tipi; yani elektrik gitse de içerisinde kayıtlı olan veri kendiliğinden silinmiyor. Flash belleğe göre yazım ömrünün çok fazla olması, bu devre elemanını bu gün dahi popüler tutmaya yetiyor.

PIC16F84A içinde de 64 byte’lık bir EEPROM bulunuyor. 64 byte kadar küçük bir EEPROM olsa da, özellikle kalıcı konfigürasyonları saklama konusunda, bu modül hayat kurtarıyor. Bu durumda bize düşen de, PIC16FLIB adıyla geliştirdiğimiz alternatif PIC kütüphanesine bu modülü de eklemek olacak. Öyleyse hemen başlayalım!

İlk adım olarak, her zamanki gibi datasheet’i okuyup anlayarak, yazılımsal olarak modelleyeceğiz. Datasheet’te EEPROM modülü, sistemin blok diyagramında şöyle yer alıyor:

PIC16F84A veri kağıdından alınmıştır.

Buradan da görüldüğü gibi EEPROM modülümüz 64*8 bitlik veriyi saklayabiliyor. Şimdi de, EEPROM ile ilgili kütüklerin (register), hangi adreslerde olduğuna bakalım.

İlgili kütükleri fosforlu sarı ile işaretlediğimden adreslerini görebilirsiniz. Artık adreslerini ve yapılarını da bildiğimizden, bu kütükleri yazdığımız PIC kütüphanesine ekleyebiliriz. EEPROM modülünü de derlemeye dahil edip etmemeyi seçimli yapmak için işe pic16flib_conf.h dosyasına aşağıdaki işaretli satırı ekleyerek başlıyoruz.

Şimdi pic16f84a_lib.h içerisindeki kütük tanımlamalarına geçelim. Aşağıdaki işaretli satırları pic16f84a_lib.h dosyasına ekliyoruz.

Register tanımlarını nasıl yaptığımızı daha önceki yazılarda çokça açıkladığımdan bu defa tekrara düşmemek adına açıklamayacağım. Her zamanki gibi, veri kağıdındaki bilgileri modelleyerek kütük tanımlarını yaptık.

Şimdi gelelim eeprom’dan veri okuma ve eeprom’a veri yazma fonksiyonlarına. Onları da aşağıda görebilirsiniz:

Her iki fonksiyon girişinde de, girilen adresin 63 değerinden büyük olup olmadığını kontrol ettik. Toplamda 64 byte’lık bir eeprom’umuz olduğundan, en yüksek adres 63 oluyor. Ardından okuma yapmak için, okuma yapacağımız adresi seçtik. Sonrasında RD bitini 1 yaparak okumayı başlattık ve okunan değeri REG_EEDATA kütüğünden okuduk.

Yazma kısmında ise işler biraz daha karışık şekilde çözülüyor. Yine adres seçimini yaptıktan sonra ilk iş olarak yazmak istediğimiz veriyi REG_EEDATA kütüğüne yazıyoruz. Ardından WREN bitini 1 yaparak yazma izni vermiş oluyoruz. Sonrasında, veri kağıdından okuduğumuza göre EECON2 kütüğüne sırasıyla 0x55 ve 0xAA yazmak gerekiyor. Bu, koruma amaçlı konmuş ve veri kağıdına üretici tarafından yazılmış bir ek sekans 🙂 Kodu yazan ne yaptığını biliyorsa, ancak o zaman yazabilsin demişler. Saygımız sonsuz 😉 Ardından WR bitini 1 yaparak yazım sürecini başlatıyoruz. Yazım hemen bitmiyor; bu durumda yazımın bittiğini anlayabilmek için tek çaremiz EEI (eeproma veri yazıldı) kesmesini kurarak, kesme bayrağı 1 olana kadar beklemek. Burada bekleme işini asm(“nop”); satırı ile yaptık. asm(KOMUT) fonksiyonu, XC8 derleycilerinde C kodunun içerisnde assembly komutları çağırmaya yarar. Biz de “nop” yani “bir şey yapmadan 1 saat darbesi bekle” komutunu çalıştırarak bekleme sağladık. Ardından kesme bayrağı 1 olup while döngüsünden çıktığımızda kesmeyi kapatıp, kesme bayrağını temizleyip, WREN kütüğünü sıfara çekerek çıkıp gidiyoruz 🙂 Verimiz yazıldı.

Dikkat! Burada while döngüsü sonsuza kadar sürebilir. Bunu engellemek için while içinde bir değişkeni her turda 1 artırıp, döngü sayısı bir üst sınır değerini geçerse ve yazım işlemi hala bitmemişse hata döndürerek çıkmasını sağlamakta fayda vardır.

Yukarıdaki fonksiyonların eklendiği durumda pic16f84a_lib.c dosyamız şöyle oluyor:

Artık kütüphanemiz hazır olduğuna göre, basit bir test fonksiyonu yazacağız. 0x01 adresli EEPROM bellek alanına 1 byte’lık ‘X’ karakterini yazan ve doğru yazıp yazmadığını kontrol eden bir kod, aşağıda yer almakta.

Bu kodumuz, yazım ve okuma işlemleri başarılı ise B portuna 0xAA yazıyor. Eğer hata olursa B portu ilk değeri olan 0x00 değerinde kalıyor. B portuna 0xAA=10101010 değerinin yazılması, sırasıyla pinlerin yüksekte ve alçakta olmasına sebep oluyor.

Kodda bir diğer önemli kısım ise #pragma ile başlayan konfigürasyon satırları. Buna göre osilatör olarak kristal osilatör seçmiş olduk. Ayrıca, mikrokontrolörün donup kaldığı durumlarda ona reset atacak olan watchdog timer modülünü aktive ettik. Yine güç dalgalanmalarında reset atmaya yarayan power on reset’i aktive ettik ve kod korumayı kapattık. Kod koruma açık olarak mikrokontrolöre yazılım atarsanız, o kod bir daha okunamayacak ve kolaylıkla değiştirilemeyecektir. Prototip aşamasında CP (code protection, kod koruma) seçeneğini OFF yapınız (varsayılan değer de budur).

Bu kodun çalıştığı duruma ilişkin Proteus ISIS simülasyon çıktısı ise aşağıda yer alıyor.

Gördüğünüz gibi, EEPROM sürücümüz de başarıyla çalışıyor 🙂

Projenin kaynak kodlarını BURADAN indirebilirsiniz.

Bu günlük de bu kadar. İleride yeni yazılarla devam edeceğiz.

Yazıları beğendiyseniz, faydalanabilecek tanıdıklarınızla paylaşmayı unutmayınız.

Önceki Sayfa   Sonraki Sayfa

Leave a Reply