Elektronik Devreler Projeler Elektronik ve biraz daha fazlası İletişim - Araçlar - Dikkat - Topluluk
Elektronik / Elektronik Kaynakları/

MikroC Dersleri 9

Sponsorlu Bağlantılar

Merhaba elektronik Severler..

Bir önceki dersimizde programcılık deneyimlerimiz arasına kesme değimlerini ve ilk kesme uygulamamızı gerçekleştirdik.

Sanıyorum kesme olgusu geçen dersten kalan bilgilerimizle zihnimizde biraz olgunlaştı. Bu dersimizde yine kesme konusunu ele alacağız ve önceden bahsettiğimiz seri iletişim ile çalıştırabileceğimiz ve esnek kullanımı olan 74hc595 entegresini bu sefer pic ile sürecek bir yazılım gerçekleştirelim.

Bu dersimizde 16F628A PİC’i ile PORTB 4-7 kesmesini temele alarak işleyeceğim .Bu konudan sonra KESME konusunun en can alıcı kısmına yani TIMER kesmesini enine boyuna inceleyeceğiz.

Dersimize başlamadan önce işimize yarayabilecek kısa ip uçları vermek alışkanlık oldu.

  • Pic ile çevresel aygıt kontrolü pic pinlerindeki sinyali bir akım güçlendirme işlemine tabi tutularak yapılabilmektedir.
  • Pic çıkışlarının sinyal yükseltmesi transistörler aracılığı ile yada opamp entegreleri ile yükseltilmelidir.
  • En genel sinyal kuvvetlendirme NPN tipi taransistörler direk sürülerek yapılmaktadır.
  • Yüksek akım ve yüksek frekans gerektiren kontrol işlemlerinde düşük güç transistörleri yerine MOSFET kullanılmaktadır.
  • Genel olarak mosfetler gate yolu üzerine 1k ohm’luk diren üzerinden pic ile sürülür
  • Mosfetlerin sağlıklı ve verimli çalışması için gate terminalinden 100k ohm değerinde direnç şaseye çekilmelidir.
  • Bu sayede Mosfetlerin gate ucunun boşta bırakıldığında kararsız çalışması önlenmiş olur

yuk-mosfet-mikroc

Geçen dersimizde işlediğimiz kesmenin tabımına tekrar değinelim ki kesme olgusu aklımızda yer etsin.

KESME (İNTERRUT Programlanması)

Kesme Gerçek zamanlı denetleyici ve işlemcilerde büyük önem ve kolaylık taşımaktadır. Esasen kesme programlamak assembly dilinde deveye hendek atlatmaktan zor bir iştir.(tabi ki bu derslerden önce :D),Fakat MikroC derleyicisinin özel bir fonksiyonu bulunur ve kesme anında program bu fonksiyona yönlendirilir.

Bu yüzden oldukça kolay kullanımı vardır. Kes e fonksiyonu void interrupt() şeklinde başlar ve programda fonksiyon olarak çağırılamaz.Pic kesme gerçekleştiği anda fonksiyona kendiliğinden gider.

Peki genel hatlarıyla kesmeyi izah etmek gerekirse?

Kesme olgusunu günlük bir olayla bağlayıp anlatırsak evde dev akranda sinema film izliyorsunuz ve bir yandan mısır patlağı yiyorsunuz.

Ve her hangi bir andakapı zili çalıyor siz elinizdeki son mısırı yiyip filmi dondurup kapıya gidersiniz kapıda gelen kişiyi karşılarsınız konuşursunuz vs tekrar tv karşısında eski yerinizi alırsınız filmi kaldığı yerden başlatıp mısır yemeye devam edersiniz. Ve bütün bunlar bir anda gerçekleşir.

Burada gerçekleşen olayı kesme ile bağdaştıracak olursak sizin ilk başta film izleyip mısır yiyor olmanız işleyen pic programı kapının çalması KESME anı kapıya gidip orada birtakım işlemler yapmanız Kesme programı kapıdan dönüp geri geldiğinizde kalığınız yerden devam etmeniz kesme sonlanması.

Yani kesme gerçekleştiği anda PIC işlemekte olduğu Son komut satırını işler son komutun bulunduğu adres bilgisini stack register(kaydedici)

Kaydeder kesme gerçekleşti anlamına gelen kesme bayrağını kendiliğinden 1 yapar ve kesme programına gider kesme programı içerisinde olan komutları işler(burada işlemler çok uzun olmamalı ve mümkünse Delay (zamanlama) kullanılmamalıdır. Aksi taktirde pic normal programa geç döner) Sonrasında pic stack register e gider ve kesmeden önce yürütülen son program komutunun adresini alır ve o komut satırının bir sonrasına giderek programı kaldığı yerden devam ettirir. Biz kesme programının sonunda kendiliğinden 1 olan kesme bayrağını 0 yapmalıyız aksi taktirde bir daha kesme programına gidilmez.

RB 4 – 7 kesmesi

RBIE kesmesi int0 kesmesinde olduğu gibi pic yazılımına kullanıcının doğrudan müdahale etmesine olanak tanır Bir buton kontrolü aracılığı ile işleyen programda değişkenler veriler yada işlemler kontrol edilebilir. Bu kesmeyi kullanmak için B portunun4 ile 7 .bitleri arası kesinlikle giriş olarak tanımlanmalıdır ve pic donanımı arasında yer alan İNTCON register(İNTerruptCostimizasyON) yada (İNTerruptCONTROL) kesme ayarları program başlangıcında istenilen sistemin çalışmasına göre ayarlanmalıdır.

Bu kaydediciler aracılığı ile programda kesmeler aktif veya pasif edilir ve kesmenin gerçekleşme şartları ayarlanır. Bu kaydedicilerden İNTCON registere tekrardan değinelim

intcon-register-address-0bh-8bh-10bh-18bh-mikro-c

Buradaki kısaltmaların her biri bir anlam taşımaktadır. Bu registerin yapısını kullanacak olduğunuz PIC datasheet de bulabilirsiniz.

Bit 7: Bu bitin anlamı Global İnterrupt Enable kelimeleridir.Yani Evrensel Kesme aktif bitidir.

• 1 ise Kesmelere izin verilimiştirBütüm kesmelerde 1 yapılır
• 0 ise kesme programı kullanılmayacaktır.

Bit 6: Peripheral İnterruptEnable bitÇevresel kesmelere izin verme biti

Bit5: TMR0 Overflow Interrupt Enable bit . TMR0 sayacının başlangıca dönmesi sonucu kesme oluşturur.
• 1 ise TMR0 kesmesi aktif yapılır
• 0 olduğunda TMR0 zaman kesmesi kullanılmayacaktır

Bit4: İNTE RB0 Dış kaynak kesmesi

• 1 RB0 Aktif
• RB0 Pasif

Bit3: RBIE RB 4 7 Değişiklik kesmesi ( b Portunun 4 ve 7 portları (4 5 6 7 ) Giriş yapılmak zorundadır)

• 1 aktif 0 pasif Biz bu ders bu bitleri ayarlayacağız

Son 3 bit ise ilgili kesmelerin bayraklarıdır her hangibir bayrak 1 iken diğer kesmeler aktif bile olsa kesmeler çalışmaz o yüzden bayraklar kesme programı sonunda 0 yapılmalıdır.

RB0 int kesmesinde kullandığımız option_registerRB47 de kullanılmıyor timer kesmesinde yeri geldiğinde bu registeri tekrar inceleyeceğiz.

RBİE 4 7 KESMESİ

BRIE kesmesiint 0 kesmesinde değindiğimiz :“Pic programına kullanıcının müdehale etmesine veya PİC dışında gerçek dünyadaki bazı olguların müdehale etmesine olanak tanır. Bu Durum bir makinenin ACİL STOP butonu olabilir veya fiziki bir değişiklik sinyali ile olabilir yada bir çevresel aygıtın bilgi veren sinyali olabilir. Bunun gibi durumlarda PICe çeşitli işlemler yaptırmak için kullanıma müsaittir. “ Bilgilerini aynen geçerli kılar tek farkı toplam 4 terminali kesmeye duyarlıdır.

Buda demek oluyorki 2^4(iki üzeri dört) ten toplam 16 onaltıolasılğı değerlendirir ve PİC ile onaltı farkı durum için kesme programlaması gerçekleştirilebilir. Buda Pic ile bazı olguları çok hızlı ve kararlı kontrol etme olanağı sağlar.PIC bu 16 olgunun gerçekleşmesini portB 4 7 sinyallerinin her hangi birisinin kenar değişimini algılar ve programı kesme alt programına dallandırır

Bu kesmeyi kullanacağımız bir yazılım gerçekleştirelim. Ve Yazılımın hemen ardına 595leri tekrardan inceleyelim

Bu program portbnin 4 ile 7 bitleri arasındaki değeri ikili sayı sistemi ile portB 0 3 arasında gösterirken aynı anda portA da sonsuz döngüde yürüyen ışık yazılımı çalışmaktadır. Yazılımın anlaşılır kılınabilmesi için çevresel aygıtlardan sinyallerin bir bütün olarak gelmesi sebebi ile bu gerçekliği yakalayabilmek için kesmeler 74hc245 octal reciver entegresi kullanılarak sağlanmıştır.

74hc245 entegresinin bilgi aktarma pinini 1 yapmamızla birlikte girişlerindeki sinyalleri tek seferde pice yollar. Aynı anda 1 sn aralıklarla portA da gerçekleşen yürüyen ışık fonksiyonu kesme işleminden etkilenmeksizin devam eder.

Burada verilen Kodları yeni oluşturacağınız proje dosyasına ekleyip derleyiniz.


    /*Programı Hazırlayan Aytaç Dürgen                                                                  */


    /*değişkenler ve tablo tanımlamaları ayarlanıyor. Tablolar için dizileri anlattığım derslere göz atın*/
unsignedshort kesme_port_degeri=0,kesme_pin_ara_deger1=0,kesme_pin_ara_deger2=0,kesme_pin_ara_deger3=0,kesme_pin_ara_deger4=0,sayac;
unsignedshortkesme_tablo[16] ={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsignedshortyuru_tablo[] ={1,2,4,8,64,128,256};
     /****************BU PROGRAM BUTONA BASILDIĞINDA ********************/
void ayarlar(){
     CMCON=0x07;       /*Karşılaştırıcı modül kapatıldı Portlar dijitale ayarlandı*/
INTCON.GIE  = 1; /*Tüm kesmelere izin verildi*/
INTCON.RBIE = 1; /*portB 4-7 Kesmesi Aktiflendi*/
     PORTB=0;
     TRISB=0xF0; /*PORTB.4-7 KESMEYE Ayarlandığı için RB4 7  Giriş*/
     PORTA=0;
     TRISA=0x00;

}
     /******************************KESME PORTU SAYISAL DEĞERİ HESAPLAMASI*******************************************/
     /***********B portunun 4 ile 7 pinleri arasından hangisine veya hangilerine basıldığı bulunuyor*****************/
voidkesme_hesaplama(){
if(PORTB.B4)kesme_pin_ara_deger1=1;
if(PORTB.B5)kesme_pin_ara_deger2=2;
if(PORTB.B6)kesme_pin_ara_deger3=4;
if(PORTB.B7)kesme_pin_ara_deger4=8;
     /******************TÜM ARA DEĞERLER toplanarak PORTB 4 7 değeri hesaplanıyor        ***************************/
kesme_port_degeri=kesme_pin_ara_deger1+kesme_pin_ara_deger2+kesme_pin_ara_deger3+kesme_pin_ara_deger4;
     /******************TÜM ARA DEĞERLER YENİ KESMELERDEKİ HESAPLAMALAR İÇİN SIFIRLANIYOR***************************/
kesme_pin_ara_deger1=0;
kesme_pin_ara_deger2=0;
kesme_pin_ara_deger3=0;
kesme_pin_ara_deger4=0;
}
     /********************KESME ALT PROGRAMI****************************/
void interrupt(){



if(INTCON.RBIF){
kesme_hesaplama();
PORTB=kesme_tablo[kesme_port_degeri];
kesme_port_degeri=0;
INTCON.RBIF = 0;
}


}
void main()
{
ayarlar();



for(;;)
{

          /*sonsuz döngü içerisindeki yürüyen ışık fonksiyonu*/
for(sayac=0;sayac<7;sayac++){
          PORTA=yuru_tablo[sayac]; /*PortA de sayac değerine göre yukarıda tanımlanan tablo değerleri gösteriliyor.Bu kodlar PORTA nınpin yapısına uygun hazırlandı.
          A portu 16f628Anın iç osilatörükullanıldığında  6 çıkış olarak kullanılabiliyor. yada 8 giriş olarak kullanılabilir
          RA4 ve RA5 pinlerisadeceçıkış olarak kullanılabilmektedir ve bu durum pic donanımı ile alakalıdır*/
delay_ms(1000);
}



}
}

/*******************************************Program BURAYA KADAR*****************************************/

Şimdi SPi konusunu derinlemesine tekrar alıp yukarıdaki verdiğimiz programı genişletip kesme değerlerini port b de göstermek yerine 595 entegresine programla yazalım.

Öncelikle 595 entegresinin özelliklerini tekrar edelim 595 entegresi seri girişli paralel çıkışlı çıkışlarını aktif veya pasif yapabilen ,bir bilgiyi göstermeye devam ederken yeni bilgiyi kaydedebilen istendiğinde resetlenebilen,20Mhz hızında bilgiyi işleyebilen, çıkışlarını OE sayesinde PWM yapabilen “BENCE” üstün özellikli bir entegredir.

spi-74hc595

Şekilden de anlaşılabileceği üzere bu entegre Kaskat bağlanabilir (peşiSıra) bilgiyi seri data hatı üstünden alır ve yine tek bir hattan diğer entegreler için sinyal taşmasına izin verir. U1 entegresi 1.entegredir ve pic ile bilgi ilk olarak bu entegreye yollanır.

Bilgi bir bit kaydırılıp bir kez clock palsi gönderilir ve bu işlem 8 bitlik (genelde) byte halinde entegreye yazılır. Eğer peşi sıra bilgi yazılacaksa ve entegreler sıfırlama veya reset yapılmaz ise 2.paket veri yazımında gelen veriler ilk entegreye yazılır ve daha önce ilk entegrede olan veriler 2. Entegreye kaydırılıp çıkış aktif yapılınca bilgiler görüntülenir.

Önceki derslerde verdiğim şemayı aşağıda veriyorum ve şimdi onun üzerinde biraz konuşalım.

Eğer sadece port genişletme veya display sürme gibi işlemler yapılacaksa bu entegreler şekildeki bağlanıp reset ucu +5Volta Output Enable(OE) ucu –(GND) ye bağlanmalıdır.
Eğer daha fonksiyonel bir devre yapılacaksa ve bilgi peşi sıra aktarılmayıp ayrı demetler halinde tüm entegrelere tek seferde yazılacaksa o zaman reset ucu da pic programına dahil edilecektir.

OE ucu ise farz edelim bir grafik ekran ,kayanyazı veya animasyon kartı tasarladınız ve ekranınızın gündüz parlak gece kısık yanmasını istiyorsunuz yada bir bilgi panosu yaptınız ve bunun sabah ışıkla beraber çalışıp akşam karanlığında durmasını istiyorsunuz yada tam tersi , işte bu durumda bu ucu kullanıp istediğiniz özelliğe uygun programa dahil etmelisiniz.

Yukarıdaki devreye önceki derslerimizde veri yazmayı öğrendik .veri yazmayı nasıl yapıyorduk ? Hatırlayan var mı?

Hatırlamayan varsa sıfır vereceğim. :)

Ben sıfır vermeden kısaca bir anlatayım. Öncelikler data clock latch 0 da tutulur. Sonra data hattına verinin 1.biti koyulup bir clock yollanır (clock 1 yapılır sonra 0 a çekilir) 2. Veri dataya koyulur clock 3 4 5. 8. Kez veri yazılıp clock ardından latch 1 yapılıp sıfıra çekilir .ve böylece veri görüntülenir.

Şimdi bu işlemi elle yaptığımızı düşünürsek bizim hızımız bir iki hertz i geçmez o yüzden gelin bu işe PIC e yaptıralım da rahat edelim çalışsın dursun işinin adı ne o kadar emek verip programını yazıyoruz dimi :) :)

Kısaca özetleyeyim. Biz SPİ bilgi yazmayı programda çok defa kullanacağımız için her veri yazmak gerektiğinde program döktürmek yerine SPİ adında bir fonksiyon hazırlayalım ve programda yeri geldiğinde bu fonksiyonu çağırıp kullanalım.

SPİ programının temel yapısı şu olmalı Bizim programın çeşitli yerlerinde veya zamanlarında yazılacak veriyi değiştimemizeimkan tanıyacak özellikte olmalı. Program bu veriyi alıp bitlerini incelemeli 0.bitten başlayıp bit bir ise tanımlanan data pinine bir koymalı ve ardından clock palsini yollamalı datanın bitleri 0 ise datayı sıfır yapıp clock işlemini gerçekleştirmelidir.

Bunun için verini her zaman 7.bitini kontol edip 8 döngü halinde çalışan for altında her döngüde veriyi bir sola kaydırıp 7.biti tekrar okumalıyız.

Şimdi yukarıdaki programın bilgisini 595 e yazalım


    /*Programı Hazırlayan Aytaç Dürgen                                                                  */



/*Burada spi için pinler anlaşılır program için etiketleniyor*/
#define clock   PORTB.B0
#define data    PORTB.B1
#define latch   PORTB.B2
    /*değişkenler ve tablo tanımlamaları ayarlanıyor. Tablolar için dizileri anlattığım derslere göz atın*/
unsignedshort kesme_port_degeri=0,kesme_pin_ara_deger1=0,kesme_pin_ara_deger2=0,kesme_pin_ara_deger3=0,kesme_pin_ara_deger4=0,sayac,veri,temp;
unsignedshortkesme_tablo[16] ={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsignedshortyuru_tablo[] ={1,2,4,8,64,128,256};
     /****************spi alt programı************** ********************/
voidspi (unsignedshort veri)
{
unsignedshort i;
unsignedchartemp;
temp = veri;               /*veri ara değişkene aktarılıyor*/
i=8;
while (i>0)
{
if (temp.F7==0) data = 0; /*verinin kaydırılma işleminden sonra veya ilk kez 7. biti  kontrol ediliyor*/
else            data = 1;
temp = temp<<1;            /* veri bir bit sola kaydırılıyor */
        clock=1;                  /*veri 595de  bir kez öteleniyor*/
        clock=0;
i--;
}
latch=1;                   /*veri Görüntüleniyor*/
latch=0;
}

     /*Burada spi fonksiyonu sonlanıyor*********************************/
void ayarlar(){
     CMCON=0x07;       /*Karşılaştırıcı modül kapatıldı Portlar dijitale ayarlandı*/
INTCON.GIE  = 1; /*Tüm kesmelere izin verildi*/
INTCON.RBIE = 1; /*portB 4-7 Kesmesi Aktiflendi*/
     PORTB=0;
     TRISB=0xF0; /*PORTB.4-7 KESMEYE Ayarlandığı için RB4 7  Giriş*/
     PORTA=0;
     TRISA=0x00;

}
     /******************************KESME PORTU SAYISAL DEĞERİ HESAPLAMASI*******************************************/
     /***********B portunun 4 ile 7 pinleri arasından hangisine veya hangilerine basıldığı bulunuyor not 0000 değeri tanımlanmadı*****************/
voidkesme_hesaplama(){
if(PORTB.B4)kesme_pin_ara_deger1=1;
if(PORTB.B5)kesme_pin_ara_deger2=2;
if(PORTB.B6)kesme_pin_ara_deger3=4;
if(PORTB.B7)kesme_pin_ara_deger4=8;

     /******************TÜM ARA DEĞERLER toplanarak PORTB 4 7 değeri hesaplanıyor        ***************************/
kesme_port_degeri=kesme_pin_ara_deger1+kesme_pin_ara_deger2+kesme_pin_ara_deger3+kesme_pin_ara_deger4;
     if((PORTB.B7==0)&&(PORTB.B6==0)&&(PORTB.B5==0)&&(PORTB.B4==0))kesme_port_degeri=0;
     /******************TÜM ARA DEĞERLER YENİ KESMELERDEKİ HESAPLAMALAR İÇİN SIFIRLANIYOR***************************/
kesme_pin_ara_deger1=0;
kesme_pin_ara_deger2=0;
kesme_pin_ara_deger3=0;
kesme_pin_ara_deger4=0;
}
     /********************KESME ALT PROGRAMI****************************/
void interrupt(){



if(INTCON.RBIF){
kesme_hesaplama();
if(kesme_port_degeri != 0){
spi(kesme_port_degeri);       /*kesme gerçekleştiği anda spi alt programı çalıştırılıp kesme port değeri fonksiyona alınıp gönderiliyor(parantez içerisine yukarıda tanımlandı*/
kesme_port_degeri=0; }
INTCON.RBIF = 0;
}


}
void main()
{
ayarlar();



for(;;)
{

          /*sonsuz döngü içerisindeki yürüyen ışık fonksiyonu*/
for(sayac=0;sayac<7;sayac++){
          PORTA=yuru_tablo[sayac]; /*PortA de sayac değerine göre yukarıda tanımlanan tablo değerleri gösteriliyor.Bu kodlar PORTA nınpin yapısına uygun hazırlandı.
          A portu 16f628Anın iç osilatörükullanıldığında  6 çıkış olarak kullanılabiliyor. yada 8 giriş olarak kullanılabilir
          RA4 ve RA5 pinlerisadeceçıkış olarak kullanılabilmektedir ve bu durum pic donanımı ile alakalıdır*/
delay_ms(1000);
}



}
}




/*PROGRAM SONU*

Çalışmanın devre şeması

sonsuz-donguler-yuruyen-isisk-led-display

Bu dersimizi burada sonlandırıyorum. Bir sonraki dersimizde timer0 kesmesini ele alacağız sanıyorum artık program yazabilir hale geldik. TMR0 kesmesinin uygulaması olarak SPİ yöntemi ile 7 segment display süren program düşünüyorum. Farkı program yazmamı isteyen arkadaşlar bana bildirin.

Programın çalışma ve isis dosyaları; mikroc-dersleri-9.zip – Ama tavsiyem hazırdan ziyade yeniden sizin yeniden dosyaları oluşturmanızdır.

Uğraşanlara kolay gelsin İyi çalışmalar.

http://www.facebook.com/#!/tarsus.led
aytacdurgen@gmail.com

Aytaç Dürgen
Elektrik Elektronik Teknolojileri
Teknik Öğretmen

  • ali-ekin

    hocam dersler bittimi? 10. ders yokmu?

  • aytaç Dürgen

    @Ali Ekin 10,dersi hazırlıyorum. işlerden fırsat bulamıyorum. o yüzden geciktiriyorum

  • Ali Ekin

    anladım hocam yeni baktım tarihe, size çok teşkkür ediyorum emeğinize,yüreğinize sağlık

  • A.E

    hocam meraklı ve sabırsız bir öğrenciniz olarak tekrar haatırlatmak istedim 10. dersimizi unutmanıza izin vermem :D iyi çalışmalar

  • aytaç Dürgen

    yılbaşına kadar yetişecek bir kaç iş var vakit bulup toparlıyamadım.
    Biraz geç oluyor ama idare edin hocanızı.
    yılbaşının ilk günlerine yeni ders yayında olur allahın izniyle.

  • Gökhan

    Yazılımsal spi kısmı işime yaradı. Teşekkürü borç bilirim.