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
Yazılımın tamamına buradan ulaşabilirsiniz.
Ş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
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
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ı
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.