MSP430 ile GPIO uygulamaları
|Merhabalar..
Bu konuda önceki konunun devamı olarak MSP430 ile GPIO uygulamalarına değineceğiz. Örnek olarak basit led uygulamaları(karaşimşek, binary sayıcı vb), buton ile led kontrolü, buton interruptları gibi örneklere yer vereceğiz.
İlk örneğe geçmeden önce bazı ayrıntılara değinelim. Öncelikle MSP430 pinleri en falza 10 mA çıkış verebilmektedir (Datasheet’ te 6 mA standarttır). Bu yüzden herhangi bir led bağlantısı için mutlaka direnç kullanmanız gerekir. Aksi taktirde o portu yada portun o pinini kullanım dışı bırakabilirsiniz.
İkinci olarak pin yapılarına biraz değinelim. Konumuz GPIO’ lar olduğu için bu konu son derece önemli. Örneğin benim örnekleri vereceğim MSP430 modelinde 6 numaralı porta kadar kullanılabilirken, MSP430G2 serisinde port numaraları en fazla 2 ye kadar gitmektedir. Yani siz aşağıdaki örnekleri denerken kendi MSP çeşidiniz port yapısına göre denemenizi yapmalısınız.
Son olarak önceki konuda MSP430 ile RAM bölgesinde örnekler vermiştik (BURADAN ulaşabilirsiniz). Önceki uygulamalar IAR üzerinden yapılmıştı. Lakin bu konuda örnekleri CCS üzerinden gerçekleştireceğim. Bunun sebebine gelince IAR ile GPIO işlemlerini yapmaya kalktığınız zaman kodunuz tam doğru olsa bile çözümü olmayan bazı sorunlar yaşayabiliyorsunuz. Bu yüzden benim tavsiyem uygulamanız sadece RAM bölgesi üzerinde değilse IAR’ ı değil CCS’ i kullanmanız. Ancak seçim size kalmış. Ben iki ideyi de kullanabilin diye aralarındaki farklı kullanımları yeri geldikçe belirteceğim.
Şimdi ilk uygulamamıza geçebiliriz. Her zaman olduğu gibi ilk olarak MSP430 üzerindeki dahili bir ledi belli aralıklarla yakıp söndürme işlemi yapalım. Aşağıdaki resimlerde benim kullandığım MSP430F5529 ve piyasada sıklıkla kullanılan model olan MSP430G2253(1)’ in pin yapıları görünmekte
MSP430F5529 üzerinde resimdede görüldüğü üzere iki dahili led bulunmakta. Biz bu uygulamada P1 portunun 0 nolu pinine yani P1.0′ a bağlı ledi belli aralıklarla yakıp söndürelim. MSP430G2 serisinde de sanırım bu led aynı pine bağlı. Bu sebeple de yazılımda değişiklik yapmadan kullanabilirsiniz.
Led yakıp söndürmek istiyoruz. Led’ in bağlı olduğu pinden gerilim almak bir çıkış işlemidir. Biz denetleyiciden çıkış almak istiyorsak o pini ilk olarak o pini çıkış olarak yönlendirmemiz gerekir. Bunun için şu şekilde bir işlem yeterlidir.
bis.b #0x01, &PADIR ;ledi çıkış olarak yönlendirdik
Burda “bis” komutu user guide’ dan bakabileceğiniz gibi basit olarak bit set leme işlemi gerçekleştirir. PADIR ise port yönlendirme registeridir. Bu register üzerinden portun o pinine karşılık gelen pin 0 ise giriş 1 ise çıkış olarak yönlendirilir.
outer xor.b #01h, &PAOUT ;portu 01 ile xor ladık
Bu kodlarda ise outer etiketinin olduğu yerde PA portunun değerini 0000 0001 değeri ile xor işlemine soktuk. Böylece birince pine bağlı olan led yanıyorsa söndü, sönmüşse yandı.
mov.w #0xFFFF, r5 inner dec.w r5 tst.w r5 jne inner jmp outer ;outer etiketine atladık
Bu kısımda ise ledin yanıp sönme arasındaki gecikmeyi oluşturduk. Yani led yandıktan sonra denetleyici belli bir süre beklesin sonra ledi söndürsün. Yada bu işlem tam tersi şekilde gerçekleşsin. Bunu sağlamak için bir registere FFFF değeri atayıp birer birer azalttık. Bu değeri seçtik çünkü denetleyicimizdeki registerlerimiz 16 bit ve 16 bitlik en büyük sayının değeri FFFF‘ dir. Bu sayede bir register üzerinden verilebilecek en büyük gecikmeyi vermiş olduk.
En alttaki jmp komutu ile de sonsuz döngüyü oluşturduk ve yazılımın başına geri döndük.
MSP430 ile Assembly’ de led blink uygulaması bu şekilde. Yazılımın tamamına buradan ulaşabilirsiniz. Şimdi gelelim butondan giriş alarak led yakıp söndürme uygulamasına. Bu uygulamada MSP430 üzerindeki led’ lerden biri belli aralıklarla yanıp sönerken butona bastığımızda diğer led’ i yanıyorsa söndürecek, sönmüşse yakacağız. Böylece interrupt’ un ana programa etkisini tam olarak gözlemlemiş olacağız.
Yeri gelmişken interrupt’ tan bahsedelim. Interrupt’ lar adından da anlaşılacağı gibi ana programın işleyişini kesen yapılardır. Bu sayede siz ana programda bir iş gerçekleşirken bir interrupt gelmesi durmunda denetleyicinize o an ki işini bırakıp interrupt gerçekleşince yapılması gereken işlemi yapmasını sağlayabilirsiniz. Peki bunu nasıl ayarlıyacağız? Elbet registerler üzerinden ayar yaparak. Şimdi bu registerleri tanıyalım.
Registerlere geçmeden interrupt’ ı kullanmak istediğimiz pin için bazı ayarlar yapmamız gerekeli. Bu ayarlar o pinin giriş olarak kullanılabilmesi için gereklidir.
bic.b #02h, &P2DIR ;P2.1 butonu giriþ olarak yönlendirildi bis.b #02h, &P2OUT ;P2.1 giriþ Pull Up voltajý verildi bis.b #02h, &P2REN ;P2.1 giriþ Pull Up direnci aktif edildi
P2IE register’ i P2 portu için Interrupt Enable registeri’ dir. 8 bitliktir. Her bit bir pini temsil eder. Registerde bitin karşılığındaki değer 1 ise o pin için interrupt aktif edilmiş demektir.
bis.b #02h, &P2IE ;P2.1 interrupt u atif edildi
eint ;Tüm interruptları aktif ettik
“eint”, general interrupt enable komutudur. Bu komut ile bir üstte yaptığımız Interrupt Enable işleminin geçerli olmasını sağlıyoruz. Eğer bu komutu kullanmazsak interrupt çalışmayacaktır.
Daha sonra interrupt’ in işaretin hangi kenarında tetikleneceğine karar vermeye geldi.
Biz MSP430′ da bulunan dahili butonu kullanmaya çalıştığımız için interrupt’ u düşen kenar olarak ayarlamalıyız. Çünkü buton normalde Vcc’ ye bağlı ve biz butona bastığımızda girişimiz toprak gerilimi seviyisine düşüyor. P2 portu için bu ayarı yapmak istiyorsak P2IES registerini setlemeliyiz. Eğer bu register’ de pinin karşılığı olan biti 1 setlersek düşen kenar olarak setlemiş oluruz.
bis.b #02h, &P2IES ;P2.1 için interrupt düþen kenar olarak ayarlandý
Şimdi sıra geldi interrupt geldiğince setlenecek bayrağa. İnterrupt geldiğinde eğer ayarlar doğru şekilde yapılmışsa P1 portu için P1IFG registerinde ilgili pin setlenir. Daha sonra MSP430 yazılımda interrupt geldiğinde yapılacak işlemlerin olduğu kısma geçip işlemlerini yapmaya başlıyacaktır. Burda dikkat edilmesi gereken işiniz bittiğinde bu registeri temizlemelisiniz. Aksi taktirde ana yazılım asla interrupt’ tan çıkamaz.
Şimdi gelelim CCS’i IAR’ dan ayıran bir diğer kısma. Interrupt vektörünü ayarlarken IAR’ da registeri ve etiket adresi girmeniz yeterlidir. Lakin CCS’ de interrupt vektör adresini temsil eden bazı string ifadeler vardır ve onları kullanmalısınız. Port 2 için bu ayar şu şekildedir.
.sect ".int42" ;port 2 interrupt vectörü .short P2_ISR
Eğer IAR ı kullanıyorsanız bu ayar şu şekilde olmalıdır:
ORG 0FFD4h ;P2 portu interrupt vectoru DW P2_ISR ;Interrupt etiketi
Eğer MSP430G2231 kullanıyorsanız, IAR’ da Interrupt ayarını bu şekilde yapmalısınız:
ORG 0FFE6h ;P2 portu interrupt vectoru DW P2_ISR ;Interrupt etiketi
Şimdide interrupt geldiğinde yapılmasını istediğimiz işlemleri ayarlayalım.
P2_ISR ;TOGGLE LED ;------------------------------------------------------------------------------- xor.b #080h, &P4OUT bic.b #02h, &P2IFG reti
Artık uygulamamız hazır MSP’ ye yükleyip denemelerimizi yapabiliriz. Buradan yazılım tamamına ulaşabiliriz.
Son olarak led counter uygulaması ile konuyu sonlandıralım. led counter’ ımızı butona bastıkça artacak veya azalacak şekilde ayarlayalım. Yani her butona basmamızda sayacın değeri bir artacak ve ledler değişecek. Diğer butana bastığımızda ise sayacın değeri azalacak. Bu uygulama için dışardan led bağlantısı yapacağız. Led leri pinlere bağlarken direnç kullanmayı unutmayın. Aksi taktirde üzücü sonuçlar alabilirsiniz. Bunu dışında bu uygulama için kullanacağımız 4 ledi herhangi bir pine bağlarsanız arttırma işleminde zorluk çekersiniz. Ledleri mutlaka herhangi portun 0. pininden başlayarak 1, 2 ve 3. pinlerine bağlamalıyız. Yani bağlantınız eğer MSP430G2231 kullnıyorsanız resimdeki gibi olmalıdır.
MSPF5529 için bağlantı şemasını Fritzing kütüphanesinde bulunmadığı için ekleyemedim. Lakin sadece pinleri P6 portunda 0′ dan 3 e kadar bağlamanız benim yazdığım uygulama için yeterli olacaktır. Butonlar MSPG2231 kullacaklar için farklı pinlere bağlanmıştır.
Öncelikle giriş çıkış konfigurasyon ayarlarımızı yaparak uygulamaya başlayabiliriz.
mov.b #0fh, &P6DIR ;P6 portunun ilk 4 bitini çıkış olarak atadık bic.b #02h, &P2DIR ;P2.1 i giriş olarak ayarlaryıp bis.b #02h, &P2IES ;interrupt' ı aktif ettik bis.b #02h, &P2IE bic.b #02h, &P2IFG bis.b #02h, &P2REN bis.b #02h, &P2OUT bic.b #02h, &P1DIR ;P1.1 portunu giriş olarak ayarlayıp bis.b #02h, &P1IE ;interrupt' ı aktif ettik bis.b #02h, &P1IES bic.b #02h, &P1IFG bis.b #02h, &P1REN bis.b #02h, &P1OUT nop eint ;genel interruptları aktif ettik
MSP430F5529′ da onboard butonlar P1.1 ve P2.1 pinlerine bağlı ancak üsttede belirttiğimiz gibi MPSG2231 de bu pinler yerine P1.3 ve P2.4 pinlerini kullanmalıyız. Eğer MSPG2231 kullanıyorsanız bu ayarlar şu şekilde olmaldır.
mov.b #0fh, &P2DIR ;P6 portunun ilk 4 bitini çıkış olarak atadık bic.b #016h, &P2DIR ;P2.1 i giriş olarak ayarlaryıp bis.b #016h, &P2IES ;interrupt' ı aktif ettik bis.b #016h, &P2IE bic.b #016h, &P2IFG bis.b #016h, &P2REN bis.b #016h, &P2OUT bic.b #08h, &P1DIR ;P1.1 portunu giriş olarak ayarlayıp bis.b #08h, &P1IE ;interrupt' ı aktif ettik bis.b #08h, &P1IES bic.b #08h, &P1IFG bis.b #08h, &P1REN bis.b #08h, &P1OUT nop eint ;genel interruptları aktif ettik
Burdan sonraki kısımlarda MSPG2231 kullanmak isteyen arkadaşlar değişikliği üstteki kısımlarda yaptığım gibi yapabilirler. Üzerinde ayrı ayrı durmayacağım.
Şimdi de ana döngüyü oluşturalım.
basla mov.b r6, &P6OUT ;r6 yı çıkışa atadık jmp basla
Burada P6 portuna sayaç olarak kullandığımız r6 registerindeki değeri yazdırdık. Böylece sayaç her arttığında led lerin durumu değişmiş oldu. Şimdide butona bastığımızda arttırma ve azaltma işlemini yapalım.
;------------------------------------------------------------------------------- ;Interrupt ;------------------------------------------------------------------------------- P2_ISR inc r6 ;P2.1 butonuna basılmışsa sayacı 1 arttır cmp #010h, r6 ;Eğer sayaç değeri 0f olmuşsa jnz m1 ;sayacı 0 yap mov #01h, r6 ;olmamışsa devam et m1 nop bic.b #02h, P2IFG reti ;------------------------------------------------------------------------------- ;Interrupt ;------------------------------------------------------------------------------- P1_ISR dec r6 ;P1.1 butonuna basılmışsa sayacı 1 azalt cmp #0h, r6 ;Eğer sayaç değeri 00 olmuşsa jnz m2 ;sayacı 0f yap mov #0fh, r6 ;olmamışsa devam et m2 nop bic.b #02h, P1IFG reti
Yorum satırlarında da belirttiğimiz gibi P2 portuna bağlı butona bastığımızda sayacın değerini bir arttırdır, P1 portuna bağlı butona bastığımızda ise sayacın değerini bir azalttık. Ekstra olarak sayaç değerinin 16 nın dışına çıkmaması (4 led var 2^4 = 16 adım yapar) için bir kontrol işlemi yaptık. Böylece sayaç değeri 16 yı geçmişse sayacı sıfırladık 0 ın altında düşmüşse 16 yaptık. Eğer MSPG2231 kullanıyorsanız bayrak temizleme işlemlerinde pini üstte belirttiğimiz şekilde P1.3 ve P2.4′ e göre yapmalısınız.
Son olarak Interrupt adreslerini belirlemeye geldi sıra. Eğer CSS IDE’ sini kullanıyorsanız ayarları bu şekilde yapmasınız.
.sect ".int42" ;port 2 interrup adresi .short P2_ISR ;port 2 interrup etiketi .sect ".int47" ;port 1 interrupt adresi .short P1_ISR ;port 1 interrup etiketi
IAR IDE’ sini kullanıyorsanız ayarları bu şekilde yapmalısınız.
ORG 0FFFEh ;P1 portu interrupt vektörü DCW P1_ISR ;P1 portu interrupt etiketi ORG 0FFE6h ;P2 portu interrupt vektörü DCW P2_ISR ;P1 portu interrupt etiketi
Yazılımın CCS ile MSP430F5529 için yazılmış olanına buradan ulaşabilirsiniz.
Bu konumuz da bu kadar. Konuların fazla ilgi çekmemesi sebebi ile devam bu şekilde devam etme konusunda kararsızım. Lakin devam edersem bir sonraki konu ADC ve Seri Haberleşme işlemleri olacaktır.
Herşeyi açık açık anlatmaya çalıştım, işinize yaraması dileklerimle..
İyi çalışmalar..