14 Haziran 2015 Pazar

SDCC ile Led Yakma (PIC16F628A) – Ders03


Bir önceki dersimizde belirli zaman aralıkları ile LED yakıp söndürme uygulamasını yapmıştık. Bu derstede çalışma olarak aynı diyebileceğimiz bir uygulamayı yapacağız. İki ders arasındaki tek fark sigorta ayarlarının pic16f628a ya göre yapılmış şeklini göreceğiz. Belki basit bir sigorta ayarı diyebilirsiniz ancak pic16F886 ile pic16F628A arasındaki sigorta ayarlarının aynı olmadığını öğrenmek benim yaklaşık 6 saatime mâloldu :) . Deneme yanılma yolu ile buldum diyebilirim. Tabi bendeniz bu işin uzmanı olmadığım için bir uzmana göre daha çok uğraştım. Siz uğraşmayasınız diye bu yazıyı kaleme alıyorum. Şimdi pic16F628A ya göre hazırlanmış devreyi ve yazılmış kodu bir görelim.

















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

#define NO_BIT_DEFINES
#include <pic14regs.h> //Mikrodenetleyici Ayar adreslerini ve seçenekleri içerir
#include <stdint.h> //uint16_t tanımı için gerekli

//Dahil osilatörü kullanacak ve osilatör portları giriş çıkış amaçlı kullanacağım
//Watch Dog Timer devredışı
//Düşük voltaj programlaması devre dışı.
// Bu ayarlanmış sigorta ayarlarının dışında kalanlar varsayılan ayarlar olacaktır.

__code uint16_t __at _CONFIG __configword = _INTRC_OSC_NOCLKOUT && _WDTE_OFF && _LVP_OFF;

//Not: Yukardaki sigorta ayarları pic16f628a ya özel oluşturuldu.

#define LED_PORT PORTBbits.RB0
#define LED_TRIS TRISBbits.TRISB0

// kalibrasyonsuz delay, sadece bir dizi döngü yinelemeleri için beklemeyi sağlar.
void delay(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 < 4; j++)
__asm nop __endasm;
}
}

void main(void){

LED_TRIS = 0; // Pin çıkış olarak ayarlandı
LED_PORT = 0; // LED sönük
while(1)
{
LED_PORT = 1; // LED Yanıyor
delay(10000); // 1 sn bekle
LED_PORT = 0; // LED Sönük
delay(10000); // 1 sn bekle
}

}


Bu kodun diğer bir farkıda delay fonksiyonunda oldu. Bu mikrodenetleyicinin dahili osilatörünün hızından kaynaklı delay fonksiyonunda senkronizasyonu sağlamak için düzeltmeler yaptım. Isis programında yaptığım testte tâbi tuttuğumda gerçektende birer saniye aralıklarla yanıp söndüğünü gördüm.

Şimdi pic16886 ile pic16f628a mikrodenetleyicileri için fark arz eden sigorta ayarlarının yapıldığı satırlara göz atmaya :

PIC16F628A için:

__code uint16_t __at _CONFIG __configword = _INTRC_OSC_NOCLKOUT && _WDTE_OFF && _LVP_OFF;

PIC16F6886 için:

__code uint16_t __at (_CONFIG1) __configword = _INTRC_OSC_NOCLKOUT && _WDTE_OFF && _LVP_OFF;


Aslına bakarsanız çok bir fark yok. Sadece (_CONFIG1) ifadesini 16F628A mikrodenetleyicisi için derleyici kabul etmedi ve hata verdi. O yüzden deneme yanılmalar sonucu bu ifadenin yerine _CONFIG değişkenini kullanınca sorunu çözdüm. Bilmiyorum belki 16F628A için olan tanımlama diğeri içinde geçerli olabilir. Ancak böyle bir farkı gördüğümü sizlerle paylaşmak istedim. Muhtemelen başlık dosyasındaki tanımların uyuşmayışıyla alakalı olabilir. Gördüğünüz üzere kodun geri kalan kısmında fazla bir fark yok. Sdccman.pdf el kitabından okuduğuma göre pic14 yazılım mimarisi ile pic16 yazılım mimari arasında sdcc tarafından iyileştirmelerin yapıldığı ve pic16 tarafının daha iyi Ansi C uyumu sağlağı gibi şeylerden bahsetmekte. Zaten ileriki derslerde göreceğimiz üzere pic16 yani 18FXXXX piclerde sigorta tanımlarını #pragma önişlemci ifadesi ile daha iyi yapılabildiğini göreceğiz. Sdcc geliştiricileride 18F grubu piclerde eski tanımlama yerine #pragma önişlemci ifadesi ile yapılmasını tavsiye etmekteler. Şimdilik bununla kafanızı karıştırmayın. Bir sonraki derste görüşmek üzere Hoşçakalın.


duralikiraz.blogspot.com
15 Haziran 2015

Muvaffakiyet Allahtandır”

2 yorum:

  1. 18f lerde de _CONFIG1 kullanılıyor

    YanıtlaSil
    Yanıtlar
    1. Teşekkür ederim Abdurrahman bey. Bu yorumunuz yazı dizimin amaçlarından biriydi. Yalnız dikkat ederseniz 16F serisinde PIC16F6886 için (_CONFIG1) çalışmış. Demekki bu kural sdcc için geçerli değilmiş benim tecrübe ettiğim kadarıyla.

      Sil