MSP430 ile Assembly’ e Giriş

 Merhabalar..

 Bu konuda yeni yeni kullanmaya başladığım elektronik kartlardan olan MSP430 ile ilgili izlenimlerinden bahsedip, basit bir kaç uygulamaya yer vereceğiz. 

 Öncelikle neden MSP430  olduğuna ufak bir değinelim. İlk sebep okulumuzda mikroişlemciler dersinde bize bu kart ile assembly’ in anlatılıyor olması. İkinci sebep düşük güç kullanımında ilk bakılan elektonik kart olması ve düşük enerjili sistemlerin günümüzde çokca ihtiyaç duyulması, üçünce sebep ise Arduino kadar olmasa da son derece yaygın olması ve TI’ ın bu karta verdiği büyük destek ile gelecekte de karşıma çıkma ihtimalinin son derece yüksek olması gibi sebeplerden ötürü bu kart üzerinde çalışmaya başladım.

 Peki ya neden Assembly? Bu sorunun cevabını çalışmaya başlayana kadar bende merak ediyordum. Ancak kullanmaya başlayınca anlıyorsunuz ki C ve benzeri orta seviye veya üst seviye programlama dillerinin farkında olmadan bize koyduğu sınırlara Assembly ile takılmıyorsunuz. Yada işlemler için anlamlı anlamsız bir çok değişken tanımlamanız gerekmiyor. Direk adres üzerinden istediğiniz yere istediğiniz bilgiyi yazabiliyorsunuz…

 Dezavantajları yok mu? Elbet var. En büyük dezavantajı son derece zor bir dil olması. Bu zorluk hem kod uzunluğu hem kod yapısı bakımından bir zorluk. C’ de 5 satırda yapacağınız bir işi belki Assembly ile 15 satırda yapmanız gerekebiliyor. (Tersi de olabiliyor ancak bu durum ilk olasılığa göre daha nadir :) ) Yada en basitinden bir bölme yada çarpma işlemi için C de basit bir hesap makinesiymiş gibi işlem yapabilirken Assembly’ de işler iyice karışıyor.

 Assembly’ de kod yazmaya başlamadan önce nelere ihtiyacımız var? Kullanacağımız kartın datahseet  ve user guide dokümanlarına sahip olmanız, donanımı assembly ile programlamanız için yeterlidir. Ben işlemlerinde MSP430F5529 isimli donanımı kullanacağım. Ancak en çok kullanılan MSP kartı MSP430G2553 modeli olduğu için aradaki RAM boyutu ve aralığı, GPIO port ları gibi bazı farklılıklardan da kodların diğer cihazda kullanımı için değineceğim.  Bu linklerden 2 donanımında datasheet ve user guide dokümanlarına ulaşabilirsiniz.

MSP430F5529 User guide                        MSP430G2553 User Guide

MSP430F5529 Datasheet                          MSP430G2553 Datasheet

 Dokümanlarımız da tamam çalışmaya nereden başlamalıyız? Benim tavsiyem (ve benimde izlediğim yol) RAM bölgesi üzerinde toplama, çıkarma, en büyük en küçük bulma gibi işlemler ile başlamak mantığın daha iyi oturması için çok daha uygun bir yol. Bu yüzden ilk örneklerde RAM bölgesinden bir kaç örnek vermeye çalışacağım. Daha sonraki konularda GPIO’ lar ile giriş, çıkış ve interrupt örnekler vermeye çalışacağım.

 Assembly kodlarında komutların hangisnin ne işe yaradığına user guide’ da instruction set başlığı altından detaylıca ulaşabilirsiniz. Basit ingilizce biliyor olmanız anlamanız için yeterli olacaktır. Ancak özellikle CMP, ve buna bağlı olarak Status Register üzerinden sorgularının kullanımı dikkat edilmesi gereken bir durum Assembly için. Bu yüzden örneklere başlamadan sorgu komutlarının kullanımına ufak bir değineceğim. 

Bu kısımda anlatılacaklar  User guide içerisinde Instruction Set Description başlığı altına bulunmaktadır.

 


 

“Compare” komutu ile komutlara başlayalım

cmp” komutunun detaylı kullanımı kısmında operation diye gösterilen, komutun aslında ne yaptığını matematiksel olarak ifade eden bir gösterim var. Operation, cmp komutu için “dst – src” şeklinde gösterilmiştir.

Burada:

dst –> destination (hedef)

src –> source (kaynak)           anlamına gelmektedir.

Siz Assembly de bir kod kullanırken eğer two operand (iki parametreli şeklinde düşünülebilir) kod kullanıyorsunuz genel gösterim bu şekildedir. Bunun manası da ilk parametre değer yada kaynak ikinci parametre ise bu değerin etki edeceği hedef şeklinde yorumlanabilir.

 

cmp komutu için dst – src nin manasını bir örnek ile açıklayalım.

cmp  #010,  r5    ==>    r5 adresindeki değerden 10 decimal değerini çıkar.

Üst tarafta bu komutu karşılaştırma yapmak için kullanırız demiştik. Ancak burada çıkarma yaptırdık diye siz düşünmeden hemen karşılaştırma kısmına gelelim. .. :)

 

Assembly’ de karşılaştırma işlemleri Core Register kısmındaki, Status Register(SR) üzerinden yapılır. Status register’ de bizim karşılaştırmalar için kullandığımız 4 tane register vardır.

C ==> Taşıma işlemi olduğunda setlenen bit’ tir

V ==> Aritmetik işlemlerde taşma olduğunda set’ lenir. (16 bitlik ifadenin 17′ ye taşması)

Z ==> Bir işlemin sonucu 0 olduğu zaman set’ lenir.

N ==> Bir işlemin sonucu negatif olduğu zaman set’ lenir.

cmp kodu gerekli karşılaştırmayı çıkarma işlemi gibi yaptı. Bu çıkarma işleminin sonucu:

– negatif ise SR’ de N biti setlenir.

– sıfır ise SR’ de Z biti setlenir. Taşma ve taşıma bitinin setlendiği durumlara ben ihtiyaç duymadığım için açıklama gereği duymadım. Ancak örnekli açıklamasına yine user guide’ den ulaşabilirsiniz.

Şimdi gelelim bu bit’ lerin durumuna göre atlama işlemlerine. Atlama işlemlerini yapan komutlar JC/JHS, JEQ/JZ, JGE, JL, JN, JNC/JLO, JNZ/JNE ve JMP komutlarıdır. Bunlardan jmp şartsız olarak istenilen yere atlama yapar. Bunun dışında diğerleri için;

JC/JHS ==> C bitinin durumuna bakar. Eğer set’ lenmişse istenilen yere atlar.

JEQ/JZ ==> Z bitinin durumuna bakar. Eğer set’ lenmişse istenilen yere atlar.

JGE        ==> N xor V işlemini yapar. Sonuç 0 ise(N ve V aynı anda 0 yada 1 ise) istenilen yere atlar.

JL           ==> N xor V işlemini yapar. Sonuç 1 ise (N ve V farklı ise) istenilen yere atlar.

JN           ==> N bitinin durumuna bakar. Eğer set’ lenmişse istenilen yere atlar.

JNC/JLO ==> C bitinin durumuna bakar. Set’ lenmemişse istenilen yere atlar.

JNZ/JNE ==> Z bitinin durumuna bakar. Set’ lenmemişse istenilen yere atlar.

 Bu komutların aslında ingilizce karşılıklarının kısaltmasıdır. Örneğin JC komutu “jump if carry set” ‘ den gelmektedir. Yada JGE komutu “jump if greater of equal” şeklindedir. Burda büyük olması istenen cmp’ deki ikinci parametre yani destination(hedef) kısmıdır.

 Eğer ki siz bu komutlara hakimseniz, Assembly’ de başlangıç seviyesindekibir çok yazılımın ne iş yaptığını rahatlıkka anlayabilirsiniz. Şimdi bir kaç uygulama yapalım.

RAM bölgesinde 2400h ile 2410h arasındaki pozitif sayıların toplamını veren bir uygulama yapalım:

 

 Önemli NOT: MSP430F5529 RAM bölgesi 2400H ile 4400h arasındadır. Eğer siz farklı bir MSP ürünü kullanıyorsanız bu RAM bölgesi farklı olabilir. Örneğin MSP430G2553 için bu alan 0200h adresinden başlar. Bu yüzden de örneklerdeki RAM adreslerini sizdeki MSP430 ürününe göre değiştirmelisiniz.


 

 Öncelikle kullanacağımız registerleri temizleyelim

        clr     r5              ;registerleri temizledik
        clr     r6
        clr     r7

 Burada r5 registerini indexli adresleme için kullanacağız. r6 ve r7 ise toplama işlemini yapacağımız registerler olacak. r6 ‘da pozitif sayılar geldikçe ekleme işlemi yapılırken, bu toplamın 16 biti taşması durumundaki taşmayı r7 registerine ekleyeceğiz.

 Şimdi sıra geldi pozitif ve negatif sorgusuna. Bu işlemi mikroişlemci komutlarından tst komutu ile yapacağız.

 Bu komut hedef adresteki değer negatif N bitini setler, sıfır ise Z bitini setler. Eğer ki N biti setlenmişse bizim algoritmamız gereği atlama yapmamız gerekiyor. Bu sebeple buna uygun atlama komutu olan JZ komutunu kullanacağız. Bu komut eğer zero biti setlenmişse (yani hedef adresdeki değer negatif ise) toplama işlemini geçmemizi sağlayacak.

basla   tst     2400h(r5)               ;adresdeki değeri test ettik
        jn      atla                    ;eğer negatif ise atladık
        add     2400h(r5), r6           ;değilse toplama işlemi yaptık
        adc     r7                      ;taşma varsa taşmayı r7 ye ekledik

 Daha sonra indexli adresimizin değerini arttırıp kontrol ederek işlemi sonlandırdık.

atla    incd    r5                      ;indexli adres için kullandığımız registerin
        cmp     #010h, r5               ;değerini arttırdık. Değer f olmuşsa işlemi
        jnz     basla                   ;sonlardık

        nop

 

ram2
Resmi Büyültmek İçin Resme Tıkla

 

Yazılımın tamamına buradan ulaşabilirsiniz.


 

32 bitlik sayı LSB ve MSB

 

Şimdi 32 bitlik iki sayının toplamını yapan bir kod yazalım. MSP430′ da adres bölgeleri 16 bitlik olacak şekilde tasarlanmıştır. Yani siz 16 bitlik bir sayı ile işlem yapacaksanız iki adres bölgesine ihtiyacınız var demektir. Biz sayının göze düzgün görünür olması için yan yana iki adres böglesni kullanacağız. Öncelikle bu alanı temizleyelim.

        ;kullanacağımız adres bölgesini sıfırladık
        
        clr     r5
m1      clr     2400h(r5)
        incd    r5
        cmp     #020h,  r5
        jnz     m1

Şimdi bu bölgede 2402h adresine ilk sayının anlamlı kısımı 2404h ise anlamsız kısmını yazalım. İkinci sayıyı da hemen altına denk gelecek şekilde yerleştirelim.

        ;32 bitlik sayı ilk sayıyı tanımladık
        
        mov     #0f010h, &2402h      ;anlamlı ksıım
        mov     #08010h, &2404h      ;anlamsız kısım
        
        ;32 bitlik sayi ikinci sayıyı yanımladık
        mov     #0ffffh, &2412h      ;anlamlı kısım
        mov     #08020h, &2414h      ;anlamsız ksıım

 

ram0
Resmi Büyültmek İçin Resme Tıkla

Sıra geldi bunları toplamaya. Toplama işlemini her zamanki gibi yapacağız. Ancak burada sayı 32 bitlik olduğu için iki aşamalı bir işlem gerekli. İlk aşamada anlamsız kısımları kendi arasında toplayacak, ikinci aşamada ise anlamlı kısımları toplarken birde anlamsız kısımdan gelen eldeyi işleme dahil edeceğiz.

        add     &2404h, &2414h       ;anlamsız kısımları topladık
        addc    &2402h, &2412h       ;anlamlı kısımları elde ile birlikte toplatk
        adc     &2410h               ;taşma yı yazdırdık
        
        nop
ram1
Resmi Büyültmek İçin Resme Tıkla

 

Yazılımın tamamına buradan ulaşabilirsiniz.


 

 Şimdide en küçük negatif sayı ile en büyük pozitif sayıyı bulan bir program yazalım. Burada dikkat edilmesi gereken bir detay var. Eğer bir en büyük sayıyı bulmak için karşılaştırma yapacaksak kıyaslayacağımız sayıyı başta gelebilecek en küçük sayı seçmeliyiz. Aksi taktirde kıyaslama için seçtiğimiz sayı en büyük sayıdan zaten büyük olur ve en büyük sayıyı bulamayız.

 İlk olarak register ayarlarını yapalım

        clr     r5                      ;index registerini temizledik
        mov     #00h, r6                ;en küçük pozitif sayı
        mov     #07fffh, r7             ;en büyük pozitif sayı

 Burada en büyük pozitif sayıya negatif sayıları kıyaslarken ihtiyaç duyduk. En küçük pozitif sayıya ise pozitif sayıları kıyaslarken. Bunun yerine ffff de yazabilirsiniz.

 

basla   tst     2400h(r5)               ;sayıyı kontrol ettik
        jn      m1
        cmp     r6, 2400h(r5)           ;sayı pozitif ise devam ettik
        jn      art
        mov     2400h(r5), r6           ;adresdeki değer daha büyükse r6 ya yazıldı
        jmp     art                     ;indexli adres değerini arttırmak için
                                        ;atladık

 Burada indexli adres ile taranan RAM bölgesindeki değerlerin önce pozitif mi yoksa negatif mi olduğuna baktık. Eğer sayı pozitif ise r6 adresindeki değer ile karşılaştırmaya tabi tuttuk. Negatif ise:

m1      cmp     r7, 2400h(r5)           ;sayı negatif ise buraya atladık
        jn      art     
        mov     2400h(r5), r7           ;adresdeki değer daha küçükse r7 ye yazıldı

 

ram3
Resmi Büyültmek İçin Resme Tıkla

 

Yazılım tamamına buradan ulaşabilirsiniz.


Bu yazının sonuna geldik. Bu yazı ile birlikte gpio ve interrupt uygulamarınıda açıklayacaktım lakin yazı iyice uzun olmaya başladı. Bu yüzden bir sonraki yazıya eklemeye karar verdim. GPIO örneklerine buradan ulaşabilirsiniz. 

Ayrıca son bir not RAM bölgesi uygulamaları IAR ile yazılmıştır. Lakin GPIO işlemleri için Code Composer Studio(CCS) kullandım. Bunun sebebi RAM bölgesini görüntülemede IAR’ ın çok kullanışlı olması. Diğer işlemler için şiddetle CSS’ i kullanmanızı tavsiye ederim. Benim karşılaştığım çok ufak tefek kod farklılıkları bulunmakta bunlara diğer konuda değineceğim.


Diğer çalışmalarım için

 

İyi Çalışmalar.

 

Add a Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir