Site içi Arama

Ara

PIC Mikrodenetleyicilerde Bankların Kullanımı

İsmail Sahillioğlu - 18.04.2017
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.

PIC16F628A Denetleyicisinin Veri Belleği Haritasının İncelenmesi


Resimde 16F628A denetçisinin veri belleği haritası gösterilmiştir. 

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.

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:

BANKSEL	   EEDATA       ;Bu direktifle assembler’a EEDATA’nın konumlandırılmış olduğu banka geçmesini söylüyoruz.	
MOVLW d’57’ ;Bu komut gönderilecek veriyi işlem birimine bildirir. Bu veri bizim postamızdır.
MOVWF EEDATA  ;Bu komut da postanın yani verinin gideceği adresi işlem birimine bildirir. 

Bilgi: 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. Aynı derleyici komutu olan BANKSEL kullanılmadan yapılmak istenirse Assembly kodu şu şekilde olur:

BSF		STATUS, RP0	;STATUS yazmacının RP0 bitini 1 yapınca BANK1 sokağına geçiyoruz.
MOVLW d’57’ ;Bu komut gönderilecek veriyi işlem birimine bildirir.
MOVWF 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.

Şimdi biraz daha ileri gidiyoruz ve kasabalar arası  nasıl posta göndereceğimizi betimliyoruz:

8-bit mikrodenetleyicilerde; tek bir adres seçici yazmaçla yalnızca 256 adres konumu indekslenebilir.  Yani heksadesimal olarak 00’dan FF ‘ye kadar indeksleme yapılabilir. 

Bu sınır veri belleğinde bir sayfayı oluşturur. Bu şu demektir:

00’dan FF’ye kadar olan bölge bir kasaba içinde, 100’dan 1FF’ye kadar olan bölge de başka bir kasaba içinde yer almaktadır. Bu 00 – FF aralığında adresli ilk kasabanın adı 1.SAYFA kasabası, 100 – 1FF adresli bögenin kasabasının adı da 2.SAYFA kasabasıdır. Şimdi verilen bellek haritası resmine bir bakınız. BANK0 sokağının ilk adresi 00’dan başlıyor, ve BANK1 sokağının son adresi FF adresinde bitiyor. Bu demek oluyor ki; BANK0 ve BANK1 sokaklarındaki adreslerde bulunanlar 1.SAYFA kasabasına aittir. 

Aynı şekilde BANK2 sokağının ilk adresi100’dan başlıyor, BANK3 sokağının son adresi 1FF numarasında bitiyor. Böylece BANK2 ve BANK3 sokaklarında bulunan adresler de 2.SAYFA kasabasında yer almış oluyor. Bu durumda bizim işlem birimine gönderdiğimiz verinin 1.SAYFA kasabasındaki adrese mi yoksa 2.SAYFA kasabasındaki adreslere mi gideceği bilgisini de vermemiz gerekiyor ki; işlem birimi postayı(veriyi) doğru kasabada konumlanmış olan adrese teslim etsin. PIC denetçileri varsayılan olarak 1.SAYFA’da çalışacak şekilde üretilmişlerdir. Bu durumu da bir Assembly kod örneğiyle inceleyelim:

Diyelim ki BANK2’nin 120h numaralı adresinde SAYAC adında bir değişken oluşturduk ve bu değişkene desimal 100 değerini posta olarak göndereceğiz. Denetçi varsayılan olarak 1.SAYFA’da olduğu için önce;

PAGESEL	   SAYAC      ;Direktifini kullanarak assembler’a 2.SAYFA kasabasına gitmesini söylüyoruz.
MOVLW d’100’     ;Gönderilecek veriyi(postayı) bildir.
MOVWF      SAYAC      ;Ve veri(posta) istenen kasabadaki istenen adrese teslim edilmiş oluyor, bu kadar basit.

Bilgi: Kod içinde kullanılan PAGESEL, 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. Aynı derleyici komutu olan BANKSEL kullanılmadan yapılmak istenirse Assembly kodu şu şekilde olur:

BSF		STATUS, RP1	;Burada RP1 biti 1 yapılır
BCF STATUS, RP0 ;Burada da RP0 biti 0 yapılır böylece BANK2 sokağına geçilmiş olur.
MOVLW d’100’ ;Veri işlem birimine bildirilir.
MOVWF SAYAC ;İşlem birimi de veriyi belirtilen adrese postalar.

Bilgi: Sayfa seçimi işlemi; STATUS yazmacı içindeki 7. bit olan IRP biti 1 yapılarak da gerçekleştirilebilir. (Ancak IRP bitiyle sayfa değiştirme işi daha çok dolaylı adresleme kullanarak sıralı yazma ve silme işlemleri yapılırken kullanılır.) Ayrıca programın ilk başlarken, programın doğru sayfada olduğundan emin olmak için de kullanılabilir. Aşağıda bunun kod örneği veriliyor:

ORG		0x00
PAGESEL GIRIS
GOTO GIRIS

Bunlar dışında bank seçim işlemleri STATUS yazmacının RP0 ve RP1 bitlerini kullanarak yapılır.

Aşağıda RP0 ve RP1 bitleri kullanılarak hangi bankların seçilebileceği gisterilmiştir.


Aşağıda STATUS yazmacı görülüyor.


Peki bank seçmenin STATUS yazmacının 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 2'den 4'e seçici devresi kullanılmıştır. 74LS155/156 tümdevresinin (entegre) iç yapısını merak ederseniz aşağıdaki bağlantıdan veribetini (datasheet) inceleyebilirsiniz (İngilizce). Bu tümdevrenin içinde 2 tane 2'den 4'e kod çözücü vardır.

http://www.ti.com/lit/ds/symlink/sn74ls156.pdf

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 üzerinden istediğ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.

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(Özel İşlev Yazmaçları) 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 0x00 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ç 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.


E-posta: ismailsahillioglu@gmail.com

Endüstriyel Otomasyon - Elektronik Teknikerliği

Yorumlarınız

Hiç yorum yapılmamış, ilk yorumu siz yapabilirsiniz.

Yorum yapabilirsiniz

İsim:
E-posta:
Yorumunuz:
Güvenlik Kodu:
 
Tüm alanları doldurmak zorunludur. Yorumunuz kontrol edilince yayınlanacaktır
Sayfa Etiketleri:Asm (2)
İçerik Yan Blok
Konular
Tasarım: Teknimer Teknoloji
Yukarı