PIC Assembly Programlamada Bellek Bankları
Genel Bakış
PIC denetleyicilerde; her biri 8-bit genişliğinde olan, Special Function Registers / Özel İşlev Yazmaçları ve General Purpose Registers / Genel Amaçlı Yazmaçların bulunduğu veri bellekleri haritalandırılmış bir yapıya sahiptir. Bu bellek haritası modelden modele değiştiğinden dolayı burada yalnızca PIC16F628A modelinin veri belleği yapısından ve bu bellekte verinin nasıl işlenebileceği ve yönetilebileceğinden söz edeceğim. Bu model üzerinde anlatılacakları kavradığınızda bank yönetimi mantığını kavramış olur; Assembly dilinde, tüm PIC10, PIC12 ve PIC16 serisinin bank yönetimini yapabilirsiniz.
Şunu da belirtmek gerekir ki; kimi PIC modelleri yalnızca tek banktan oluşan bir veri belleğine sahiptir. Bu PIC modelleri için bank yönetimi yapma gereği yoktur çünkü zaten tüm yazmaçlar tek bir bank içinde konumlandırılmıştır. Bu PIC’lere örnek olarak; PIC10 serisinin bir çok modeli, PIC12F508, PIC16F54 gibi modeller verilebilir.
PIC16F628 Denetleyicisinin Veri Belleği Haritasının İncelenmesi

Neden harita diyoruz?
Çünkü bellek gerçekten fiziksel olarak haritalandırılmıştır. Biraz daha açacak olursak:
Resimde görülen kimi boş, kiminde yazı olan dikdörtgen kutuların her biri 8-bitten oluşan bir yazmacı temsil eder. Yazmaç; İngilizce “register” sözcüğünün Türkçe karşılığıdır. Bu kutulardan içinde isim olanlar; Özel İşlev Yazmaçlarıdır (SFR). Alttaki daha geniş kutular Genel Amaçlı Yazmaçlardır (GPR). Gri renkli kutular da fiziksel olarak işlenmemiş alanları temsil eder ki bu alanlara denk gelen adresler okunursa 0 olarak okunur.
Bu yazmaçların her biri tıpkı birkaç sokaktan oluşan küçük bir kasabanın sokak ve binalarının haritalandırıldığı gibi haritalandırılmıştır. Resimdeki kutular arasındaki boşlukları haritalardaki sokaklar, kutuları da binalar ve evler gibi düşünebilirsiniz. Bu harita içindeki her sokak ve binanın kendine has bir adı ve adresi olacaktır.
Burada bu yazmaçlardan herhangi biri ile işlem yapılacağında; bu yazmacın adres bilgisi İşlem birimine (CPU) sağlanmalıdır. Bunu uzakta bulunan bir eve bir posta göndermeye benzetebiliriz. Burada posta kaydedilecek veriyi, adres de verinin teslim edileceği adresi temsil eder. Postayı gönderebilmemiz için; posta merkezine gidecek adresi sağlamamız gerekir ve böylece verilen adres sayesinde posta biriminde çalışan bir postacı, o postayı yüzlerce ev ve binanın içinden yalnızca adresi verilen doğru yere bırakır. Bu yazmaçlarla çalışırken de aslında işlem birimi bir postahane gibi davranır ve yaptığı da aynı şeydir. Yani veriyi (postayı), bellek içinde bulunan yüzlerce yazmaçtan programcının adresini belirteceği yazmaca götürüp teslim etmektir.
Bank Seçimi ve Çalışma Mantığı
Buraya kadar temel veri belleği haritasını, nasıl işlediğini ve bu haritayı neden bilmemiz gerektiğini anlamış olduk. Şimdi ise biraz daha ileri gideceğiz ve bu haritadaki her bir adrese, bankları yani posta örneğimizdeki sokakları kullanarak
nasıl işlem yapabileceğimizi göreceğiz:
Önce şunu bilmemiz gerekir ki: PIC denetleyiciler varsayılan olarak Bank0’dan işlem
yapmaya başlar. Bank0’ı burada sokağımızın adı olarak düşünürsek; bu bankta /
sokakta olmamız demek; bu sokağa kapısı bulunan bütün evlere erişebilmemiz
demektir.
Diğer bir deyişle elimizdeki posta (veri) bu sokaktaki adreslerden birine
gönderilmişse ilgili postayı (veriyi) adresi verilmiş olan eve ya da binaya
bırakabiliriz demektir.
Ancak postalardan hiç biri bu sokaktaki adreslere ait değilse, diyelim ki Bank1
sokağında bulunan 9A numaralı binada olan EEDATA
kişisine ait olsun. Bizim de
Bank0 sokağından çıkıp postayı doğru adrese verebilmek için Bank1 sokağına girmemiz
gerekir ki; 9A numaralı binaya erişebilelim. Bank1’e geçme işlemini BANKSEL
direktifi ile yapabiliriz. Bunu bir assembly kod örneğini kullanarak inceleyelim:
1BANKSEL EEDATA ;Bu direktifle assembler’a EEDATA’nın konumlandırılmış olduğu banka geçmesini söylüyoruz.
2MOVLW d’57’ ;Bu komut gönderilecek veriyi işlem birimine bildirir. Bu veri bizim postamızdır.
3MOVWF EEDATA ;Bu komut da postanın yani verinin gideceği adresi işlem birimine bildirir.
Kod içinde kullanılan BANKSEL
, bir derleyici komutudur Assembly komutu
değil.Yukarıdaki kodlamada bir derleyici komutu olan BANKSEL
kullanılmıştır.
Bu programlama yaparken programcıya zaman kazandırır.
BANKSEL
kullanılmadan yapılmak istenirse Assembly kodu şu şekilde olur:
1BSF STATUS, RP0 ;STATUS yazmacının RP0 bitini 1,
2BCF STATUS, RP1 ;RP1 bitini 0 yapınca BANK1 sokağına geçiyoruz.
3MOVLW d’57’ ;Bu komut gönderilecek veriyi işlem birimine bildirir.
4MOVWF EEDATA ;Bu komut da verinin gideceği adresi işlem birimine bildirir.
EEDATA
veri belleğinde Bank1 sokağında, 9A adresinde konumlandırılmıştır. Ama
burada işlem birimi otomatik olarak sokak/bank değiştirme ya da seçme yeteneğine
sahip değildir. Bu yüzden programcının, 9A (EEDATA
) adresinin tam olarak hangi
sokakta olduğunu da işlem birimine bildirmesi gerekir. İşte bu işleme Assembly
programlamada “Bank Seçme” işlemi denir. Nedir bu işlem?: İşlem birimine postayı
hangi sokaktaki hangi adrese göndereceğini bildirme işlemidir.
Aşağıda RP0
ve RP1
bitleri kullanılarak hangi bankların seçilebileceği
gösterilmiştir.
Yukarıdaki örnek kodda görüldüğü gibi bank seçmek için STATUS
yazmacı kullanılır.
Status yazmacı şöyle görünür:

IRP
, RP1
ve RP0
bitleriyle ne ilgisi var diye
düşünenler olabilir. Şunu diyebilirim ki; doğrudan doğruya ilgisi var. Çünkü
bankların denetim yolları bu bitler üzerinden geçiyor. Bu yollar demultiplexer'lere
yani kodçözücü/seçici devrelerine bağlanır. Dijital/Sayısal Elektronik derslerine
iyi çalışanlar bu devreleri iyi bilirler ;)) . İhtimal gömülü olarak
74LS155/156 gibi bir ikiden dörde seçici devresi kullanılmıştır. 74LS155/156
tümdevresinin (entegre) iç yapısını merak ederseniz üzerindeki bağlantıdan
veribetini (datasheet) inceleyebilirsiniz (İngilizce). Bu tümdevrenin içinde
2 tane ikiden dörde kod çözücü vardır.
RP0
ve RP1
bitleri bu seçicinin girişlerine, banklar da bu seçicinin
çıkışlarına bağlıdır. Bu yapıyı yukarıdaki kasaba-sokak-postacı örneğine
pekiştirdiğimizde bu bitler o kasaba ve sokaklara geçişi denetleyen birer bariyer
gibidir. Bu bariyerleri gerektiği gibi açıp kapatarak ancaküzerindenistediğimiz
sokağın ya da kasabanın yoluna girebiliriz. Bunu daha iyi anlayabilmek için
aşağıdaki hazırlamış olduğum temsili blok diyagramı gif resmini izleyelim. Bu blok
diyagramı tahmini olarak hazırladım, çipin içinde bağlantı ve yollar tam böyle
olmayabilir ancak çalışma biçimi tam olarak böyle.

Şimdi PIC16F628A tümdevresinin veribetinde(datasheet) verilmiş olan bank seçim tablosuna yeniden bakalım:

Görüldüğü gibi tam olarak bank seçim tablosundaki değerlerle bire bir çalışıyor.
Yanlış Bankta Çalışmanın Sonuçları
Peki verileri yazarken doğru Bankı seçmezsek ne olur? Bu durumda istenmeyen veri teslimi gerçekleşir ve umulan veri umulmayan yerlere yazılır.
Örneğin; Bank1 içinde bulunan A0h adresine atadığımız bir değişken olan TOPLAM değişkenine işlem sonuç verilerini yazdırmak istiyoruz ve o andaki konumumuz Bank0. Eğer veri yazma işleminden önce Bank1’e geçmezsek, işlem birimi bulunduğu banktaki (Bank0) karşılık gelen adrese veriyi yazacaktır. A0h adresinin Bank0 içindeki karşılık gelen adresi 20h’dir. Dolayısıyla veriler bu adrese yazılır. Sonra bu işlem sonucunu bu değişkenden okumak için Bank1’e geçip A0 adresini okuduğumuzda ise koca bir 0 değeri elde ederiz çünkü işlem sonucu Bank0’daki 20h adresine yazılmıştır.
SFR Yazmaçlarını Yanlış Bankta Yüklemenin Sonuçları
SFR yapılandırmalarını yaparken doğru banka geçmezsek ne olur? Bu program açısından daha ölümcül bir hata olacaktır çünkü denetleyici; işlev ayarları doğru denetim yazmaçları üzerinde yapılmadığı için, denetim yazmaçlarının reset sonrası durumlarını okuyacaktır. Bunu şöyle bir örnekle pekiştirebiliriz:
Diyelim ki Port giriş – çıkışları yapılandırılıyor. PORTB
çıkış olarak ayarlanmak
isteniyor. Bunun için Bank1’e geçip TRISB
yazmacına 0 değeri yüklememiz
gerekir. Ancak Bank1’e geçilmeden TRISB
yazmacına değer yüklenmeye kalkılırsa,
Bank0’da olduğumuzu düşünürsek bu değer aslında PORTB
’ye yüklenmiş olacak ve
TRISB
varsayılan olarak reset sonrası tüm port bacaklarını giriş olarak
yapılandırdığından, PORTB
hep giriş olarak kalacaktır. Dolayısıyla PORTB
bacaklarına bağlı hiç bir şey denetlenemeyecektir. Örneğin PORTB
’nin 3. bacağına
bağlı bir led yakılıp söndürülemeyecektir.
Sonuç
Sonuç olarak Assembly programlama yapılmak istenirse doğru bank seçimini yapmak çok önemlidir. Doğru bank seçimi yapılmadığı durumda yazılan program istendiği gibi işlemeyecek ve sürekli hatalı sonuçlar üretecektir. Bu yüzden doğru bankın seçildiğinden emin olmak programcının sorumluluğundadır.
Bu uygulamanın kodları MIT lisansı altında paylaşılmaktadır.