20 Haziran 2015 Cumartesi

SDCC ile 7 Segment Display Uygulaması ve 0-9 Sayıcı (16F877A) –Ders06











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

#include <pic14regs.h>

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 ;

// 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;
   }
}


                                      // .gfedcba Görünen 
const unsigned char segment[]={ 
                                0x3F, // 00111111 0
                                0x06, // 00000110 1
                                0x5B, // 01011011 2
                                0x4F, // 01001111 3
                                0x66, // 01100110 4
                                0x6D, // 01101101 5
                                0x7C, // 01111100 6
                                0x07, // 00000111 7
                                0x7F, // 01111111 8
                                0x6F // 01101111 9
                             };

void main(void) // Ana fonksiyon alanı
{
   char i = 0; // Herhangi bir değişken tanımlanıyor
   TRISB = 0x00;// PORTB çıkış olarak yönlendiriliyor
   PORTB = 0x00;// PORTB'nin tüm çıkışları sıfırlanıyor

   for(;;) // Sonsuz döngüye giriliyor
   {
      PORTB = segment[i]; // Seven segment değerleri alınıyor
      i++;                // i bir artırılıyor
      ms_bekle(1000);     // 1000ms bekleniyor
      if(i>9)             // Eğer sayı 9'dan büyük ise 0'a dön
         i=0; // Değişken 0 yapılıyor
   }
}



Bu dersimizde elektroniğin en önemli çıktı araçlarından 7 segment display ile 0~9 arası basit bir sayıcı (counter) yapmaya çalışacağız. 7Segment display; kısaca üzerinde 7 adet led'i bulunan elektronik bir parça. Çalışma şekli olarak ortak katot ve ortak anot olmak üzere iki çeşittir. Tabi bunların da alt çeşitlerinin olduğunu bilmek gerekiyor. Yazılımla bu 7 segmente ait ledlerden hangisinin yanıp hangisinin söneceğine karar veriyoruz. Olayın hepsi bu. Tabi bunun yanında ikili,üçlü hatta 4 lü segment display lerde kullanılmakta. Onlarla igili örneğimizi başka bir ders yada dersler olarak değerlendireceğiz.




Bu devredeki uygulayacağımız mantık bellirli zaman aralıklarında (1000ms) sırayla ilgili ledlerini yakıyoruz. Böylece sayı sayma efektimiz oluşmuş oluyor. Kod'a bakacak olursak; daha önceki derslerimizde bahsettiğimiz sigorta tanımlarımız, pic16f877a 4 MHZ için senkronize ettiğimiz ms_bekle isimli bekleme fonksiyonumuz yer almakta. Daha sonra kod üzerinde açıklamaya çalıştığımız segment isimli bir sayısal dizi tipimiz var. Diziyi onaltılık (hexadecimal) olarak tanımladık. İstersek binary yada onluk tipinde de yazabilirdik, farkeden bir şey olmaz. Dizide her değerin yanında ikilik karşılıklarını açıklama olarak yazdığımız dikkatinizi çekmiştir. By ikilik sayı görüntüsündeki 1 ler yanacak olan ledleri, 0 lar ise sönük kalacak ledleri işaret eder. Yani herşey 1 ve 0 olayı. Biz yinede hangi sayının gönderilen değerlerle 7 segment displayde görüneceğini Görünen diye belirttik. Herhalde bu husus anlaşılmıştır.

Ana kodumuza (main fonksiyonu) gelecek olursak; B portunun tüm pinleri çıkış olarak ayarlanmış, ardından başlangıç olarak 0x00 değeri gönderilmiştir. Sonrasında for ile sonsuz döngümüz başlamakta. Bu döngü içinde

PORTB = segment[i];

satırında segment isimli dizi değişkenin i ninci elemanı PORTB ye atanıyor. Bildiğiniz gibi diziler 0 başlangıç değerini indis olarak seçer. Yani sıfırıncı eleman ilk elemanıdır. Dolayısınla ilk olarak i=0 olduğu için segmentin sıfırıncı eleamanı (0x3F) PortB ye atanır. 0x3F gösterimde sıfırın gösterilmesini sağlar. Bu sebeple displayda 0 gözükür. Sonrasında

i++;

ile esasında “i = i+1” yapılır. Ve

ms_bekle(1000) ;

ile 1 saniye kadar bekleme yapılır.

if(i>9)
i=0;

satırı ile i eğer 9 a ulaşmışsa sıfırlanır. Yani döngü 10 kere dönüş yapar ve dizideki 10 elemanı sıra ile display'e gönderir. Bu döngü sonsuza kadar devam eder. Başka bir derste görüşmek üzere hoşçakalın.


duralikiraz.blogspot.com
20 Haziran 2015


Muvaffakiyet Allahtandır”



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”