
Merhaba Arkadaşlar,
Bugün ilk programımızı yazacağız. Umarım heyecanlısınızdır çünkü heyecan istekli olduğunuzu işaret eder. 🙂 Nasıl ki yazılım dillerinde ilk olarak “Hello World” çıktısı veren programı yazılıyorsa, donanım programlamada da ilk olarak LED yakıp söndürme programı yazılır. İşin raconu budur. 🙂 Bu nedenle biz de racona uyarak bu yazıda LED yakıp söndürme programı yazacağız.
Programa geçmeden önce kullanacağımız kaydediciler ve komutlara kısaca değinmek istiyorum.
- P1DIR Kaydedicisi (8 bit): Port1 modülünün pinlerinin giriş-çıkış tanımlama bilgilerini saklayan kaydedicidir.
- P1OUT Kaydedicisi (8 bit): Port1 modülünün çıkış olarak tanımlanan pinlerinin durum bilgisini (HIGH veya LOW) saklayan kaydedicidir.
- R4 Kaydedicisi (16 bit): Genel amaçlı veri kaydedicisidir.
- bis kaynak, hedef Komutu: kaynak adresteki veriye göre hedef adresteki istenilen bitlerin setlenmesini (HIGH konumuna geçirilmesi) sağlayan komuttur.
- bic kaynak, hedef Komutu: kaynak adresteki veriye göre hedef adresteki istenilen bitlerin temizlenmesini (LOW konumuna geçirilmesi) sağlayan komuttur.
- mov kaynak, hedef Komutu: kaynak adresteki verinin doğrudan hedefe adrese aktarılmasını sağlayan komuttur.
- xor kaynak, hedef Komutu: kaynak adresteki veriyi hedef adresteki veri ile XOR işlemini soktuktan sonra hedef adrese kaydeden komuttur.
- jnz etiket Komutu: jump if not zero kendisinden önce yapılan işlemin sonucunun sıfır olmadı (yani sıfır bayrağı kalkmadığı) sürece önünde bulunan etiketin satırına atlama yapan komuttur.
- jmp etiket Komutu: koşulsuz önünde bulunan etiketin satırına atlama yapan komuttur.
- call etiket Komutu: önünde bulunan etiketin alt programına geçişi sağlayan komuttur.
- ret Komutu: alt programdan ana programa dönüşü sağlayan komuttur.
- org adres Komutu: yazılan kodların flash bellekte kaydedileceği adresi girdi alan komuttur.
- dec hedef Komutu: hedef adresteki veriyi 1 azaltan komuttur.
Bu komutlar ilk aşamada anlamsız gelebilir ancak korkmayın program içerisinde kullandıkça her şey daha anlaşılabilir olacak.
Şimdi programı yazmaya başlayabiliriz. Assembly programlamada ben programı 4 temel bölüme ayırıyorum. Bunlar;
- Ayarlama
- Ana program
- Alt programlar ve kesme programları
- Kesme vektör tablosu
bölümleridir. Şimdi LED yakıp söndürme programını yazmaya başlayıp aynı zamanda bu bölümleri tanıyalım.
1. Ayarlama Bölümü
Bu bölümde işlemcinin ve kullanacağımız modüllerin ayarlamalarını yapmamız gerekmektedir. Biz ilk programımızda sadece Port1 modülünü kullanacağız. Şimdi LED yakıp söndürme programı için yazdığımız ayarlama bölümü kodlarını inceleyelim.
#include "msp430.h"
org 0f800h
reset mov #0280h,SP
mov #WDTPW+WDTHOLD,&WDTCTL
bis.b #01h,&P1DIR
Kodumuzun ilk satırında projeye işlemcimizin bilgilerinin bulunduğu kütüphaneyi dahil ediyoruz. Daha sonra üçüncü satırdaki komut ile bundan sonra yazacağımız kodların flash bellekte 0f800h adresinden itibaren saklanacağını belirtiyoruz. Dört ve beşinci satırı şimdilik atlıyorum ancak dördüncü satırdaki “reset” etiketine dikkat etmemiz gerekiyor. Bu etiket programımızın başlangıç noktasını belirtmektedir. Yazının sonuna doğru neden önemli olduğuna geleceğim.
Ayarlama bölümünün son satırına geldiğimizde bis komutunu ve P1DIR kaydedicisini görüyoruz. Bu komutta P1 modülünün sıfırıncı pinini (P1.0) çıkış olarak tanımlıyoruz. Peki bunu nasıl yapıyoruz. Anlaşılması açısından komutu biraz daha açık yazalım.
bis.b #0000 0001b,&P1DIR \\ bis.b kaynak, hedef
Burada gördüğünüz gibi komutumuzun kaynak bölümünde (0000 0001b) ikili sayısı bulunmaktadır. bis komutu ile kaynakta bulunan verideki “1” değerli bitler, hedef adresinde de (ki burada hedef P1DIR) “1” yapılmaktadır. Ancak kaynaktaki “0” olan bitler hedefte herhangi bir değişiklik yapmamaktadır. Yani bu komutun sonucunda P1DIR kaydedicisi içerisindeki veri (xxxx xxx1) olmaktadır. (x: değişiklik yok)
Eğer P1 modülünün ikinci ve dördüncü pinlerini çıkış olarak tanımlamak isteseydik. Kaynak bölümüne (0001 0100b) ikili sayısını veya (14h) hexadecimal sayısını yazmamız gerekecekti.
Yukarıdaki kodlarda “#” ve “&” işaretlerinin dikkatinizi çektiğini düşünüyorum. Bu işaretler sonrasında yazılan şeyin bir sayı mı yoksa bir adres mi olduğunu belirtmek için kullanılmaktadır. Sayıları belirtmek için “#” işaretini, adresleri belirtmek için ise “&” işaretini kullanıyoruz. Pek çok komut gibi bis komutu da kaynak olarak bir sayı veya adres alabilir ancak hedef olarak sadece bir adres almaktadır. (şimdilik neden olmadığı konusuna kafa karıştıracağından dolayı girmiyorum ama nedenini düşünerek bulabilirsiniz bence)
2. Ana Program Bölümü
Bu bölümde programımızın hedeflediği işi yapan kodlar bulunmaktadır. Bizim programımız için LED yakıp söndürme işlemini yapan kodlar aşağıda yer almaktadır.
loop xor.b #01h,&P1OUT // (01h) = (0000 0001b)
call #wait
jmp loop
Bu kodları incelediğimizde ilk olarak P1OUT kaydedicisi (01h) sayısı ile XOR işlemine sokulmaktadır. Bildiğiniz gibi bir sayının “0” ile XOR’u kendisine, “1” ile XOR’u ise tersine eşittir. O halde bu komutun sonunda P1OUT kaydedicisinin içerisindeki veri (xxxx xxxx’) olacaktır. (x: değişiklik yok, x’: önceki durumun tersi) Yukarıda açıklandığı gibi P1OUT kaydedicisi çıkış olarak tanımlanmış pinlerin durumunu belirlediğinden dolayı bu komut her çalıştırıldığında P1.0 pinine bağlı LED’ın durumunun tersi alınmakta yani yanıyorsa söndürülmekte, sönüyorsa yakılmaktadır.
Sonraki satırda ise call komutu ile “wait” isimli bir alt program çağrılmaktadır. Bu programın içeriğine bir sonraki bölümde geleceğiz.
Son olarak ise jmp komutu ile “loop” etiketine zıplama yapılmakta yani ana programdaki işlemler tekrarlanmaktadır. Burada LED’in sürekli yanıp sönmesi için sonsuz bir döngü oluşturulmuştur.
3. Alt Program ve Kesme Programları Bölümü
Bu bölümde farklı amaçlarla kullanabileceğimiz alt programlar ve kesme programları yazabiliriz. Bu bölümün tüm programlarda olmasına gerek yoktur ancak programın kullanışlı olması ve okunabilirliği açısından alt programların kullanımı faydalıdır. Programımızda kullandığımız LED’ın belirli bir süre yanık veya sönük kalmasını sağlayan bekleme alt programı aşağıda yer almaktadır.
wait mov #050000,R4
l1 dec R4
jnz l1
ret
Bu alt programda kabaca yaptığımız işlemi anlatacak olursak. Öncelikle bir kaydedicinin içine büyük bir sayı atıyoruz. Daha sonra dec komutu ile R4’ün içerisindeki sayı bir azaltıyoruz. Bu azaltma işleminin sonucu sıfır değil ise jnz komutu “l1” etiketine zıplamamızı sağlar, sıfır olduğunda ise zıplama yapmayarak alt satırdaki ret komutuna geçer. Son olarak ret komut ile alt programdan ana programa geri dönüş yapılmış olur. Alt program içerisinde yapılan bu azaltma işlemi belirli bir zaman geçmesine neden olmakta ki bu da bizim istediğimiz bekleme işlemini sağlamaktadır. Bu beklemenin ne kadar zaman aldığına daha sonraki yazılarda değineceğiz.
4. Kesme Vektör Tablosu Bölümü
Bu bölümü kesmelerle ilgili olan yazımızda çok detaylı olarak anlatacağım. Şimdilik sadece programımızın bazı özel durumlarda nasıl çalışması gerektiğini tanımladığımız bölüm olarak bilmeniz yeterlidir. LED programımız için yazmamız gereken kodlar aşağıda yer almaktadır.
org 0fffeh
dw reset
end
Burada yazılan kodlar ile işlemciye “reset” etiketinin programın başlangıcı olduğunu söylüyoruz. Eğer bunu yapmasaydık işlemci kodun nereden başladığını bilmediği için programımız çalışmayacaktı. Neyse ki bunu size söyleyen bir kişi var. Ben saatlerce bu program neden çalışmıyor diye saçlarımı yolmuştum. 🙂 Böylelikle LED yakıp söndürme programını tamamlamış olduk. Tavsiyem bütün kodları kendiniz yazmanız olacaktır. Çünkü bu size hem yazma alışkanlığı kazandıracak hem de komutların kullanımı aklınızda yer edinecektir.
Evet arkadaşlar uzun bir yazı oldu. Buraya kadar sıkılmadan okuduysanız ya gerçekten öğrenme isteğiniz vardır yada sınavlara 1 hafta kalmıştır. 🙂 Umarım ilk seçenek doğrudur. O zaman sonraki yazılarda görüşene dek kendinize iyi bakın efendim.
Hocam bu kısımda launcpadimizin P1.0 pinine ve gnd bağlantısına ledi bağladığımız zaman yanması gerekiyor değil mi?
Merhaba Yunus Emre, evet bu program P1.0 pinini belirli aralıklarla açıp kapatıyor. Launchpad in üzerindeki LED bu pine bağlı yani ayrıca dışarıdan LED bağlamana gerek yok ama paşka bir pine LED bağlayarak yakıp söndürmek istiyorsan dediğin gibi o pinle toprak arasına bağlantı yapmalısın ama LED yanmaması için seri birde direnç kullanman gerekir. 220 veya 330 ohm yeterli olacaktır.
Kodun çalıştırılması hakkında bilgi vermemişsiniz Hocam . Kodu yazıyorum ama nasıl entegreye aktarıp çalıştıracağımı bilmiyorum hata alıyorum.
Merhaba Okan, kodu işlemci üzerinde çalıştırmak için gerekli adımları bir önceki “IAR Kurulumu” yazısında anlatmıştım. Oraya bakabilirsin.
http://www.mehmetalikucuk.com/dersler/msp430-dersleri-2-iar-kurulumu/
Hocam cihaz bağlı değil hatası alıyorum ve ayrıca
– Tue May 18, 2021 20:25:49: Fatal error: Failed to re-initialize Session aborted!
bu hatayı alıyorum . download and debug butonuna tıkladığım zaman oluyor bunlar . Yardımcı olursanız sevinirim.
Öncelikle bilgisayarın işlemciyi tanıdığından emin olmalısın. Bunu aygın yöneticisine girerek kontrol edebilirsin. Sonrasında kodda bir hata olup olmadığını kontrol etmek için önce işlemci üzerinde çalışmak yerine simülasyon yapabilirsin. Şuan bilgisayarımda IAR yüklü olmadığı için bu ayarın tam nerede olduğunu söyleyemem ama “Debugger” ayarlarından yapılıyordu yanılmıyorsam. Simülasyon yaparken hata almıyorsan sorun bağlantıda diyebiliriz. Farklı USB portuna bağlamayı deneyebilirsin. USB 2.0 portlarına bağlamayı dene bazen 3.0 da böyle sorunlar yaşanabiliyor. Bunların dışında aklıma bir çözüm gelmiyor maalesef.
Hocam maalesef pc iar da ki kodları çalıştırmıyor hata oluyor . Code Composer de çalıştırabilir miyim bu kodları . Diğer derslerde ki kodlarda felan sıkıntı yaratır mı Code Composer ?
CCS’de bir defa deneme yapmıştım. Komutları aynı şekilde kullanabilirsin, ancak interrupt vektör tablosu biraz farklı bir şekilde oluşturuluyordu yanılmıyorsam.