17 Haziran 2015 Çarşamba

SDCC ile Karaşimşek Uygulaması (16F877A) –Ders05




 
// Copyright (C) 2015 Durali Kiraz
// PIC16F877A için hazırlandı.

#include <pic14regs.h> //Mikrodenetleyici Ayar adreslerini ve seçenekleri içerir

typedef unsigned short int uint16_t;

//sigorta tanımlarımızı yapıyoruz.
__code uint16_t __at _CONFIG __configword =
_FOSC_XT &&
_WDT_OFF &&
_BOREN_OFF &&
_LVP_OFF ;

// kalibrasyonsuz delay, sadece bir dizi döngü yinelemeleri için beklemeyi sağlar.
// Bu ms_bekle 168877a 4 Mhz frekansı için ayarlanmış bir fonksiyondur
void ms_bekle(uint16_t milisaniye)
{
  uint16_t i,j;
  for (i = 0; i < milisaniye; i++)
  {
    // Döngüde optimizasyon için bu asm komutu eklenmiştir.
    for (j=0; j < 46; j++)
     __asm nop __endasm;
  }
}



void main(void)
{
  unsigned char kaydirikci=1; // kaydirikci şeklinde bir sabit tanımlanıyor
  TRISB = 0x00; // PortB tamamen çıkış olarak ayarlandı.
  PORTB = 0x00; // PORTB'nin tüm çıkışları sıfırlanıyor

  for(;;) // Sonsuz döngüye giriliyor
  {
     PORTB = kaydirikci; // PORTB kaydirikci değişkenine eşitleniyor
     kaydirikci = kaydirikci << 1; // kaydirikci birimi bir sola kaydırılıyor
     ms_bekle(100); // 100ms bekleniyor

    if(kaydirikci == 0x80) // Eğer PORTB=0x80 olursa alt işlemlere geçiliyor
    {
      for(;;) // Tekrar sonsuz döngüye giriliyor
      {
        PORTB = kaydirikci; // PORTB led değişkenine eşitleniyor
        kaydirikci = kaydirikci >> 1; // kaydirikci birimi bir sağa kaydırılıyor
        ms_bekle(100); // 100ms bekleniyor
        if(kaydirikci == 0x01) // Eğer PORTB=0x01 olursa ikinci sonsuz döngüden
           break; // birinci sonsuz döngüye giriliyor
      }
    }
  }

}


Bu dersimizde nev'i şahsına münhasır Karaşimşek devresini yapamaya çalışacağız. Yukarıda açık devre çizimini ve kodu paylaştım Bu kodu derlemek için Konsolda;

sdcc --use-non-free -mpic14 -p16f877a Karasimsek.c

demeniz yeterli. Oluşan hex dosyasını gpsim yada Proteus-Isis gibi bir similasyon programında verdiğimiz açık devredeki gibi oluşturarak test edebilirsiniz. Bu derslerdeki devreler proteus isis üzerinde test'i tarafımdan yapılarak burada paylaşılmaktadır. Simulasyonda ledler arasındaki yanıp sönme ile oluşan ahengi sizde hissedebilirsiniz.
Kodumuza bakacak olursak bir önceki derste bahsedildiği gibi 16F877A ya mikrodenetleyicisinin 4 MHZ kristal ösilatör ile nispeten uyumlu bir ms_bekle fonksiyon tanımız var. Sigorta ayarlarımız keza yine bu mikrodenetleyici seçimine uygun. Kodumuzdaki can alıcı nokta iç içe olan “for” döngüleri. İlk for döngüsü ile 1 değeri atanmış kaydirikci isimli bir değişkenimizi PortB nin tamamına atamasını yapıyoruz. Bu değişken adı üstünde ikilik sistemde 1 değerini sağdan (yani b0 bitinden) sola (b7 bitine) doğru birer basamak kaydırma işlemlerini öncesinde yapacağımız, sonrasında da bu kaydırılmış değeri PORTB ye atayacağımız bir değişkendir. Zaten bir alt satırda

kaydirikci = kaydirikci << 1;
yapıldığı görülmekte. Buradaki “<<” ifade ANSI C dilinde sağdan sola doğru bitsel kaydırma operatörüdür. Yaptığı iş kısaca bir sayının ikilik değerinin sağ tarafına bir adet sıfır ekleyerek bir basamak kaydırmasını yapmaktır. Şöyleki;

00000001 sayısını
00000001 << 1 işlemine bir sefer tâbi tutarsak
00000010 sayısını elde ederiz.

Umarım farkı anlayabilmişsinizdir. Şimdi bu işlem bu ilk for döngümüz ile 00000001 sayısı 10000000 haline gelene kadar devam eder. 10000000 ikilik sayısının onaltılık sayı sistemindeki karşılığı 0x80 dir. Dolayısıyla 0x80 haline gelince ikinci for döngüsü başlayacaktır. Bu ikinci for döngüsüde diğer döngüde yaptığı gibi yine kaydirikci değişkenindeki sayımıza bitsel kaydırma işlemi yapacaktır. Fakat bu sefer kaydırmayi sağdan sola değil soldan sağa doğru yapacaktır. Bu işlemin şu şekilde

kaydirikci = kaydirikci >> 1;

yapıldığı görülmekte. Buradaki “>>” ifade ANSI C dilinde soldan sağa doğru bitsel kaydırma operatörüdür. Yaptığı iş kısaca bir sayının ikilik değerinin sol tarafına bir adet sıfır ekleyerek bir basamak sağa kaydırmasını yapmaktadır. Şöyleki;

10000000 sayısını
10000000 >> 1 işlemine bir sefer tâbi tutarsak
01000000 sayısını elde ederiz.

Bu ikinci for döngüsü de ikilik olarak 00000001 sayısına yani onaltılık sayı olarak 0x01 değerine ulaşıncaya kadar döngüyü devam ettirir. 0x01 değerine ulaştığında ise döngüyü “break” ifadesi ile durduruyoruz. Bunun sonucunda kodumuz tekrar ilk for döngüsünün başına gelir. Sonuçta bu iç içe iki döngü sonsuza kadar devam eder.

Şimdi bu bitsel kaydırmanın sonuçlarına toplu olarak bakarsak bütünü görmemiz daha kolay olabilir.

birinci döngünün çalışma sonuçları

00000001
00000010
00000100
00001000
00010000
00100000
01000000
10000000

ikinci döngünün çalışma sonuçları

10000000
01000000
00100000
00010000
00001000
00000100
00000010
00000001

Umarım bu görüntü mantığı anlamanızda yardımcı olmuştur. Efektimiz daha iyi olması için her kaydırma sonrası 100 milisaniye bekleme aralığı belirledik. Başka bir derste görüşmek üzere hoşçakalım.


duralikiraz.blogspot.com
17 Haziran 2015

Muvaffakiyet Allahtandır”

Hiç yorum yok:

Yorum Gönder