MSP430 Launchpad – 7 Segment Display Uygulaması

Bu yazımda, launchpad ile, 7 segment display üzerinde sayı gösterme olayına değineceğim. Aslında devre de kod da kötü. Ancak başlangıç seviyesi için bu halinin, konunun daha anlaşılabilir olmasını sağlayacağını düşünüyorum.

Önce 7 segment display nedir, nasıl çalışır bundan bahsedeyim. 7 segment display, aslında 8 LEDden oluşmuş bir elemandır diyebiliriz. Üzerinde sayıları ya da karakterleri göstermek için 7 parça, bir de sağ alt tarafındaki nokta için olmak üzere toplam 8 LED.

Elemanın 10 tane bacağı bulunuyor. Bunlardan iki tanesi ortak (anot ya da katot), geri kalan 8 tanesi de her bir LED için ayrılmış bacaklar. Bu elemanlar ortak anotlu ve ortak katotlu olmak üzere ikiye ayrılıyor. Ortak anotlu olanda, tüm ledlerin anot (+) uçları birleşik. Bu durumda bu birleşik düğümden pozitif (yeterli seviyede) bir gerilim uygularsanız, ve yakmak istediğiniz led için ayrılmış diğer bacağı toprağa (ya da ledin yanması için üzerine düşmesi gereken gerilim dikkate alınarak daha düşük bir gerilim seviyesine) bağlarsanız, display üzerindeki o segment yanacaktır.

Bu displayleri sürmek için entegreler piyasada satılmakta. (Örn : 7447) Bu entegrelere giriş olarak displayde göstermek istediğiniz sayıyı binary olarak verdiğinizde, çıkışta gerekli pinleri aktifleştiriyor. Böylece display üzerinde istediğiniz sayıyı görebiliyorsunuz. Ayrıca displayin pinlerinin önüne birer küçük direnç bağlamakta fayda var. Bağlamazsanız LED’ler kullanılamaz hale gelebilir.

Ben uygulamada ortak anotlu bir display kullandım. Herhangi bir sürücü entegre kullanmadım. MSP430’un bacakları direkt olarak displaye bağlanmakta. Pin dizilimimi ise şöyle yaptım; sadece PORT1’i kullandım. P1.0 pinini ortak anot olarak belirleyip sürekli lojik 1’de tuttum. Diğer pinleri de P1.1 => A, P1.2 => B, P1.3 => C olacak şekilde toplam 8 pin kullanmış oldum. (1 pin ortak anot, 7 pin segmentler olmak üzere – sağ alttaki noktayı kullanmayacağım için ona hiçbir bağlantı yapmadım.)

Gelelim pinlerin değerlerini belirlemeye. Ortak anot olduğu için, ortak olan ucum sürekli “1”. Diğer pinler için de, yakmak istediğim segmente karşılık gelen pini “0”a çekersem, o segmenti yakmış olurum. Bu durumda P1.7, yani G segmentine karşılık gelen bit en solda, P1.0 da en sağda olacak şekilde pinlerin durumlarını yazacak olursak;

0  =>  10000001   =>   0x81
1   =>   11110011   =>   0xF3
2   =>   01001001   =>   0x49

şeklinde, yakacağımız bitlere “0”, en sağdaki bite “1”, geri kalanlara da “1” yazarsak hangi sayıyı göstermek için nasıl bir çıkış vermemiz gerektiğini buluruz. Yanlarındakiler de, bu binary gösterime karşılık gelen hexadecimal değer. Porta çıkış uygularken, bu hexadecimal değeri kullanacağız.

Ben şöyle bir devre kurdum. Dirençler 470 ohm değerinde.

Kodu da paylaşalım, assembly dilinde yazıldı.

#include "msp430.h"                     ; #define controlled include file

        NAME    main                    ; module name

        PUBLIC  main                    ; make the main label vissible
                                        ; outside this module
        ORG     0FFFEh
        DC16    init                    ; set reset vector to 'init' label

        RSEG    CSTACK                  ; pre-declaration of segment
        RSEG    CODE                    ; place program in 'CODE' segment

init:   MOV     #SFE(CSTACK), SP        ; set up stack

main:   NOP                             ; main program
        MOV.W   #WDTPW+WDTHOLD,&WDTCTL  ; Stop watchdog timer

        MOV.B   #0xFF, &P1DIR           ; P1 portu çıkış olarak seçildi.

basla:  MOV.B   #0x81, &P1OUT           ; 0 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0xF3, &P1OUT           ; 1 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0x49, &P1OUT           ; 2 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0x61, &P1OUT           ; 3 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0x33, &P1OUT           ; 4 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0x25, &P1OUT           ; 5 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0x05, &P1OUT           ; 6 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0xF1, &P1OUT           ; 7 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0x01, &P1OUT           ; 8 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        MOV.B   #0x21, &P1OUT           ; 9 basıldı.
        CALL #bekle                     ; Bir süre beklendi.

        JMP basla                       ; Başa dön.

        ; bekleme alt programı : 

bekle:  MOV.W   #0xFFFF, R5             ; R5 registerına FFFF değeri atandı.
azalt:  DEC     R5                      ; R5 değeri bir azaltıldı.
        JNZ     azalt                   ; 0 olana kadar azaltmaya devam et.
        MOV.W   #0xFFFF, R5             ; R5 registerına tekrar FFFF değeri atandı.
azalt2: DEC     R5                      ; R5 değeri bir azaltıldı.
        JNZ     azalt2                  ; 0 olana kadar azaltmaya devam et.
        RET

        END                             ; (endless loop)

Kod oldukça basit. Önce P1 portunu çıkış olarak koşullandırıyorum. Daha sonra sırasıyla P1OUT registerına, yukarıda her sayı için hesapladığım değerleri bastırıyorum. “bekle” altprogramıyla da sayılar arasına bir gecikme koyuyorum. 9’a kadar saydığında, tekrardan başa dönerek 0’dan saymaya başlıyor.

“bekle” altprogramında ise, gecikme oluşturması için R5 registerına 0xFFFF değerini yüklüyorum, ve bu değer 0’a ulaşana kadar birer azaltıyorum. Böylece işlemci bu azaltma işlemini yaparken benim istediğim gecikme elde edilmiş oluyor. Daha uzun süreli bir gecikme için aynı işlemi iki kere yaptım. Bu, daha değişik yollarla da yapılabilir.

Ekleme (01 / 06 / 2011)

Önceki yazılarımı incelerken, bu yazıda devre şemasını paylaşmadığımı farkettim. Ayrıca elimde bu devre için yazılmış C kodu da var, onu da ekliyorum. Bir de bu devreyi burada paylaştıktan sonra, tek display için ortak anot ucu olarak bir i/o pinini kullanmanın çok acemice olduğunu öğrendim. Tek display kullanılacaksa ortak anot ucunun direkt Vcc’ye çekilmesi daha mantıklı ve doğru bir hareket olacaktır. Ancak aşağıda paylaşacağım devre şeması ve C kodu, yazının orijinalinde bahsedilen devredir, yani ortak anot ucu P1.0’a bağlıdır. Denemelerinizde bunu dikkate alın.

Devre şeması

Devre şeması

C kodu :

#include "io430.h"

void kucuktenBuyuge(void); // Küçükten büyüğe sayar.
void buyuktenKucuge(void); // Büyükten küçüğe sayar.
void sayiGoster(int); // O anki sayıyı displayde gösterir.
void bekle(void); // Sayılar arası bekleme.

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  P1DIR = 0xFF; // P1 çıkış olarak ayarlandı.
  P1OUT = 0x81; // 0 sayısı displaye basıldı.

  while(1) // Sonsuz döngü.
  {
    kucuktenBuyuge(); // Fonksiyonlar çağrılıyor.
    buyuktenKucuge();
  }
}

void kucuktenBuyuge(void)
{
  int i;
  for (i = 0 ; i < 9 ; i++) // 0'dan 9'a kadar sayar.
  {      
    sayiGoster(i); // O anki sayıyı basması için fonksiyonu çağırır.
    bekle(); // Bir süre bekle.   
  }    
} 

void buyuktenKucuge(void) 
{      
  int i;      
  for (i = 9 ; i > 0 ; i--) // 9'dan 0'a kadar sayar.
  {
    sayiGoster(i); // Sayının basılması için fonksiyon çağırır.
    bekle(); // Bir süre bekle.
  }
}

void sayiGoster(int sayi)
{
  switch(sayi) // Gelen sayı kaç?
  {
    case 0 : P1OUT = 0x81; break; // Sayı 0 ise ilgili pinler ayarlanır.
    case 1 : P1OUT = 0xF3; break; // 1
    case 2 : P1OUT = 0x49; break; // 2
    case 3 : P1OUT = 0x61; break; // 3
    case 4 : P1OUT = 0x33; break; // 4
    case 5 : P1OUT = 0x25; break; // 5
    case 6 : P1OUT = 0x05; break; // 6
    case 7 : P1OUT = 0xF1; break; // 7
    case 8 : P1OUT = 0x01; break; // 8
    case 9 : P1OUT = 0x21; break; // 9
    default : P1OUT = 0x0D; break; // Hata oluştu, displayde 'E' harfini göster.
  }
}

void bekle(void)
{
  long int delay;
  for(delay = 0 ; delay < 100000 ; delay++); // Hiçbir işlem yapmadan bekle.
}

Kod yine basit, kucuktenBuyuge ve buyuktenKucuge fonksiyonlarında değişen sayı, sayiGoster fonksiyonuna gönderiliyor. Burada bir switch – case ile P1OUT registerı doğru şekilde ayarlanıyor. Daha sonra bir süre bekleyip diğer sayıya geçiliyor.

Ekleme sonu

Bu da, ilk denememde çektiğim, devrenin çalışırkenki videosu. Bu arada youtube’a google hesabımla giriş yaptım, “g88888888g” diye bir kullanıcı adı vermiş, ilginç 🙂

Share
  1. MSP430 Launchpad – İki Display Sürme | Berk Baykal - pingback on 08 Nisan 2011 at 21:04
  2. güzel anlatmışssın,devamını beklıyoruz

  3. Pinleri lehimlerken içinden çıkan male header veya
    female header kullanmak zorundamıyız.Ayrıca lehimlerken direk p1.6 p1.7 gibi pinleri kullanabilirmiyiz

    • Headerları kullanırsanız, launchpadden dışarıya bağlantıları daha kolay bir şekilde yaparsınız. Onun dışında kullanmak zorunda değilsiniz. Headerları kırarak istediğiniz boyuta getirirseniz, sadece istediğiniz çıkışlara da lehimleyebilirsiniz.

  4. teşekkür ederim yardımınız için ben kullanmıcam 😛 .Çok teredütte kalmıştım

  5. ben bu işlerde yeniyim:) ben internetten sipariş verdim aldığım devrede entegre kullanılmış sizin yaptığınızda yok bi şey fark edermi..

    • İnternetten hangi devreyi satın aldınız? Launchpad aldıysanız zaten kutudan çıkanlar standart. Entegreden kastınız hangi entegre? MSP430 ise videodaki launcpadde pek gözükmese de bir tane takılı var zaten.

  6. sizden acaba msp430 7 seg uygulamasını alabilirmiyim mümkünse tüm dosyalarını

  7. berk bey çok teşekkür ederim yanlız sizden çok özür dileyerek bi sorum daha olucak ben bu devreyi akşma bord ta kurdum yani sadece dirençleri dislpaye bağladım sonrada dirençlerin çıkışına msp 430 bağladım fakat hiç bir hareket hatta devreye enerji dahi gelmedi sizden özel isteğim var ben bu devreyi yarına vermem gerek ödevim benm buu bana rica etsem bord üzerinden nasıl takıcam yapacakarmı sölerseniz anlatırsanız size minnet kalırım çünkü ben buişlerde biraz yeni yani hiç bord kullanmadım desem yalan olmaz ama az çok bilgim var tabi fakat nasıl bağlıcamı bilmyorum ve ben bunu baskı devre yapıp vermem lazım çalışr vaziyette sizden ricam önemlizamanınızdan bana bi 10 dknızı ayırırısanız memnun olurum sayglarımla

    • bu arada bende düzce üniversite 2 ci sınıf öğrencsiyim end.elektronik tek.

    • Merhaba, su an yoldayim ve 4-5 gun boyunca yanimda hicbir elektronik malzeme olmayacak. Bu yuzden board yerlesimini gosteremeyecegim. Ancak internette ufak bir arastirmayla boardi nasil kullanacaginizi ogrenebilirsiniz. Kodu paylastigim yazida hangi pinleri nereye baglamaniz gerektigi yaziyor. Displayin pinlerinin de hangileri oldugu mevcut. Oraya bakarak baglantiyi dogru bir sekilde yaptiginizda devre calisacaktir. Birkac kucuk hatirlatma yapayim: kod ortak anot displaye gore yazildi. Ortak katot kullanirsaniz calismaz. Bir de displayi mutlaka direncle surun. Direnc kullanmadiysaniz display bozulmus olabilir. Bir de direnclerinizin degeri kucuk olsun. 220 330 ohm gibi. Kolay gelsin…

  8. Merhaba, ben de 7segment ile bir digital clock yapmak istiyorum.Bu konuda bana yardımcı olurmusun?Devre şeması ve nasıl board üzerine bağlanacağı konusunda herhangi bir fikrim yok.MSP430 kullanıyorum bu arada.Teşekkürler

    • Eğer benim gibi 10 i/o pini bulunan bir denetleyici kullanıyorsanız (ki sanıyorum öyle), direkt olarak bağlantı için pin sayınız yetmeyecektir. Burada iki önerim olabilir size. Ortak katot display kullanıyorsanız, displayleri aktif etme işini 74139 gibi bir decoder ile yapabilirsiniz. Bu yöntem için devre şemanız yaklaşık olarak şu linkteki gibi olmalıdır. http://www.berkbaykal.com/upload/dortDisplay.PDF
      Ya da bir BCD to 7 segment dönüştürücü kullanabilirsiniz. Bu, dönüştürücüye girdiğiniz binary sayıya göre displayin uçlarını otomatik olarak “1”e ya da “0” a çekecektir. Oldukça pratik. Ortak anot display için 7447, ortak katot için 7448 entegreleri bu işe yarıyor. Detaylı bilgi için yazdığım entegrelerin datasheetlerine bakabilirsiniz.
      Daha da iyi bir şey için yukarıda yazdığım iki yöntemi birleştirip toplam 6 pin ile dört adet displayi sürebilirsiniz. Kolay gelsin…

    • Yardımın için teşekkür ediyorum öncelikle,aklıma takılan bir soru daha var.Bu binary sayıları saat sistemi olduğu için nasıl bir uygulamayla aldırabilirim?Bana önerebileceğin bir c kodu bulabilirmiyim

    • Yani display üzerinde istediğiniz herhangi bir sayıyı bastırır gibi bastıracaksınız, bir fark yok. Kullanacağınız BCD to 7 segment entegresinin datasheetini incelerseniz istediğiniz sonuç için nasıl giriş vermeniz gerektiğini göreceksiniz.
      Hazır bu işi yapan C kodları internette mevcuttur diye düşünüyorum. Ancak benim yollamış olduğum devre şemasına göre devreyi kurup, başka yerden aldığınız kodu kullanırsanız sonuç alamayabilirsiniz. Size önerim kurmuş olduğunuz devreye uygun kodu kendiniz yazmanız. Ama hazır kullanacağım derseniz de, kodu aldığınız yerde devresi mutlaka vardır. O devreyi kullanmanız gerekir. MSP430 için de bu saat örneğinin olacağını düşünüyorum, ama yoksa bile PIC ile yapılmış örnek mutlaka bulursunuz. Onu biraz değiştirerek MSP430’a uygun hale getirebilirsiniz. Kolay gelsin…

  9. Merhaba,
    Tutorial icin cok tesekkurler. Bir sorum olacak, Kullandiginiz seven segment display in Forward Voltage degeri nedir? Bendekinin maximum Forward VOltage degeri 2 V, ve msp430 launchpad de bu parcayi kullanirken direnc kullanmam gerekir mi onu merak ediyorum.
    Tesekkurler

    • Merhaba,
      Maximum forward voltage değerini bilmiyorum ama MSP430 kullandığım için o anki forward voltage değerinin 3.5V civarı olduğunu düşünüyorum. Her segmentin önüne ufak dirençler koyarsanız olası sıkıntıları önlemiş olursunuz.
      Kolay gelsin…

  10. slm msp430 la ilgili genel açıklamaların bulunduğu türkçe bir site önerebilirmisiniz bu işlere yeni girdim ama tam olarak bilmiyorum yardımcı olursanız sevinirim saygılar

    • Merhaba,

      mcu-turkey.com ve fatihinanc.com yardımcı olacaktır. Ancak Türkçe ile sınırlandırmazsanız kendinizi google’dan çok güzel kaynaklar bulabilirsiniz. Ayrıca TI’ın örnek kodları da gayet yardımcı oluyor.

  11. MSP430g2231 de bu kodlar çalışırmı

  12. öncelikle tutorial için teşekkür ederim . benim bir sorum olucak . 7 segment displayde kayan yazı yapmak için nasıl bir algoritma tasarlamalıyım .

    • Merhaba,
      Bence önce displaylerde her istediğiniz şeyi yazdırabildiğiniz bir fonksiyonunuz olmalı. Bir de kaydırma fonksiyonu yazmalısınız. Bu fonksiyon içinde metni birer karakter kaydırarak şu her şeyi yazdırabildiğiniz fonksiyona gönderirseniz istediğinizi başarmış olursunuz.
      Kolay gelsin…

  13. Merhabalar, bu projeyı yapmak istiyoruz fakat çok çok acemi olduğumuzdan bağlantıyı nasıl yapabileceğimizi bilmiyoruz. Kablo bağlantılarını daha açık bir şekilde gösterebilmenız yada anlatmanız mümkün mü acaba?

Yorum Yap


Not - Bunları KullanabilirsinizHTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Geri İzleme: