Pic C ile 2×16 Sıvı Krisal Ekran'da (LCD) Karakter Oluşturmak

Bir önceki yazımda pic c ile 2×16 ekrana yazı yazmaktan bahsetmiştim. Bu yazıda ise kendi oluşturabileceğimiz karakterleri ekrana yansıtmaktan bahsedeceğim.Üzerinde çalıştığım, 2×16 HD44780 nokta matrisli sıvı kristal ekrandır.Genellikle piyasada 2×16 denildiği zaman bu ekran geçer.Bu arada belirtmek isterim; LCD açılımı olan “liquid crystal display” yerine “sıvı kristal ekran” ifadesini kullanmayı daha doğru bulduğumdan bundan sonra bu şekilde bahsetmeyi istiyorum.
LCD

LCD

Şimdi çok uzatmadan yavaş yavaş ekranımızda karakter oluşturmaya başlayalım.
Not:Burdaki bilgiler ccs pic c derleyicisi kullanılarak hazırlanmıştır. Bilgileri uygulamak için pic c tecrübesi gerekir.
Kullandığımız 2×16 sıvı kristal ekranlarda Türkçe karakter desteği yoktur.Üretici firma kullandığımız bu ekranları ascii tablosuna göre kullanım olanağı sağlamıştır. Ascii kodlaması, İngilizce’de kullanılan latin alfabesi üzerinde oluşturulmuş bir karakter kodlama tipidir. Ayrıca bakınız. Projelerimizde örn: ğ,ı,ş,ü,ç,gülücük,çöp adam vs.. gibi karakterleri kullanacağımız durumlar elbette olacaktır. Bu sebeple ekran üreticisi, tanımsız karakter oluşturulabilmesi için en fazla sekizer bayttan 8 karakterin yazılabileceği boyutta kullanıcıya hafıza bırakmıştır. Kullanıcı 5×7 matris yöntemi (aşağıda bahsedeceğim) ile kendi oluşturduğu karakterin kodunu bu hafızaya yazarak istenildiği vakit ekrana yazdırılmak üzere bu hafızada yer alan karakterleri çağırabilir.Kullanıcı isterse bu hafızayı geçici olarak(ram) bilgi saklamak üzere de kullanabilir.Bu yazıda asıl olarak bahsettiğimiz hafızanın(cgram’in) kullanımından bahsedeceğim.
Öncelikle karakter nasıl oluşturulur, bir göz atalım. Geri kalanını oku »

Pic C ile 2×16 Lcd Ekran (2*16 lcd)

Ekranlar, günlük yaşantımızda hayatımızı kolaylaştırmaya yarayan en güzel örneklerdendir. Kullanım alanları sınırsızdır. örneğin; hız, nem, sıcaklık, basınç v.b.  gibi değerleri ekranlar aracılığı ile rahatlıkla görebiliriz veya okuyabiliriz. Bu yazıda pic c ile 2*16 lcd ekran kullanmayı öğreneceğiz. Pic c dilini kullanmak bize bir takım avantajlar ve en önemlisi büyük kolaylık
sağlıyor. Pic c’yi yeni öğreniyorsanız, daha önceden “c programlama” diline ait bir takım bilgilere sahipseniz hiç zorluk çekmeyeceğinizden eminim. Sayfalarca yazacağınız asm kodlarını, pic c’de çok daha az sayıda sayfa ile kod yazarak büyük yükten kurtulabilirsiniz. Tabi ki asm bilmek önemlidir. Bence sadece asm bilen bir elektronikçi asm’nin hamallığını çeker, asm ve pic c bilen elektronikçi basit bir şekilde büyük işleri halledebileceği gibi takıldığı yerde asm ile de müdahele edebilir, sadece pic c bilen bir elektronikçi ise işlerini yapar fakat takıldığı yerlerde arka plana müdahele edemeyebilir. Bu da asm’nin
avantajıdır. Biraz pic c hakkında ön bilgi verdikten sonra artık lcd ekranı sürmeye geçelim.

Önemli not: Burdaki bilgiler CCS PCWH 4.018 derleyicisi kullanılarak hazırlanmıştır.
Aşağıda lcd ekran için kullanabileceğimiz fonksiyonlar ve açıklamaları. Geri kalanını oku »

Pic Programlama Devresi

Merhaba arkadaşlar,

Aşağıda şeması ve baskı devre görünümünü verdiğim Pic programlama devresi ile PIC 16F84, PIC 16F84A, PIC 16F628 ve PIC 16F628A gibi 18 bacaklı Pic mikrokontrolör entegrelerini programlayabilirsiniz.

Bu devreyi, seri port ile programlayan programlayıcılarda kullanabilirsiniz. Mesela PicUP, Picprog gibi programlayıcıları kullanabilirsiniz.

Devre şeması:

pic programlama kartı

Baskı Devre:

Genel Yerleşim:

Üstten Görünüş:

Teknomerkez.com’dan alıntıdır.

Selim Şahin
elosel@teknomerkez.net

Pic Basic Öğreniyorum-4

Ders-4
Program Oluşturma Genel Kuralları

Bu bölümde bir program yazılırken nelere dikkat etmeliyiz, hangi bilgi nerede verilmeli bunları öğreneceğiz. Ayrıca program oluşturmak için kullanacağımız yazılımlara bir göz atacağız.
Daha sonrada oluşturduğumuz programı derleyip Hex file (Hex Dosyası) haline getirip Pic’e yüklemeyi öğreneceğiz.
Basic programları yazılırken bir editör programından yararlanılır. Bu herhangi bir editör programı olabileceği gibi BASIC ler için yaratılmış özel editör programları da olabilir. Tabii ki özel editörlerin görsellik ve program takibi açısından büyük avantajları vardır. Bu nedenle bizde Özel editör programlarından olan Micro Code Studio programını kullanacağız.

Program yazma işinde ilk önerimiz programlarınızın başına bir başlık mutlaka yerleştirin.
Bu aynı zamanda program sırasında ilk olarak yazılacak bölümü kapsamaktadır.

Örnek başlık;
****************************************************************
‘* İsim : Program Adı.BAS *
‘* Yazar : [İsminiz] *
‘* Not : Copyright (c) 2004] *
‘* : Tüm Hakları Saklıdır *
‘* Tarih : 21.12.2004 *
‘* Sürüm : 1.0 *
‘* Notlar : *
‘****************************************************************
Hiçbir program ilk yazıldığı hali ile çalışır hale gelmez. Sürekli olarak düzeltmeler yapıldıktan bir müddet sonra program yerine oturur. Bu nedenle her program değişikliğinde sürüm numarasını mutlaka değiştirmeye çalışın. Aksi taktirde programın hangisi olduğu konusunda tereddüde düşersiniz.
Bu başlık verildikten sonra , şayet program içinde interrupt (kesme) kullanılacak ise ikinci öncelik sırası olarak kesme tanımlaması yapılmalıdır. Tanımlama şöyle olabilir.

ON INTERRUPT GOTO KESME
Şayet kesme kullanılmayacak ise Giriş çıkış pinleri ayarlanmalıdır.

TRISA=0
TRISB=255 gibi

Daha sonra kullanılan mikro işlemciye ait Device tanımlamaları ve Config bilgileri verilmelidir.
Burada @ (at) işareti ile başlayan ve aslında ASM (assembly) komutlarının Basic satırlarında kullanılmasına olanak tanıyan bir komuttan yararlanıyoruz. Çünkü bu komutlar ASM komutları olarak verilmektedirler. Örnek kullanım şekli aşağıdaki gibi olacaktır.

@ DEVICE pic16F628
@ DEVICE pic16F628, WDT_ON
@ DEVICE pic16F628, PWRT_ON
@ DEVICE pic16F628, PROTECT_OFF
@ DEVICE pic16F628, MCLR_ON
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT ‘XT_OSC – HS_OSC –

Yukarıdaki örnekte program için ilk sırada 16F628 mikro işlemcisinin kullanılacağı tanımlanıyor . İkinci sırada Config değerini oluşturmak üzere, Watch Dog Timer On yani açık yapılıyor.
Üçüncü sırada Power on Timer açık olarak ayarlanıyor.
Dördüncü sırada Kod Protek kapalı olarak ayarlanıyor.
Beşinci sırada MCLR pini kullanılacak deniyor. Bu 16F628’in bir özelliği olup MCLR pini gerektiğinde bir INPUT pini olarak kullanılabilmektedir. Burada MCLR ON yani açık olarak ayarlanıp pin’in MCLR fonksiyonu şeklinde kullanılacağını gösteriyor. Şayet bu OFF yapılırsa MCLR pini bir INPUT pini olarak kullanılabilir.

Son satırda ise yine 16F628’e özel bir komut görülüyor. Bu komut 16F628 içinde bulunan dahili osilatör ün kullanılıp dışarıya ayrıca Clock çıkışı yapılmayacağını göstermektedir. Bu komuta yazılabilecek diğer alternatifler satır sonunda XT_OSC veya HS_OSC olarak verilmiştir.
Bu işlemler yerine getirildikten sonra yine mikro işlemci tipine bağlı olarak gerekirse bir emir daha verilir. Bazı işlemcilerde Komparatör bazılarında ise Analog-Digital çeviriciler bulunur. Bu sistemler açılışta önseçimli (default) olarak açık çalışırlar. Yani Komparatör ’ü olan bir Pic de aksine bir emir koymaz iseniz Komparatör önseçimli olarak çalışır. Şayet bu Komparatör bacaklarını iptal edip onları normal giriş-çıkış pin lerine dönüştürmez iseniz programınız hatalı çalışacaktır. Bu yüzden programın bu sırasında var ise bu komutlar yer alır.

Komparatör lerin iptali için genelde;
CMCON=7 şeklinde bir komut yazılır.
Analog Digital çeviricilerin iptali için ise;
ADCON1=7 bilgisi verilir.
Verilen değerler pic tipine göre değişiklik arz edebilir. Bu nedenle işlemcilerin Data Sheet’ lerine bakarak doğru bilgiler verilmelidir.
Bu bölümden sonra programda LCD kullanılacak ise LCD tanımlamaları yapılır.
Örnek tanımlama bir önceki derste verilmiştir. Görsel olarak unutulmaması için burada yeniden tanımlama yapıyoruz.
DEFINE LCD_DREG PORTB ‘LCD data bacakları PortB ye bağlı
DEFINE LCD_DBIT 4 ‘LCD data bacakları 4. bit den başlıyor
DEFINE LCD_RSREG PORTB ‘LCD RS Bacağı PortB ye bağlı
DEFINE LCD_RSBIT 1 ‘LCD RS bacağı 1. Bite bağlı
DEFINE LCD_EREG PORTB ‘LCD Enable Bacağı PortB ye bağlı
DEFINE LCD_EBIT 3 ‘LCD Enable Bacağı 3. bite bağlı
DEFINE LCD_RWREG PORTB ‘LCD RW Bacağı PortB ye bağlı
DEFINE LC_RWBIT 2 ‘LCD RW Bacağı 2. bite bağlı
DEFINE LCD_BITS 4 ‘LCD 4 bit olarak bağlı
DEFINE LCD_LINES 2 ‘LCD 2 sıra yazabiliyor

Bu aşamadan sonra sıra, Değişkenlerin tanımlanmasına gelir. Programın bu bölümünde program içinde kullanacağımız değişken isimleri ve tipleri belirlenir. Değişkenler büyüklüklerine göre Bit – Byte ve Word tipinde belirlenebilirler. Gerekirse port pinleri için Symbol tanımlaması kullanılabilir. Dolayısıyla Symbol tanımlaması da değişken tanımlama bölümünde yapılmalıdır.

Örnek vermek gerekir ise
SIRA VAR BYTE
TOPLAM VAR WORD
X VAR BYTE
DOGRU VAR BIT
TUS VAR PORTB.0
CLK VAR PORTA.1
DATA VAR PORTA.2
SYMBOL BUTON=PORTB.7
SYMBOL LED = PORTB.6
Değişken tanımlamaları verildikten sonra, program için gerekli olan ilk değerler ayarlanır. Genelde değişkenler sıfırlanır (sıfıra eşitlenir). Varsa LCD için Türkçe karakterler tanımlanır.
SIRA=0
TOPLAM=0
X=0
LOW CLK
Artık sıra programın ana bölümüne gelir. Genellikle programlar bir etiket ile başlatılır. Çünkü işlemlerin tekrarlanması amacı ile tekrar bu başlangıç bölümüne geri gelinmesi gerekebilir. Etiket adı olarak genelde BASLA veya START veya ILK veya BIRINCI gibi isimler kullanılır.
Şimdi buraya kadar öğrendiklerimizi bir Örnek programla tekrarlayalım.
Proje 4a : 

resim

Yapacağımız örnekte LCD kullanmayacağız. İşlemci 16F628 olacak. Port a ya bağlı butonlar olacak ve bunlar normalde pinler Pull-up olarak ayarlanacak.

PortB pinlerine ise birer tane LED bağlı olacak. Port a da hangi Buton’a basılırsa PortB de aynı bite karşılık gelen Led yanacak veya yanık ise sönecek. Programımız bu şimdi tüm program yazma kaidelerini uygulayarak programımızı yazalım.

‘****************************************************************
‘* Name : TOGGLE.BAS *
‘* Author : [E.T.E] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 01.09.2004 *
‘* Version : 1.0 *
‘* Notes : *
‘****************************************************************
TrisA=255
Trisb=0
‘————————————————————————————————————
@ DEVICE pic16F628 ‘işlemci 16F628
@ DEVICE pic16F628, WDT_ON ‘Watch Dog Timer açık
@ DEVICE pic16F628, PWRT_ON ‘Power on Timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Protek kapalı
@ DEVICE pic16F628, MCLR_ON ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘—————————————————————————————————————
CMCON=7 ‘16F628 de kompa
ratör pinleri iptal hepsi giriş çıkış
‘—————————————————————————————————————
SYMBOL TUS0=PORTA.0
SYMBOL TUS1=PORTA.1
SYMBOL TUS2=PORTA.2
SYMBOL TUS3=PORTA.3
SYMBOL TUS4=PORTA.4
LED0 VAR PORTB.0
LED1 VAR PORTB.1
LED2 VAR PORTB.2
LED3 VAR PORTB.3
LED4 VAR PORTB.4
PORTB=0
‘————————————————————————————————————————
BASLA:
IF TUS0=0 THEN ‘Tuşa basılmadığı zaman Tus=1 dir basılınca 0 olur.
TOGGLE LED0 ‘ LED’in durumunu değiştir yak veya söndür.
WHILE TUS0=0 ‘ hala tuşa basılı tutuluyor ise
wend ‘ bırakılıncaya kadar bekle.
endIF ‘ tuş bırakılınca buraya geç.
IF TUS1=0 THEN TOGGLE LED1
IF TUS2=0 THEN TOGGLE LED2
IF TUS3=0 THEN TOGGLE LED3
IF TUS4=0 THEN
TOGGLE LED4
WHILE TUS4=0
WEND
ENDIF

‘ TUS kullanımı son derece değişik neticeler verir. Yukarıdaki örnekte
‘ toplam 5 adet Tuş bulunmaktadır. İlk tuş ile sonuncu tuş korumaya alınmıştır.
‘ korumadan kasıt tuşa bir kere basılınca Toggle komutu icra edilmekte ancak
‘ tuş bırakılıncaya kadar başka hiç bir işlem yapılmamaktadır.
‘ Diğer tuşlarda ise koruma yoktur. Toggle komutu yerine getirildikten sonra
‘ program çok hızlı bir şekilde yeniden aynı tuşa bakmakta ve şayet halen basılı
‘ ise bir kez daha toggle komutunu icra etmektedir. Tüm tuşları deneyerek aradaki
‘ farkı görmeye çalışınız. Gerekirse PAUSE 100 süresini daha da kısaltarak farkı görmeye
‘ çalışınız.
PAUSE 100
GOTO BASLA
END
Yukarıdaki programda kullandığımız bazı komutları tekrar açıklayıp değişik kullanım örnekleri vereceğiz.
İlk komutumuz IF yani şart komutu dur. Türkçesi ŞAYET olan bu komutu şarta bağlı bazı durumlar için kullanmaktayız. Programımızda olduğu gibi ;
ŞAYET TUŞ0’a basılmış ise TOGGLE LED0 komutunu icra et. Bunun Basic satırı olarak karşılığı; IF TUS0=0 THEN TOGGLE LED0 idi.
Başka bir örnek , Şayet sayı=200 ise , sayı yı 0 (sıfır) yap şeklinde bir durum için;
IF SAYI=200 THEN SAYI=0 şeklinde bir komut kullanmalıyız.
IF komutu birden fazla şartlar içeren bir halka içinde kullanılabilir. Bu durumda komut önce THEN ile satır bitirilip diğer şartlar test edildikten sonra komut sonu ENDIF ile belirlenmelidir.
Örnek;
IF SAYI= 200 THEN
TOPLAM=25
X=0
ENDIF
IF satırı ile ENDIF satırı arasında başka IF lerde bulunabilir. Ama daima kural ilk giren son çıkar prensibine göre uygulama yapılmalıdır. Bunu da bir örnekle açıklamak uygun olacaktır.
IF SAYI=200 THEN
SAYI=0
IF X=100 THEN
SAYI=50
X=0
ENDIF ‘bu komut ile ikinci IF komutunu bitiriyoruz.
ENDIF ‘bu komut ile ilk IF komutunu bitiriyoruz.
İkinci kullandığımız komut TOGGLE komutudur. Bit bazında çalışan bir komuttur.
Her hangi bir bit değerini ters çevirmede kullanılır. Bit high ise Low , Low ise High yapar.
Programda Led örneğinde şayet Led yanıyorsa söndürür. Sönük ise yakar.
Bu komut Byte bazında kullanılmaz. Yani TOGGLE PORTB şeklinde bir ifade kullanamazsınız.
Kullandığımız diğer değişik komut WHILE – WEND komutudur.
While in kelime anlamı esnasında demektir. Kısaca bir durum esansında şunu yap şeklinde kullanılır. Örneğin Tuş=0 iken Led yanık olsun demek için;
WHILE TUS=0
HIGH LED ‘TUS=0 olduğu müddetçe program bu satırı icra eder.
WEND
LOW LED ‘TUS=1 olunca program bu satıra atlar ve LED söner.
İfadesini kullanmak gerekir. Wend, While komutunun bitiş yerini belirlemek için kullanılır.
Bizim örneğimizde;
WHILE TUS0=0
WEND
Yazarak aslında TUS=0 iken hiçbir iş yapma sürekli tuşa bak anlamında bir komut icra edilir. Zira While – Wend arasına hiçbir komut yazmadık. Dolayısıyla Program Tus=0 mı diye bakar. Tus=0 ise alta geçer burada hiçbir komut yok. Wend’e gelir ve bunu görünce tekrar Tus=0 mı diye bakar.
Bu olay Tus=1 oluncaya kadar devam eder. Yani Tus=0 olduğu müddetçe program WHILE WEND döngüsü içinde bekler.
İkinci Program örneğimizde LCD Kullanacağız.
Proje 4b: 

resim

Bu örneğimizde PortB ye LCD bağlayacağız. PortA.0 ve PortA.1 pinlerine Pull-Up yapılmış iki tuş bağlayacağız. PortA.0 daki tuş Yukarı , PortA.1 deki tuş ise Aşağı tuşu olarak çalışacaktır. Başlangıçta Ekranda Sayı adı altında bir değişken’ verilen sıfır değeri görülecek ve yukarı tuşuna basılınca sayı bir artırılacaktır. Aynı şekilde Aşağı tuşuna basılınca sayımız bir azaltılacaktır.
Sayıların artırılma ve eksiltme durumlarında maksimum ve minimum değerlerinden sonra aldıkları değerleri görerek öğrenmeniz için sayı değişkeni için bir sonlandırma fonksiyonu kullanılmayacaktır. Şimdi Programımıza geçelim.

‘****************************************************************
‘* Name : TUSBAS.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 07.04.2005 *
‘* Version : 1.0 *
‘* Notes : *
‘****************************************************************
TrisA=255
Trisb=0
‘—————————————————————–
@ DEVICE pic16F628 ‘işlemci 16F628
@ DEVICE pic16F628, WDT_ON ‘Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Protek kapalı
@ DEVICE pic16F628, MCLR_ON ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘——————————————————————-
DEFINE LCD_DREG PORTB ‘LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT 4 ‘LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_RSREG PORTB ‘LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 1 ‘LCD RS bacağı Hangi Bite bağlı ?
DEFINE LCD_RWREG PORTB
DEFINE LCD_RWBIT 2
DEFINE LCD_EREG PORTB ‘LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 3 ‘LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_BITS 4 ‘LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES 2 ‘LCD Kaç sıra yazabiliyor
‘——————————————————————-
CMCON=7 ‘16F628 de komparatör pinleri iptal hepsi giriş çıkış
OPTION_REG.7=1 ‘portB deki dahili PULL-UP lar iptal edildi.
‘——————————————————————-
SYMBOL YUKARI=PORTA.0
SYMBOL ASAGI=PORTA.1
SAYI VAR BYTE
‘——————————————————————-
LOW PORTB.2
SAYI=0
PORTB=0
LCDOUT $FE,1
PAUSE 200
‘——————————————————————-
BASLA:
IF YUKARI=0 then SAYI=SAYI+1
IF ASAGI=0 THEN SAYI=SAYI-1
‘ LCDOUT $FE,1,” SAYI = “,#SAYI
LCDOUT $FE,2,” SAYI = “,DEC3 SAYI
LCDOUT $FE,$C0, ” LCD ORNEK PROG.”
PAUSE 100
GOTO BASLA
END
Yukarıdaki örnekte LCDOUT $FE,2,” SAYI = “,DEC3 SAYI şeklinde bir komut satırı görüyoruz. Ekranda sayı gösterimine örnek olması açısından bu satır bir önceki ile alternatifli olarak koyulmuştur. Burada DEC3 komutu sayı değerinin 3 hane olarak ekrana geleceğini göstermektedir. 3 hane olmayan sayılarda hane sayısını doldurmak için 0 kullanıldığını daha önce söylemiş idik.
Bir satırın başına koyulan tek tırnak satırın k
omut olarak icrasını önler. Genellikle açıklama satırları bu şekilde verilir ve derleyici tarafından
değerlendirilmezler.
Programda önce Yukarı tuşuna basılarak sayı artırılmalı sonra Aşağı tuşuna basılarak sayı azaltılmalıdır. Sayı 0’a
ulaştığında azaltmaya devam edilir ise geriye doğru 255’e dönüldüğü ekrandan izlenmelidir. Aynı şekilde 250 den yukarı doğru sayıyı artırırsanız 255’e kadar gelinip 255 den sonra 0 a geçildiği yine ekrandan izlenmelidir.
Bundan sonraki örneğimiz 2X16 LCD kullanarak Ekran Mönüsü oluşturma ile ilgili olacaktır.
Genellikle Mönü ler bir den fazla seçenekli işlerde kullanılmaktadır.
Şimdi kendimize bir örnek belirleyelim ve bunu program şekline getirelim.
Diyelim ki Yine bir ısı kontrol programı yapıyoruz. Program bir evin ortam ısısını kontrol edecek. Kendimiz bir set değeri tayin ediyoruz ve bu işi hem gündüz hem de gece için ayrı yapıyoruz. Gerekçemizde gece oda sıcaklıklarının gündüze göre birkaç derece daha düşük olması.
Şimdi yazacağımız program Ekrana önce bir seçenek getirecek Gündüz veya Gece. Bunlardan birini seçtikten sonra seçtiğimiz şayet Gündüz ise Gündüz Sıcaklığı Set etme bölümüne , seçimimiz şayet Gece ise Gece Sıcaklığı Set etme bölümüne geçecek ve sıcaklık değerini ayarlayıp programdan çıkacağız. Tabii ki normal çalışma modunda ekranda yalnızca ortam sıcaklığını göreceğiz. Şayet seçim tuşuna basarsam mönü ye gireceğim.
Proje 4c : 

resim

A portuna 3 adet tuş bağlı olacak.Pull-Up’lı olarak PortA.0 da Seçim tuşu, PortA.1 de Yukarı tuşu (+) ve PortA.2 de ise Aşağı tuşu (-) yer alacak. Yine PortB de 2×16 LCD bağlı olacak ve işlemcimiz 16F628 olacaktır.

İşte Programımız ve açıklamaları;
‘****************************************************************
‘* Name : MENU.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 07.04.2005 *
‘* Version : 1.0 *
‘* Notes : *
‘****************************************************************
TrisA=255
Trisb=0
‘—————————————————————–
@ DEVICE pic16F628 ‘işlemci 16F628
@ DEVICE pic16F628, WDT_ON ‘Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Protek kapalı
@ DEVICE pic16F628, MCLR_ON ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘——————————————————————-
DEFINE LCD_DREG PORTB ‘LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT 4 ‘LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_RSREG PORTB ‘LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 1 ‘LCD RS bacağı Hangi Bite bağlı ?
define LCD_RWREG PORTB
define LCD_RWBIT 2
DEFINE LCD_EREG PORTB ‘LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 3 ‘LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_BITS 4 ‘LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES 2 ‘LCD Kaç sıra yazabiliyor
‘——————————————————————-
CMCON=7 ‘16F628 de komparatör pinleri iptal hepsi giriş çıkış
OPTION_REG.7=1 ‘portB deki dahili PULL-UP lar iptal edildi.
‘——————————————————————-
SYMBOL SEC=PORTA.0
SYMBOL YUKARI=PORTA.1
SYMBOL ASAGI= PORTA.2
ISIGUN VAR BYTE ‘gündüz ısı değeri
ISIGECE VAR BYTE ‘ gece ısı değeri
ISIODA VAR BYTE ‘oda sıcaklığı
‘——————————————————————-
LOW PORTB.2
ISIGUN=22
ISIGECE=18 ‘Bunlar default değerler olacak
ISIODA= 21
PORTB=0
LCDOUT $FE,1
PAUSE 200
‘——————————————————————-
BASLA:
LCDOUT $FE,1,” SEC => MENU ” ‘Menu ye nasıl girileceği açıklanıyor
BIR:
LCDOUT $FE,$C0,”ODA SICAKLIGI=”,#ISIODA ‘ODA sıcaklığını ekrana getiriyoruz.
PAUSE 150
IF SEC=0 THEN MENU ‘Şayet SEC tuşuna basılırsa Menu ye git
GOTO BIR ‘Tekrar başa git.
MENU:
LCDOUT $FE,1, “GUNDUZ => YUKARI”
IKI: LCDOUT $FE,$C0,”GECE =>ASAGI BAS”
PAUSE 200
IF YUKARI=0 THEN GUNDUZ ‘Yukarı tuşuna basılırsa GUNDUZ ’e git.
IF ASAGI=0 THEN GECE ‘Aşağı basılırsa GECE’ ye git.
IF SEC=0 THEN BASLA ‘Tekrar SEC tuşuna basılırsa Başla’ ya git
GOTO IKI
GUNDUZ:
LCDOUT $FE,1, “GUNDUZ SET DEGER”
UC: LCDOUT $FE,$C0,”ISIGUN = “,#ISIGUN ‘Gündüz Set sıcaklığı ekranda
PAUSE 200
IF YUKARI=0 THEN ‘Yukarı tuşuna basılınca
ISIGUN=ISIGUN+1 ‘Gündüz Set bir artırılıyor
IF ISIGUN>50 THEN ISIGUN=50 ‘50 ye ulaşınca 50 de kalıyor
ENDIF
IF ASAGI =0 THEN ‘Aşağı tuşuna basılınca
ISIGUN=ISIGUN-1 ‘Sıcaklık bir eksiltiliyor
IF ISIGUN=255 THEN ISIGUN=0 ‘255 e ulaşınca sıfıra eşitleniyor
ENDIF
IF SEC=0 THEN BASLA ‘Sec tuşuna basılınca başa gidiliyor.
GOTO UC
GECE:
LCDOUT $FE,1, ” GECE SET DEGER ”
DORT: LCDOUT $FE,$C0,”ISIGECE = “,#ISIGECE
PAUSE 200
IF YUKARI=0 THEN
ISIGECE=ISIGECE+1
IF ISIGECE>50 THEN ISIGECE=50
ENDIF
IF ASAGI =0 THEN
ISIGECE=ISIGECE-1
IF ISIGECE=255 THEN ISIGECE=0
ENDIF
IF SEC=0 THEN BASLA
GOTO DORT
END

Bu programla ilgili ilave bazı açıklamalar yapmak mantığını anlamak açısından yararlı olacaktır.
Görüldüğü üzere 2 satır 16 karakter bir ekran sınırları içinde birkaç kademeli bir menü düzenlenmiştir.
Programın baş tarafında yer alan ifadelerin açıklaması daha önce yapılmış idi. Bu nedenle açıklamamıza BAŞLA etiketinden itibaren yapacağız.
Başla etiketinden sonra hemen ekrana
LCDOUT $FE,1, ” SEC => MENU ” komutu ile Mönü ye geçmek için SEC tuşuna basılacağı açıklanıyor. Dikkat edilir ise LCDOUT $FE,1 komutu kullanılarak önce ekran tamamen siliniyor arkasından Menu açıklaması veriliyor. Bu satır yalnızca bir defa icra edileceğinden ekranın tamamen silinmesi doğru olmaktadır. Aksi taktirde bir önceki ekrandan bazı karakterler ekranda kalabilir.
Altında BIR: etiketi ile birlikte
LCDOUT $FE,$C0, “ODA SICAKLIGI=”,#ISIODA komutu ile Oda sıcaklığını veriyoruz.
Mönü’nün ilk kısmını oluşturan bu bölümde oda sıcaklığı ölçülerek ekrana getiriliyor ve kullanıcı isterse set sıcaklıklarını ayarlamak üzere bir alt mönüye geçebiliyor. Bunun için SEC tuşuna basması yeterli oluyor.
Bu konumda SEC tuşuna basıldığı zaman programda yer alan;
IF SEC=0 THEN MENU
Satırı sayesinde program MENU isimli etikete atlıyor. Burada
LCDOUT $FE,1, “GUNDUZ => YUKARI”
Komutu ile önce ekran siliniyor ve daha sonra Yukarı tuşuna basılırsa Gündüz mönüsüne gidileceği açıklanıyor. Bu satırın altında;
LCDOUT $FE,$C0,”GECE =>ASAGI BAS”
Komutu ile Aşağı tuşuna basılırsa da Gece mönüsüne gidileceği açıklanıyor.
Doğal olarak bu satırların altında da hangi tuşa basıldığını kontrol eden bir bölüm yer alıyor.
İşlem gayet basit. Yukarı tuşuna basılırsa GUNDUZ isimli etikete git;
IF YUKARI=0 THEN GUNDUZ
Aşağı tuşuna basılırsa GECE isimli etikete git;
IF ASAGI=0 THEN GECE
Şeklinde komutlar veriliyor. Tabii ki tüm bu işlemler bittikten sonra programın asıl çalışan bölümüne gitmek içinde SEC tuşunu devreye sokuyoruz. SEC tuşuna basılması halinde ise program tekrar en başa atlıyor.
BU aşamada yalnızca Gündüz etiketi altında ne yapılıyor açıklamak istiyorum. Zira Gece etiketinde yapılanlar gündüzden çok farklı değil. Birisini anlarsanız diğerini anlamanız zor değil.
Gündüz etiketi altında önce Gündüz set
değeri ekrana verilip aşağı veya yukarı tuşlarından birisine basmanız bekleniyor. Ya da SEC tuşuna basıp tekrar program başına geçmeniz bekleniyor.
Yukarı tuşuna basmanız halinde Set sıcaklığı bir artırılıyor. Ancak Artırılan sı
caklığın 50 dereceyi geçmesi istenmediğinden şayet geçerseniz sıcaklık yine 50 ye eşitleniyor. Bu bir kısıtlama veya sınırlandırma halidir.
Aynı şekilde Aşağı tuşuna basılması halinde sıcaklığın değer bir eskitiliyor ve sıfır değeri geçilip 255’e ulaşıldığında sıcaklık tekrar sıfıra eşitleniyor. Daha önce görmüş idik. Sayıları birer eskiterek gidersek. Sıfırdan sonra tekrar 255 geliyor idi.
Bu kadar örnek verdikten sonra Micro Code Studio (MCS) ile nasıl program derlenip Hex dosyası elde ediliyor birazda ona değinelim.
Bildiğiniz gibi Pic gibi mikro işlemciler yazılan programları icra ederler. Bunun için yazılan programların Pic’ kayıt edilmesi (yazılması) gerekir. Basic de yazılan programlar direkt olarak Pic’e yazılamaz. Bas uzantılı olan bu dosyaların önce makine diline çevrilerek Pic ’in anlayacağı biçime dönüştürülmesi gerekmektedir. Derleme denilen bu işlem MCS tarafından PBP derleyicisi kullanılarak yapılmaktadır. Derlendikten sonra Hex formatına dönüştürülen programın daha sonra yine başka bir program ve bir programlayıcı devre yardımı ile Pic’e aktarılması yani yazılması sağlanır. Hem program yazma ve hem de derleme işlemi için Micro Code Studio (MCS) programı kullanılmaktadır.

MCS ilk defa kurulurken bazı parametrelerin ayarlanması gerekiyor. Bunların başında PBPro klasörünün MCS ye gösterilmesi gerekmektedir. Bu iş için MCS de View mönüsünden Pic Basic Options alt mönüsü seçilir. Bu mönüde PBP nun yeri programa gösterilir.
Aynı şekilde Programlayıcı nın yeri ve parametreleri de bu seçenekte MCS ye gösterilir.
Bu işlemlerin yapıldığını kabul ederek derlemenin nasıl yapıldığına bakalım.
Programı yazmayı tamamladıktan sonra ekranın üst tarafında bulunan derle tuşuna (bir sayfa ve üzerinde sağa doğru ok olan tuş) tıklanır ise yazmış olduğunuz derlenir ve BAS uzantılı dosyanızın yer aldığı klasör içine aynı isimle ancak Hex uzantılı olarak kayıt edilir.
Dosyanın derlendikten sonra Pic’e yazılması için programlayıcıyı çalıştırmak gerekir. MCS bunu da otomatik yapabilir. Yine ekran üstünde üzerinde aşağı doğru ok bulunan bir entegre resmi göreceksiniz buda derlemeden sonra programlayıcıyı çalıştıran tuş dur. Bu tuşa basılınca önce program derlenir ve ardından program otomatik olarak programlayıcıya (IC-Prog) yüklenerek programlayıcı çalıştırılır. Size yalnızca programla tuşuna basarak Hex dosyasının Pic’e yazdırılması kalır.
MCS içinden IC-Prog gibi programlayıcıların otomatik çalıştırılması için bazı parametrelerinde ayarlanması gerekir. Bunların nasıl yapıldığı HEM MCS help mönüsünde hem de programlayıcıların açıklamalarında yer almaktadır. Bu bilgiler kullanılan programa göre değiştiğinden ve hepsini burada açıklamamız mümkün olmadığından yalnızca ön bilgi vermekle yetineceğiz.

Pic’e yazma ve Pic den okuma işlemlerinde en çok kullanılan program olan IC-Prog hakkında da biraz bilgi vermek isterim. IC-Prog hem seri porttan hem de paralel porttan çalışan programlayıcılarla uyumlu bir programlayıcıdır. Kullanımı son derece basittir. Gerekli parametreler ayarlanıp donanım seçimi de doğru yapılırsa sorunsuz olarak çalışacaktır.

Programı kullanırken dikkat edilmesi gereken en önemli nokta programlama yaparken veya programlama yaptıktan sonra doğrulama işleminin yaptırılmasıdır. Genelde hata veriyor diye bu işlem iptal edilmektedir. Hatalı yapılan bir işlemi kontrol etmez iseniz hatalı olduğunu nasıl anlayacaksınız. Hata var ise gösterilmesinde fayda vardır. Bu nedenle Seçenekler mönüsünden Programlanıyor alt mönüsünde bulunan kutucukların ikisini de veya en az birini işaretlemekte fayda vardır.

www.picproje.com ‘dan alıntıdır.

Pic Basic Öğreniyorum-3

Ders 3
LCD Kullanımı:
Yazığımız programlardan elde edeceğimiz neticeleri görsel olarak takip edebilmek amacı ile Pic’lere muhtelif büyüklüklerde LCD ekranlar
bağlandığını biliyorsunuz. Şimdi Pic ile LCD kullanımı konusunda detaylı bir uygulama yapacağız ve LCD kullanımını her yönü ile öğreneceğiz.

Önce biraz LCD leri tanıyalım. Bu konuda en çok kullanılan LCD 2 sıra ve her sırada 16 karakter yer alan LCD ler kullanılır. Bunların 4 sıralı
olanları olduğu gibi her sırada karakter adedi 40 ‘a kadar olanlarda mevcuttur.

LCD ler standart olarak 14 bacaklı (pinli) ekranlardır. Bacak numaralarına göre fonksiyonları aşağıda belirtilmektedir. 

resim

Nolu Pin : GND bacağıdır.
+5V giriş bacağı
Kontrast ayara bacağı olup genelde 22 K lık trimpot’un bir bacağı GND ye diğer uç bacağı +5V’a ve orta bacağı da bu kontrast bacağına
bağlanarak trimpot ile ekran koyuluk açıklık ayarı yapılır.
RS – Reset Bacağı
R/W yazma okuma set etme bacağı.
E – Enable bacağı.
D0 – Data Bacağı sıfır nolu bit.
D1 – Data Bacağı 1 nolu bit.
D2 – Data Bacağı 2 nolu bit.
D3 – Data Bacağı 3 nolu bit.
D4 – Data Bacağı 4 nolu bit.
D5 – Data Bacağı 5 nolu bit
D6 – Data Bacağı 6 nolu bit
D7 – Data Bacağı 7 nolu bit.
Bazı modellerinde 15. ve 16. cı bacaklarda mevcuttur. Bunlar back light denilen arkadan ekran aydınlatması için kullanılan Led ışığının voltaj
besleme uçlarıdır. Bu uçlar ayrı verildiği gibi 15 ve 16. cı bacaklar olarak da verilebilir.

LCD nin kullanımı ile ilgili protokol’e biz burada girmeyeceğiz. Bu işi bize BASIC yapacak. Yalnızca LCD nin 8 adet (8 bitlik) Data giriş bacakları
olduğunu ve istenirse LCD ile 8 yerine 4 bit üzerinden haberleşme yapılabileceğini belirtmek istiyorum. Aslında 8 bit’in tek seferde verilmesi
yerine ince ilk 4 bit sonrada ikinci 4 bit verilerek 8 bitlik bilgi tamamlanmaktadır ve bu işi yine BASIC yapmaktadır. Faydası ile 8 adet yerine
4 adet Data bacağı kullanarak Pic’de bize 4 adet fazladan bacak bırakmasıdır ve bu yüzden kullanım açısından daima tercih edilmektedir.

LCD nin Pic ile birlikte kullanılması için bazı kurallar vardır. Bunların başında DEFINE komutu gelmektedir. Bu komut LCD nin hangi porta bağlı,
Kaç data bacağı kullanıyor gibi bilgileri Pic’e vermekte kullanılır.

Kısa bir örnekle açıklayalım.

Vereceğimiz örnekte LCD tanımlama için kullanılması gereken tüm DEFINE komutlarını ve ne amaçla kullanıldıklarını göreceksiniz.

DEFINE LCD_DREG PORTB ‘LCD data bacakları hangi porta bağlı?
Bu örnekte LCD Data bacaklarının PortB ye bağlı olduğu belirtiliyor.
DEFINE LCD_DBIT 4 ‘LCD data bacakları hangi bitten başlıyor?
Bu örnekte Data bacaklarının PortB nin 4. bitinden itibaren başladığı belirtiliyor.
DEFINE LCD_EREG PORTB ‘LCD Enable Bacağı Hangi Porta bağlı?
Bu örnekte LCD Enable bacağının PortB ye bağlı olduğu belirtiliyor.
DEFINE LCD_EBIT 3 ‘LCD Enable Bacağı Hangi bite bağlı ?
Bu örnekte LCD Enable bacağının PortB.3 (3.bit) e bağlı olduğu belirtiliyor.
DEFINE LCD_RWREG PORTB ‘LCD RW Bacağı PortB de bağlı
Bu örnekte LCD RW bacağının PortB de bağlı olduğu belirtiliyor.
DEFINE LCD_RWBIT 2 ‘LCD RW Bacağı 2. bite bağlı
Bu örnekte LCD RW bacağının 2 bite bağlı olduğu belirtiliyor.

Şayet LCD den geriye karakter okuması yapılmayacak ise RW bacağı daima GND ye bağlı durabilir. Bu durumda 1 bacaktan tasarruf edilebilir.
İleride buna ait örnekler görülecektir. Burada komutun anlaşılması için biz bu bacağı da PortB ye bağlı kabul edeceğiz.

DEFINE LCD_RSREG PORTB ‘LCD RS Bacağı Hangi Porta bağlı ?
Bu örnekte LCD RS bacağının B portuna bağlı olduğu belirtiliyor.
DEFINE LCD_RSBIT 1 ‘LCD RS bacağı Hangi Bite bağlı ?
Bu örnekte LCD RS bacağının PortB.1 (1. bit) e bağlı olduğu belirtiliyor.
DEFINE LCD_BITS 4 ‘LCD 4 bit mi yoksa 8 bit olarak bağlı?
Bu örnekte LCD nin PortB ye kaç data bacağı ile bağlandığını açıklıyor.
DEFINE LCD_LINES 2 ‘LCD Kaç sıra yazabiliyor
Bu örnekte LCD nin Kaç sıra çalıştığı açıklanıyor.

Standart kullanımlarda buraya kadar olan DEFINE tanımlamaları yeterlidir. Ancak bazen yüksek frekanslı 10 MHz ve üzeri çalışma
frekanslarında LCD ekranına yazılan karakterler hızdan dolayı izlenemez hale gelebilirler. Bunu önlemek için gerek komut verildikten
sonra ve gerekse DATA verildikten sonra standart bir bekleme süresi tanımlanır ve karakterler izlenebilir hale gelir.

Bu komutlarda sırası ile

DEFINE LCD_COMMANDUS 1000 ‘1000 değer mikro saniye cinsinden gecikme süresi olup isteğe bağlı olarak artırılıp azaltılabilir.
Komut sonrası gecikme süresini belirler.
‘DEFINE LCD_DATAUS 225 ‘Data bilgisinden sonraki gecikmeleri tanımlar.

Buraya kadar verdiğimiz örneklerle LCD nin Pic’e bağlantısını tanımlamış olduk.
Program içinde LCD nin kullanımına ait bazı açıklamaları verdikten sonra örnek programımıza geçeceğiz.

LCD ye bir bilgi (emir) veya Data (karakter) göndermek için kullanılan komut;

LCDOUT dır. Bu komut şayet LCDOUT $FE eklentisi ile birlikte kullanılır ise LCD ye bir komut gönderileceği anlamına gelir.
Örneğin Ekranın silinmesi için LCDOUT $FE,1 komutunu verdiğimizde tüm ekrandaki bilgiler silinir. Program içinde sıklıkla
kullandığımız bazı komutlar vardır. Bunlar, Yazma konumunu (imleç in yeri) ekranın en başına almak LCDOUT $FE,2 ,

Yazma konumunu (imleç in yerini) İkinci satır başına almak için LCDOUT $FE,$C0 gibi komutlar verilir. Ayrıca yazma konumunu
ekranın herhangi bir yerine almak için ekran adresi kullanılır.

İlk satır birinci karakterin adresi $80, ikinci karakterin adresi $81, ve 7. karakterin adresi ise $86 dır. İkinci sırada bu adresler ilk
karakter için $C0, ikinci için $C1 ve sırası ile $C2-$C3-$C4… şeklinde gitmektedir. Örnek olarak ilk sıra 7. karakterden
itibaren “MERHABA” yazmak istersek şu komutu vermeliyiz.

LCDOUT $FE,$86,”MERHABA”

Öğrendiklerimizi artık bir programla kullanalım isterseniz.

Örnek Program 3a:

Ekranda ilk satırdan itibaren “BASIC DERSLERI” yazıp ikinci satıra ise “DERS No:3” ifadesini yazabileceğimiz programı gerçekleştirelim.
Mikroişlemcimiz yine 16F84 olsun. LCD B portuna bağlı olacak ve 4 bit data bağlantısı olacaktır. Enable pini 3 nolu bit’e , R/ W pini
2 nolu bit’e ve RS pini ise 1 nolu bite bağlı olacaktır. İşte Programımız.

DEFINE LCD_DREG PORTB ‘LCD data bacakları PortB de bağlı
DEFINE LCD_DBIT 4 ‘LCD data bacakları 4. bitten başlıyor
DEFINE LCD_EREG PORTB ‘LCD Enable Bacağı PortB de bağlı
DEFINE LCD_EBIT 3 ‘LCD Enable Bacağı 3. bite bağlı
DEFINE LCD_RWREG PORTB ‘LCD RW Bacağı PortB de bağlı
DEFINE LCD_RWBIT 2 ‘LCD RW Bacağı 2. bite bağlı
DEFINE LCD_RSREG PORTB ‘LCD RS Bacağı PortB de bağlı
DEFINE LCD_RSBIT 1 ‘LCD RS bacağı 1. Bite bağlı
DEFINE LCD_BITS 4 ‘LCD 4 bit olarak bağlı
DEFINE LCD_LINES 2 ‘LCD 2 sıra olarak çalışıyor.
TRISA=0 ‘A portu çıkış olarak ayarlandı.
TRISB=0 ‘B portu çıkış olarak ayarlandı.
LOW PORTB.2 ‘RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı.
PAUSE 200 ‘ LCD nin kullanıma hazır hale gelebilmesi için gerekli süre
LCDOUT
$FE,1 ‘Önce Ekranı siliyoruz.
LCDOUT “BASIC DERSLERI” ‘ilk sıra baştan itibaren yazdırıyoruz. Aslında bu komutu başka bir şekilde de yazabiliriz, şöyle
‘ LCDOUT $FE,2,”BASIC DERSLERI”
LCDOUT $FE,$C0,”DE
RS No: 3” ‘ikinci satıra yazdırıldı.
End ‘Program sonu
Aynı programı RW bacağını direkt GND ye bağlıyarak da çalıştırabiliriz. Bu durumda ;
LOW PortB.2 komutuna ihtiyaç yoktur.
Devre Şeması : 

resim

Ekran kullanımında en çok karşılaşılan şekillerden birisi sabit bir karakter dizisinden sonra bir değişkene bağlı olarak değer gösterme
işi dir. Diyelim ki ortam sıcaklığını ölçüyorsunuz ve bunu ekranda gösteriyorsunuz.

Bu durumda ekranda “SICAKLIK : 23,3 oC” ibaresine benzer bir görüntü olacaktır. Genelde 23 değeri bir değişkende tutulur ve 0,3 değeri
ise ayrı bir değişkende tutulur. Şimdi ISI=23 ve ONDA=3 olduğunu kabul ederek bunun ekranda gösterilme şeklini inceleyelim.

LCDOUT “SICAKLIK :” komutu ekrana SICAKLIK : ibaresini yazacaktır.

Devamı için LCDOUT “ SICAKLIK : “,#ISI şeklinde bir ifade yazılır ise;
Ekrana çıkan şekli < SICAKLIK : 23 > olacaktır. Geriye ondalık kısmını yazdırmak kalıyor.
Bunun için LCDOUT “SICAKLIK : “,#ISI,”,”,DEC1 ONDA ifadesini yazmamız gerekiyor.
#ISI komutundan sonra gelen virgül peşine ikinci bir komut geleceğini gösteriyor. Arkasında yer alan “,” ifadesi ekrana 23 rakamından sonra bir
virgül koyacaktır. Peşinden gelen DEC1 ise sonraki gelen ifadenin Desimal bir sayı olduğunu ve 1 hanesinin yazılacağını gösterir. Daha sonraki
ise zaten ONDA değişkeni olup 3 sayısını tutmaktadır. Sonuç olarak ekranda;
SICAKLIK : 23,3 olarak görülür.
Bu ifadelerin devamına derece işareti ve C karakterini ilave edince işlem tamam olacaktır. Ancak LCD karakterleri içinde derece işareti yoktur.
Bunun nasıl oluşturulduğunu ileride göreceğiz. Şimdilik yalnızca C karakterini koymaya çalışalım. Komutun tamamı;

LCDOUT “SICAKLIK : “,#ISI,”,”,DEC1 ONDA, “ C” şeklinde verilir.

Ekranda gösterilecek sayı formatlarını verdikten sonra ikinci örneğimize geçeceğiz.
Sayılarımız Desimal , Hexadesimal ve Binary olarak gösteriliyorlardı.
Bunları LCD de göstermek için aşağıdaki formatları kullanıyoruz.

Desimal Sayılar :
Sayıyı direkt olarak göstermek için başına # ilave edilir. #ISI gibi.
Çok haneli sayılarda hane sayısını kısıtlamak için DEC komutu kullanılır. DEC1 tek hane, DEC2 iki hane DEC3 üç hane gösterir. Olmayan
haneler yerine akrana sıfır çıkar. Örneğin ISI=23 ise ve biz ekrana DEC3 ISI yazmış isek ekrandaki görüntüsü 023 olarak izlenir.

HEX Sayılar.:
Değişken veya sayı başına HEX veya HEX1 veya HEX2 gibi ifadeler yazılır. Rakamlar gösterilecek hane sayısını ifade etmektedir.

Binary Sayılar:
Binary sayılar başların BIN (veya BIN1-BIN2 – BIN3..) ifadesi koyularak gösterilirler.

Proje 2b :

Bu örneğimizde değişkenlere bağlı sayıların ekranda gösterilmesi konusunu işleyeceğiz.
16F84 işlemci ve 2X16 LCD kullanarak Bazı sayı formatlarını ekranda izleyelim.
Program önce bir SAYI değişkenini kullanacak ve sıfırdan başlayıp sayı değerini her seferinde bir artırarak oluşan yeni SAYI değerini üst
satırda Desimal alt Satırda Binary olarak gösterecek.
İkinci adımda ise Yine sıfırdan başlayarak bir SAYI değişkeni değeri 10’ar artırılacak ve elde edilen yeni değer üst satırda Desimal, alt
satırda ise HEX olarak gösterilecektir. İzleyelim.

DEFINE LCD_DREG PORTB ‘LCD data bacakları PortB de bağlı
DEFINE LCD_DBIT 4 ‘LCD data bacakları 4. bitten başlıyor
DEFINE LCD_EREG PORTB ‘LCD Enable Bacağı PortB de bağlı
DEFINE LCD_EBIT 3 ‘LCD Enable Bacağı 3. bite bağlı
DEFINE LCD_RWREG PORTB ‘LCD RW Bacağı PortB de bağlı
DEFINE LCD_RWBIT 2 ‘LCD RW Bacağı 2. bite bağlı
DEFINE LCD_RSREG PORTB ‘LCD RS Bacağı PortB de bağlı
DEFINE LCD_RSBIT 1 ‘LCD RS bacağı 1. Bite bağlı
DEFINE LCD_BITS 4 ‘LCD 4 bit olarak bağlı
DEFINE LCD_LINES 2 ‘LCD 2 sıra olarak çalışıyor.
TRISA=0 ‘A portu çıkış olarak ayarlandı.
TRISB=0 ‘B portu çıkış olarak ayarlandı.
SAYI VAR BYTE ‘Sayı değişkenini Byte olarak ayarladık . Maksimum 255 değeri
LOW PORTB.2 ‘RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı.
PAUSE 200 ‘ LCD nin kullanıma hazır hale gelebilmesi için gerekli süre
LCDOUT $FE,1 ‘ Ekran silindi
SAYI=0 ‘SAYI ilk değeri sıfır olarak verildi.

‘——————————-ANA PROGRAM BAŞLANGICI ———————————————

BASLA:
LCDOUT “ SAYI = “,#SAYI ‘ilk satıra Sayı Desimal olarak yazıldı
LCDOUT $FE,$C0,” Binary = “,BIN SAYI ‘ikinci sıraya Binary olarak yazıldı.
PAUSE 500 ‘500 ms bekliyoruz.
SAYI=SAYI+1 ‘SAYI bir artırıldı.
IF SAYI<100 THEN BASLA ‘SAYI mız 100 den küçük ise tekrar başla
‘bu satırda sayı=100 olacaktır . Burada sayı değişkenini tekrar sıfırlıyoruz.
SAYI=0
ARA: LCDOUT “ SAYI = “,#SAYI ‘ilk satıra Sayı Desimal olarak yazıldı
LCDOUT $FE,$C0,” Hex = “,HEX2 SAYI ‘ikinci sıraya Hex olarak yazıldı.
PAUSE 500
SAYI=SAYI+10 ‘Sayı değeri 10 artırıldı
IF SAYI<250 THEN ARA ‘sayı değeri 250 den küçük ise ARA’ ya git
END ‘SAYI=250 olunca programı bitir.
Bu kadar LCD bilgisi yeterli olur sanırım. Birazda özel karakterlerin yaratılması işini inceleyelim.

LCD lerde 8 adet yeni karakter yaratmamıza izin verilir. Karakterler 5 x 7 formatında oluşturulur ve 8 adet data halinde özel karakter
hafızasına yerleştirilirler. Normalde LCD de Türkçe karakterlerin olmadığını biliyorsunuz. İşte bu karakterleri toplam 8 adet olmak şartı
ile kendimiz oluşturup kullanabiliriz.

Önce özel karakter hafıza adreslerini verelim sonra karakterlerin nasıl yaratıldığını açıklayalım.

LCD de 1 . karaktere ait adresin başlangıcı $40 dır. Bu adresten itibaren sırası ile 8 adet adrese 8 bitlik karakter dataları yerleştirilir ise
bu karakterin numarası 0 (sıfır) olur ve datalara bağlı olarak yeni karakter ekranda gösterilir.

LCD de 2. karakter hafızası $48, üçüncü $50, dördüncü $58, beşinci $60, altıncı $68,
yedinci $70 ve sonuncu da $78 adresinde yer almaktadır. Oluşturulacak karakterler soldan sağa 5 ve yukardan aşağıya 7 olmak üzere 5X7
matriks te oluşturulmaktadır. Son data (8.ci) daima sıfırdır.

Şimdi ilk Türkçe karakterimizi oluşturalım. Oluşturacağımız karakter Ö harfi olacaktır. Önce kendimize 5 x 7 ebadında bir matriks çizelim.
Çizdiğimiz matriks içine ü harfini oluşturacak şekilde Kareleri kapatalım veya açalım. Sonuçta aşağıdaki sisteme göre dataların değerlerini
satır satır hesaplayalım. 

resim

Görüldüğü gibi 1 olan bitlere karşılık gelen bit değerleri soldan sağa doğru toplanarak o sıraya ait data elde edilmektedir. İşte ilk sıradaki
Binary değeri olan %10001 değeri nin Desimal karşılığı için 16 + 1 değerleri toplanarak 17 değeri bulunmaktadır.

İşte bu şekilde elde edilen datalar daha sonra programın başında bir yerde LCD ye verilir. Nasıl mı şöyle;
LCDOUT $FE,$40,0,17,0,17,17,17,31,0
Böylece sıfır nolu karakteri oluşturmuş oluyoruz. Data adedinin 8 adet olmasına dikkat ediniz. Son data daima sıfır olmalı.
Şimdi Derece işaretini oluşturalım
Hesapladığımız Data lar ise
LCDOUT $FE,$40, 6,9,9,6,0,0,0,0
Şeklinde olacaktır.
Şimdi Derece işaretini 1.
karakter olarak oluşturalım.
LCDOUT $FE,$48, 6, 9, 9, 6, 0, 0, 0, 0
Yeniden Karakter üretmeyi öğrendik. Şimdi bunların program içinde nasıl kullanıldıklarına bakalım.
Diyelim ki Sıcaklık göstergesi örneğim
ize geri dönelim ve ekrana;
SICAKLIK : 23,3 oC şeklinde bir ifade yazmaya çalışalım.
Derece işareti 1 nolu karakterimiz olduğunu varsayıyoruz.
Komut şöyle olacaktır;

LCDOUT “SICAKLIK : “,#ISI,”,”,DEC1 ONDA,” “,1,”C”

ONDA isimli değişkeni verdikten sonra tırnak içinde 2 karakterlik boşluk bırakıyoruz. Daha sonra virgül koyup 1 yani 1. karakteri yazdırıyoruz.
Sonra tekrar virgül koyup tırnak içinde C karakterini yazdırıyoruz.

Buradan şu sonuç çıkmaktadır. Oluşturulan karakterler ekrana karakter numarası ile getirilirler.
İkinci örneğimiz 0 (sıfır) nolu karakterimizi ilk satır 5. haneye yazdıralım.

LCDOUT $FE,$84,0

Buraya kadar LCD kullanımını her yönü ile öğrenmiş olduk. İleriki programlarımızda bol bol LCD kullanacağız ve bilgimizi geliştireceğiz.

www.picproje.com ‘dan alıntıdır.

Pic Basic Öğreniyorum-2

Ders-2:
———-
Bu dersimizde pic pinlerinin nasıl input yani giriş olarak ayarlandığını ve bu işlemin nerelerde kullanıldığını öğreneceğiz.
Hazırlanan programlarda pic in zaman zaman dış ortamdan bilgi alması ve bu bilgiye göre karar vermesi istenir.
Örnek olarak bir tuşa basılması halinde git şu işi yap şeklinde bir program en basitinden yazılabilir.
Yada bir anahtar kapalı ise bir iş yap. Aynı anahtar açık ise başka bir iş yap gibi.
Bir önceki dersimizde Port pinlerinin giriş olarak ayarlanması için Port’a ait TRIS yazmaç’ına 1 yani high verilmesi
gerektiğini öğrenmiş idik. Bu kaide her bir pin için gerekli. Portun tamamı giriş yapılacak ise 8 bitlik 255 ($FF – %11111111)
değerinin TRIS yazmacına verilmesi gerekir.Bir örnek programla bunu açıklayalım.
Varsayımlarımız; Pic’in PortB.0 pinine bir anahtar bağlı. Anahtar açık iken pin low da (pull down direnci ile) anahtar kapalı
iken pin High da olsun. Burada Pull down şeklinde bir terim geçiyor. Port pinlerinin sıfıra yani Low’a çekilebilmesi için pin ile
GND arasına 10K lık bir direnç bağlanır. Buna Pull-Down işlemi denir. Aynı işin tersi olarak Pin şayet 10K lık bir direnç ile +5V’a
bağlanır ise bu dirence de Pull-Up direnci denir.
Şimdi PortB.0 10K ile GND ye bağlı yani bu direnç ile sürekli LOW da tutuluyor. İki ucu olan Anahtarın bir ucu pin’e bağlı diğer
ucu da +5V’a bağlı olsun. Anahtarı kapadığımız zaman pin’e +5V yani High gelsin. Anahtarın durumunu bir LED ile izlemeye çalışalım.
Anahtar kapalı iken PortA.0′a 470 Ohm dirençle bağlı bir LED yansın. Anahtar açık iken Led sönsün.

İşte programımız ve açıklamaları;

Proje 2a : 

resim

TRISA=0 ‘A portu çıkış olarak ayarlandı
TRISB=%00000001 ‘B.0 pini giriş diğerleri çıkış olarak ayarlandı.
SYMBOL TUS= PORTB.0 ‘ PortB.0 pinine sembol ismi olarak TUS adı verildi.
SYMBOL LED= PORTA.0 ‘ PortA.0 pinine sembol ismi olarak LED adı verildi.
BASLA:
IF TUS=1 THEN ‘ Anahtar kapalı ise
HIGH LED ‘ LED’i yak
ELSE ‘ Değilse
LOW LED ‘ LED’i söndür
ENDIF ‘ IF sorgulaması sonu
GOTO BASLA ‘ BASLA isimli etikete git.
END
Bu programda bazı yeni komutlar gördünüz. Sırası ile inceleyelim.
Önce SYMBOL komutunu görelim. Bu komut tanımlanmış bir değişkeni başka isimle yeniden tanımlamak veya herhangi bir
port pinine bir isim vermek için kullanılır. Burada komutu port pinlerine isim vermek için kullandık. Aynı işi port pinini değişken
olarak tanımlayarak da yapabilirdik. Şöyle;

TUS VAR PORTB.0
LED VAR PORTA.0
şeklinde yapılan tanımlama fonksiyon olarak SYMBOL tanımlaması ile aynı işlevi görür.Burada VAR isimli bir ifade görüyorsunuz.
Sırası gelmişken bu ifadenin ne olduğunu açıklayalım.VAR İngilizce VARIABLE kelimesinden kısaltılarak türetilmiş olup
Türkçesi DEĞİŞKEN dir.
Program içinde değişken tanımlamanıza imkan tanır. Program içinde muhtelif değişkenler kullanılmaktadır. PBP genel olarak
5 tip değişken tanımlamanıza olanak tanır. Bunları örneklerle açıklayalım;
Bit tipi değişken;
TUS VAR BIT (veya TUS VAR PORTA.0) değişkenin boyutu bit dir.
BYTE tipi değişken;
AL VAR BYTE ,burada AL isimli değişken 8 bitlik bir değişken olup alabileceği en büyük rakam 255 değeridir.
Böylece bu değişken 0-255 arasında herhangi bir değer alabilir.
WORD Tipi Değişken;
TOPLAM VAR WORD , burada TOPLAM isimli değişken çift baytlık yani 16 bitlik bir değişken olup alabileceği rakam
değerleri 0 – 65535 arasında olacaktır.
Dizi Tipi Değişkenler ;
ISIM VAR BYTE [10] ‘isim adı altında 11 adet değişken tanımlar. Bu değişkenlere değişken numarası verilerek ulaşılabilir.
Sıralama sıfırdan başlar. Örneğin ISIM[4] beşinci değişken olmaktadır.
Son olarak Sabit değerli değişkenleri tanımlayacağız.
TA CON 3 ‘ Burada TA isimli değişkene 3 değeri sabit olarak verilmektedir. Program içinde bir daha değiştirilemez veya sadece
ilk tanımlandığı yerde değiştirilebilir.
Tekrar programımızdaki komutlara dönersek IF (Şayet veya Eğer) komutunu göreceğiz.IF komutu sorgulama yapılması gereken
veya şarta bağlı işlerde kullanılan bir komuttur.Şayet PORTA.0 pini Low ise PORTB.0 daki Led yansın şeklinde bir şarta bağlı bir
işlemin program halinde yazılımı şu şekilde olacaktır;
IF PortA.0=0 then HIGH PortB.0
IF komutunun içinde kullanılan birde ELSE isimli ilavesi vardır. Bu komut birinci şart doğru değilse ikinci şart olarak kullanılır.
Şayet PORTA.0=0 ise LED’i yak değil ise (yani PortA.0=0 değil ise) LED’i söndür şeklinde verilen bir tanımlamayı program olarak
yazacak olur isek;
IF PORTA.0=0 THEN
HIGH LED
ELSE
LOW LED
ENDIF
Else komutunu kullanacağımız zaman mutlaka birinci satırda THEN den sonra bir şey
yazmamamız gerekir. (Yukarıda olduğu gibi) Devam eden ifade alta yazılır.
Yeni bir program yazacağız ve öğrendiğimiz yeni komutları bu programda kullanacağız.
Programın konusu şöyle;
Proje 2b: 

resim

- PortB.0 pinine bir Tuş bağlı ve Pull-Up yapılmış vaziyette. Yani pin sürekli High da duruyor. Tuşa basılınca LOW olacaktır.
- PortB.1 pinine bir Led bağlı.
- Tuşa basıldığı zaman LED yanacak , tuşa tekrar basıldığı zaman LED sönecek. Bir nevi on/off anahtar gibi çalıştıracağız tuşu.
Görüldüğü gibi yalnızca B portunu kullanıyoruz. Sıfır nolu pin (B.0) tuş bağlı olduğu için giriş olacak, bir nolu pin (B.1) ise
Led bağlı olduğu için çıkış olacak.
Şimdi programımıza geçelim ;
TRISB=%00000001
SYMBOL TUS=PORTB.0
SYMBOL LED=PORTB.1
BASLA:
IF TUS=0 THEN
IF LED=1 THEN
LOW LED
ELSE
HIGH LED
ENDIF
ENDIF
GOTO BASLA
END
Burada programı kısaltmak için başka bir komut kullanabiliriz. TOGGLE komutu. Toggle bit bazında
çalışan bir komut olup bit şayet 1 ise 0 yapar. Bit şayet 0 ise 1 yapar.
Aynı programı şimdi Toggle kullanarak yazalım;
Proje 2c : (şema 2b ile aynı)
TRISB=%00000001
SYMBOL TUS=PORTB.0
SYMBOL LED=PORTB.1
BASLA:
PAUSE 70
IF TUS=0 THEN TOGGLE LED
GOTO BASLA
END
Gördüğünüz gibi program bayağı kısaldı. Toggle komutu byte tipi değişkenlere tatbik edilmez. Örneğin TOGGLE PORTB
diyemeyiz. Ancak TOOGLE PORTB.2 diyebiliriz.
Biraz da matematik yapalım. Programlarda matematik dört işlem komutları normal matematik yapılır gibi kullanılmaktadır.
Gerektiğinde işlemler değişkenler yardımı ile de kullanılabilir.

Örnek vermek gerekir ise;
A=24
B=12
C=A+B şeklinde bir ifade kullanılabilir.
C=A-B veya C=A/B veya C=A*B şeklinde ifadeler kullanılabilmektedir.
Sonuçlar konusunda programcıların dikkatli olması gerekir. 8 bitlik değişkenler kullanılarak yapılacak hesapların sonuçları da
8 bit sınırı içinde olması gerekir. 8 biti aşan sonuçlar için WORD değişkeni kullanılmalı, 16 biti aşan hesaplamalarda ise bölme
için DIV32 komutu kullanılmalıdır. Bu konuda ileriki derslerimizde örnekler üzerinde çalışacağız.
Bu arada bit bazında yapılan işlemlerde bazı önemli noktalara işaret etmek istiyorum. Bir kısmı giriş bir kısmı çıkış ola
rak
ayarlanmış portlarda işlem yapmak genellikle problemlere sebep olur. Bu yüzden bit bazında yapılan işlemleri çok iyi öğrenmek gerekir.
Bunun için Mantıksal Operatörler (Logical Operators) konusunu inceleyeceğiz. Çoğunuzun
mantık konusunda bilgi sahibi olduğunu
düşünüyorum. Yinede mantık genel konularına burada değinmekte yarar var.
a) AND (ve) Operatörü:
——————————
Mantıksal operatörlerin anlaşılmasının en kolay yönlerinden birisi lamba devreleridir. İki adet anahtar ile bir adet lambayı
yakacağımızı düşünürsek, ve şart olarak da her iki anahtar kapalı olunca lamba yansın der isek bir AND işlemine
ihtiyacımız var demektir. Bu durumda eşitlik aşağıdaki gibi olmalıdır.
IF (SW-1=1) AND (SW-2=1) THEN HIGH LAMBA
bu eşitliğin mantık modeli ise 1 AND 1 = 1
olumsuz hali olarak 1 AND 0 = 0 yazılabilir.
Tabii ki 0 AND 0=0 olduğunu söylemeye gerek yok sanırım.
Lamba olayına geri döner isek, lambanın yanabilmesi için her iki anahtarın (1) yani kapalı olması gerektiği ortadadır.
Anahtarlardan birisi açık olur ise olumsuz hal meydana gelir ve lamba sönük kalır. AND operatörü bit bazındaki işlemlerde
genellikle aşağıdaki şekillerde kullanılır.

- 8 bitlik bir ifadeden bazı bitleri izole edip ayırmak için;
PORTB= %11100100 olsun ve bu bilginin ilk 4 adet bitini başka bir değişkene vermek isteyelim.
A=PORTB AND %00001111
A= %0100 olacaktır. yani ilk 4 adet bit A değişkenine eşitlenmiş olur. Temel kaide izole edilecek bitlerin tamamı 1 ile AND lenir.
- Yine 8 bitlik bir ifadede istenen bazı bitleri low yapmak için kullanılabilir.
PORTB=%11100100 olsun ve biz high olan 2 biti low yapmak isteyelim. İşte çözüm;
PORTB=PORTB AND %11111011
PORTB nin yeni değeri %11100000 olacaktır. Temel kaide low yapılacak bit sıfır diğer bitler 1 ile AND lenir.
b) OR (veya) Operatörü :
———————————-
Yine lamba devresini örnek verecek olursak, bir lambanın yanabilmesi için iki anahtardan birisinin kapalı olması yeterli ise
bu durumda karşımızda bir OR işlemi var demektir. Bunun şartlı ifadesi şöyledir;
IF (SW-1=1) OR (SW-2=1) THEN HIGH LAMBA mantık modeli ise
1 OR 1 = 1
1 OR 0 = 1
0 OR 1 = 1
0 OR 0 = 0
Or işlemi şartlı ifadelerde kullanılır. yukarıdaki lamba örneğinde olduğu gibi. Bundan daha fazla
olarak istenen bir bit’in high yapılmasında kullanılmaktadır. Örnek;
PortB=%11001100 ise ve 1. bit High yapılmak isteniyor ise;
PortB=PortB OR %00000010 şeklindeki ifade ile 1. bit High yapılır. Sonuç PortB=%11001110 olur.High yapılmak istenen
bit 1 diğerleri 0 ile OR lanır.
c) XOR (Özel Veya) :
—————————–
Genellikle bitleri ters çevirme işlemlerinde kullanılır. Mantıksal model şöyledir.
1 XOR 1 = 0
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
A=%11100011 , B=%01010101 olsun
C= A XOR B eşitliğine bakalım ve C nin alacağı değeri hesaplayalım
A= %11100011
B= %01010101
——–XOR ——
C= %10110110 sonucu elde edilecektir. Şimdi C nin bitlerini ters çevirmek istersek şöyle
yapılacaktır;
C=%10110110
%11111111
——XOR——-
C=% 01001001 görüldüğü gibi C nin yeni değeri öncekinin ters çevrilmiş halidir. Demek ki bir
sayının bitlerini ters çevirmek için o sayıyı tamamı 1 lerden oluşan bir sayı ile XOR lamak gerekir.Bir sayının yalnızca bir bitini
ters çevirmek için TOGGLE komutu kullanılmaktadır. Ancak aynı işi XOR ile de yapabiliriz.
A=%11111110 olsun bu sayının 7. bitini ters çevirecek olur isek
A.7=A.7 XOR %1 Bu durumda A sayısı %011111110 olacaktır.
Daha öncede belirttiğimiz gibi aritmetik işlemlerinde kullandığımız değişken tipine bağlı olarak işlem yapmaya dikkat etmeliyiz.
Özellikle vurgulamaya çalıştığım konu 8 bitlik sayılarla çalışırken elde edilecek neticenin de 8 bit sınırları içinde olmasına özen
göstermeliyiz. Şayet hesap sonucu 8 biti aşacak ise veya aşma ihtimali var ise mutlaka sonucu yerleştireceğimiz değişken
Word tipinde seçilmelidir.

www.picproje.com ‘dan alıntıdır.

Pic Basic Öğreniyorum-1

Ön Söz:
———- 
Pic Basic Pro programlama dilinin kullanımı ve komutları konusunda bilgiler vermek komutların
kullanım şekillerini açıklama ve sonuçta örnekler vererek yeni başlayanlara bu dili öğretmeyi amaçlıyorum.
Basic bilenler ise dersleri takip ederlerse bazı enteresan programlama teknikleri öğrenebilirler.
Zira Basic dili her ne kadar üniversal bir dil olsa da bazı komutlar akıllıca kullanılarak programlamada
karşılaşılan zorluklar kolaylıkla aşılabilir. 

Derslerimizde temel amaç örnekler vererek öğretmektir. Zira en iyi öğrenme yolu görsel olanıdır.
Sözü fazla uzatmadan derslerimize başlayalım.

Ders -1 :
———-
Pic Micro işlemciler hakkında kısa bilgi.
—————————————–
Pic mikro işlemciler teknik özellikleri ve kılıfları açısından farklılıklar gösterirler. Her şeyden önce birden
fazla bacağa (pin) sahip olan işlemcilerin bacakları giriş veya çıkış olarak çalıştırılabilirler. Özellikleri açısından
da bir kere programlanabilenler (C serisi) programları ultraviyole ile silinip yeniden programlanabilenler ve
birden fazla silinip programlanabilenler olarak sınıflandırılabilirler.

Biz genelde FLASH olarak tarif edilen birden fazla silinip programlanabilen tipler üzerinde çalışacağız.
Pic’ler taşıdığı ekstra özellikler açısından da bir kaç kategoriye ayrılırlar. Örnek olarak üzerin de;
1) Analog-Digital Çeviricisi olanlar,
2) Komparatör olanlar,
3) Donanımsal olarak seri haberleşme ünitesi olanlar,
4) HPWM ünitesi olanlar gibi Pic’ler mevcuttur. İleriki bölümlerde bunların kullanımına ait örnekler vereceğiz.

Pic işlemcilerin pinlerinin hem giriş hem de çıkış olarak çalıştırılabildiğinden bahsetmiş idik. Açıklamalarımızla
ilgili uygulamalarımıza “Proje” adını vereceğiz ve her projemizin bir numarası olacaktır. Şimdi Pic lerinin
organizasyonu işlemlerine kısa bir göz atalım.

Kullanacağımız Pic 16F84A olacak. Bu işlemcinin toplam 18 bacağı vardır.5 nolu bacak(-),ve 14 nolu bacak(+) besleme ,
15-16 nolu bacaklar (XTAL) osilatör bacakları ve PortA (0-4 arası 5 adet pin) < 17,18,1,2,3 nolu bacaklar > ve
PortB (0-7 arası 8 adet pin) <6,7,8,9,10,11,12,13 nolu bacaklar > olmak üzere toplam 13 adet (Giriş-Çıkış) pin’e sahip bir işlemcidir. 

resim

İlk projemize geçmeden, anlatımda lazım olacak olan BASIC de kullanılan sayı gösterim formatları konusunda
biraz bilgi vermek istiyorum. Bildiğiniz gibi kullanacağımız 3 tür sayı formatı vardır. Formatlar ve gösterim şekilleri
aşağıda verilmiştir.

1) Desimal Sayılar (10 tabanına göre düzenlenmiş sayılar):
direkt kullanılırlar 12 -23 gibi

2) Hexadesimal Sayılar (16 tabanına göre düzenlenmiş sayılar) :
başlarına $ işareti koyularak gösterilirler. $1F , $31 gibi

3) Binary Sayılar (2 tabanına göre düzenlenmiş sayılar) :
ise başlarına % işareti koyularak gösterilirler. %111000 , %0001 gibi.

Sıklıkla kullandığımız sayı sistemi desimal olduğundan diğer sayıların kolayca anlaşılabilmesi için zaman zaman
bu sayıların 10 tabanına çevrilmesi gerekir. Aşağıda bu işlemin nasıl yapıldığını basitçe göreceksiniz. Bu işlemde
temel formül; aynı on tabanına göre sayılarda olduğu gibidir. Sağdan sola doğru haneler sayı tabanının katları
şeklinde değer alırlar. Yani değişen tek şey taban çarpım değeridir. Örnekle daha iyi anlayacaksınız.

Hexadesimal sayılar :0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F: Örnek sayımız <3F> olsun. 16 tabanlı sayı formatı
olduğundan;16′lar hanesi olan 3 sayısı 16 ile çarpılıp F sayısının desimal karşılığı bu sayıya eklenir.
Dolayısıyla;3F = 3 x 16 + 15 = 63 olarak bulunur.
Şayet sayı 23F olsa idi sayımız= 2 x 256 + 16 x 3 + 15= 575 olarak bulunacak idi.

Binary sayılar; 0-1 , örnek sayımız %11101101 olsun. Hanelerin taban sayısının katları şeklinde gittiğini biliyoruz.
O halde sağdan itibaren ilk sayımız hane değerleri şöyle olacaktır. sayı sırasına göre verir isek
128 – 64 – 32 – 16 – 8 – 4 – 2 – 1
Bu sisteme göre sayımızı desimal değere çevirelim;
%11101101: 128×1 + 64×1 + 32×1 + 16×0 + 8×1 + 4×1 + 2×0 + 1= 128+64+32+8+4+1=237 olarak bulunacaktır.

En çok kullanacağımız sayı formatlarından birisi olan Binary sayı formatının kullanım yerine bir örnek vermek
bu aşamada iyi olacaktır sanırım. Bir Pic’in B portuna bağlı olan Led lerden 0-3-4-6-ve 7 nolu pinlere bağlı olanları
bir seferde yanar hale getirebilmek için porta verilecek değeri desimal olarak hesaplayalım. Bu durumda
PortB=%11011001 olacaktır.Desimal değeri = 128+64+16+8+1= 217 olarak bulunur.

İlk projemiz, 16F84A işlemcinin Tüm bacaklarını çıkış olarak ayarlamak ve bu çıkışlara bağlanacak LED lerin değişik
aralıklar ile yanmasını gösteren bir program olacaktır. Bu arada amaç, Pic lerin bacaklarının nasıl çıkış olarak
ayarlandığını öğrenmek olacaktır.

Pic lerde bacakların giriş veya çıkış olarak ayarlanmasını üstlenen bir REGISTER (Türkçe’si YAZMAÇ) vardır.
Her bir port için ayrı olan bu registerler A portu için TRISA , B portu için ise TRISB olarak adlandırılır. Tris yazmaçları aslında
Pic’in hafızasında 8 bitlik birer hafızadırlar. Buraya yerleştirilen sayının Binary formatındaki şekline bağlı olarak Pic bacaklarını giriş
veya çıkış olarak ayarlar.8 bitlik değer sırası ile port’a ait pinleri temsil etmektedir.

Şöyle ki;

A) %00000000, ifadesi 8 bitlik Binary bir sayıdır. Desimal karşılığı 0 (sıfır) dır. Bu değeri herhangi bir TRIS registerine verir isek
tüm pinlerin OUTPUT yani çıkış olarak ayarlanacağını ifade eder.

B) Şayet değer %11111111 olur ise tüm bacakların INPUT yani giriş olarak ayarlanacağını ifade eder.

Binary değerin bazılarının sıfır (0) bazılarının bir(1) olması ise bazı pinlerin çıkış bazılarının ise giriş olarak ayarlandığını gösterir.
Şimdi açıklamamızı program şeklinde verelim.

TRISA=%00000 ‘A portu Çıkış olarak ayarlandı
TRISB=%00000000 ‘B portu Çıkış olarak ayarlandı

Çıkış olarak belirlediğim portun çıkış değerini Low (0) olarak ayarlamak için şu şekilde bir ifade yazabilirim.

PORTA=0 ‘A portu tüm çıkışlar Low (0)
PORTB=0 ‘B portu tüm çıkışlar Low (0) Eğer High yapmak isteseydim
(PORTA=1),(PORTB=1) şeklinde yazacaktım.

Gördünüz mü ne kadar basit. Pinleri çıkış olarak ayarladım ve tüm çıkışları Low yaptım.
Herhangi bir portun bir pin’inin gösterilme şekli port ismi devamında nokta ve pin numarası verilerek yapılır.
Örnek A portunun 2 nolu pini için PORTA.2 şeklinde bir gösterim kullanılır.
Şimdi diyelim ki PORTA.0 yani A portunun sıfır biti yani ilk pin’e bağlı LED’i yakalım ;Komutumuz bir kaç mantıklı şekilde olabilir. Sırası ile;

PORTA.0=1 ‘PortA.0 High yani 1 oldu ve LED yandı.veya
HIGH PORTA.0 ‘PortA.0 High oldu yani LED yandı,

Komutu mümkün olduğu sürece şeklinde kullanmayı tercih edin.

Proje 1a : 

resim

Şimdi de birden fazla pin’e bağlı Led lerin aynı anda yakılmasını gerçekleştirelim.
PortA=%10101 şe
klin de bir komut yazarsam, sağdaki ilk değer olan 1 (Bir) PortA.0′a verilir.
Sonra sırası ile yani soldan sağa doğru olan Binary değerler PORTA nın 0-4 nolu pinlerine verilirler.
Değer sıfır ise pin Low, değer
bir ise pin High olur. Sonuçta bu komut ;

TRISA=%00000 ‘A portu Çıkış olarak ayarlandı
PortA.0=1
PortA.1=0
PortA.2=1
PortA.3=0
PortA.4=1 ‘( Bu pin diğerlerinden farklıdır.Open kollektör olduğu için “pullup” direnci kullanılır.
Aksi halde istediğimiz çıkışı alamayız.) şeklinde karşılık gelen Binary değerleri port pinlerine verir.

Demek ki bir port’a bağlı pinlerin birden fazlasına hükmetmek için port’a sekiz bitlik bir Binary veya desimal değer verilir.
Şimdi port pinlerinin ne amaçlı çıkış olarak kullanıldığı üzerine biraz bilgi verelim.

Diyelim ki port pin’ine bağlı bir Role yi bir transistor aracılığı ile çalıştırmak istiyorsun. İşte yolu, pin çıkışını bir direnç ile (1K-2k2)
bir transistor ün (B)eys’ine bağla. NPN tipi bir transistör kullanırsan transistör ün (E)mitterini GND ye bağla.
Port Pin’inden High (1) çıkartırsan transistör iletime geçecek ve (C) kollektör ünden GND çıkaracaktır.
Bunu bir role ye bağla ve rölenin diğer ucunu +5V’a bağlar isen pinden röleyi çalıştırıp kapatabilirsin.

Bunu bir örnekle açıklayalım;
Diyelim ki PortB.1 pinine bir transistör üzerinden role bağladık ve bu röleyi açıp kapayacağız.İşte basit programımız;

Proje 1b : 

resim

1 TRISB=%00000000 ‘B portu çıkış yapıldı
2 PortB=0 ‘B portunun çıkışı Low(0) yapıldı.
3 ROLEAC:
4 HIGH PORTB.1
5 PAUSE 1000 ‘1000 ms lik bir gecikme yaratır.
6 LOW PORTB.1
7 PAUSE 500
8 GOTO ROLEAC

1. Satırda PortB yi çıkış olarak ayarladık.
2. Satırda PortB pinlerinin tamamını LOW yaptık.
3. cü satırda ROLEAC isimli bir etiket yarattık.(Yaptırmak istediğimiz diğer komutlar için ismini
kendimizin koyduğu başka etiketler yaratıp programın daha fazla işlem yapmasını sağlarız.)
4. satırda PortB.1 pinini High yaptık.
5. satırda 1000 ms lik bir gecikme yarattık. Yani role 1000 ms süresince çekili kaldı.
6. Satırda PortB.1 pinini LOW yaptık. Yani role bıraktı.
7. satırda tekrar 500 ms lik bir gecikme yarattık.

Sonra programı tekrar aynı işleri yapması için ROLEAC etiketine yönlendirdik.

Buraya kadar öğrendiklerimizi toparlar isek;
- Sayı gösterim formatlarını öğrendik.
- Port pinlerinin nasıl giriş nasıl çıkış yapılacağını öğrendik.
- Port ve port pinlerine nasıl ulaşabileceğimizi öğrendik.
- Milisaniye cinsinden gecikmenin nasıl yaratıldığını öğrendik.
- Program içinde etiket kullanarak aynı işlemlerin nasıl tekrarlanabileceğini öğrendik.
Bütün bu öğrendiklerimizi tek program üzerinde göstermeye çalışalım.

Proje 1c : 

resim

Program PortA.0 pinine bağlı LED i kontrol edecek ve ayrıca PortB.0 pin’ine bağlı röleyi açıp kapayacaktır.
Role çekildiğinde PortA.0 pinine bağlı LED yanacak. Role bırakınca LED’de sönecektir.
Role çekili kalma süresi 1 sn. yani 1000 ms. olacaktır.

TRISA=0 ‘bu ifade “ TrisA=%00000 ” e eşdeğerdir.
TRISB=0
PortA=0
PortB=0
ROLEAC:
HIGH PORTB.0 ‘role çektirildi
PAUSE 500 ‘500 ms bekleme
HIGH PORTA.0 ‘Led yandı
PAUSE 500 ‘500 ms bekleme
LOW PORTA.0 ‘Led söndü
PAUSE 500 ‘500 ms bekleme
LOW PORTB.0 ‘Role bıraktı
PAUSE 500 ‘500 ms bekleme
GOTO ROLEAC ‘Roleac etiketine git
END ‘programın burada bittiğini ifade eder.

www.picproje.com ‘dan alıntıdır.

Pic Basic Öğreniyorum-5

Ders 5
Pic ile Analog Digital Çevirici Kullanımı:

Günlük hayatta kullandığımız cihazlar genelde Analog ve Dijital olarak ikiye ayrılmaktadırlar. Sayısal sistemle
çalışan tüm cihazlar Dijital olarak nitelendirilmekte bunun dışındakiler ise Analog cihazlar olarak nitelendirilmektedirler.
Mikroişlemcilerin tamamı dijital cihazlardır. Zaman zaman mikroişlemci bazlı bazı cihazların Analog cihazları kontrol
etmesi istenir. Zaman zamanda Analog sinyallerin işlenip değerlendirilmesi için bu sinyallerin dijital sinyaller haline
getirilmesi gerekir.

İşte bu gibi durumlarda Analog – Digital çeviriciler kullanılır. Yalnızca A/D çevirici olarak üretilmiş entegreler olduğu
gibi bazı Pic’ler de bu çeviriciler seçimli olarak hazır bulunurlar. Burada A/D çeviricisi bulunan Pic’ler incelenecek ve
kullanımları konusunda örnekler verilecektir.

Bu konuda en çok kullanılan Pic’lerden birisi 16F877 entegresidir. 40 bacaklı olan bu entegrede 8 kanal ve 10 bit
hassasiyette A/D çeviricisi bulunmaktadır.

A/D çevirim prensibi genelde bir kondansatörün belirli bir referans voltajı ile şarj edilip deşarj için geçen sürenin
sayılması esasına dayanır. Elde edilen süre bilgisi ise Analog değere karşılık elde edilmiş olan dijital değer olarak verilir.

Üzerinde A/D çevirici bulunan bir Pic kullanılırken yapılacak işlerin başında hangi bacakların ANALOG hangilerinin
DIGITAL olarak kullanılacağına karar vermektir. Sonra A/D çevirici için referans voltajı kaynağının seçimi yapılmalıdır.
İki türlü referans voltajı vardır. Birincisi Pic’in kendi VDD beslemesi (+5V) diğeri ise harici bir voltaj kaynağıdır. Tabiiki
harici kaynaklar referans voltajının 5 Volt’tan farklı olması durumunda seçilmelidir.

Şimdi gelelim bu seçimleri yaptıktan sonra bunları Pic’e nasıl vereceğimize.
A/D çeviricisi olan Pic’lerde ADCON register’i denilen 8 bitlik bir yazmaç bulunmaktadır.
Genellikle bu yazmaç ADCON1 adı ile isimlendirilir.
Şimdi 16F877 nin ADCON1 yazmaç’ını inceleyelim.

2: ADCON1 REGISTER (ADDRESS 9Fh)

Bit-7
Bit-6
Bit-5
Bit-4
Bit-3
Bit-2
Bit-1
Bit0

ADFM
-
-
-
PCFG3
PCFG2
PCFG1
PCFG0

Bit-7: A/D Sonuç Format Seçme biti dir.
1 olur ise sonuç sağa hizalanmış , ADRESH nin 6. uç bitleri 0 olarak okunur.
0 olur ise sonuç sola hizalanmış, ADRESL nin alt bitleri 0 olarak okunur.
Bit 6-4 arası kullanılmaz ve 0 olarak okunur.
Bit -3-0 arası PCFG3 – PCFG0 A/D portu ayarlama kontrol bitleridir. İşte bu bitleri ayarlayarak portların seçimleri yapılır.
Aşağıdaki tabloya bakınız. 

resim

Şimdi tablo üzerinde biraz kafa yoralım.
Şayet PCFG3:PCFG0 bitlerini 0000 olarak verir isek bu durumda RA0-RA3 , RA5, RE0-RE2 bacaklarının tamamı ANALOG
olarak ayarlanmış olacak ve artı referans Voltajı VDD den eksi referans voltajı ise VSS yani GND den alınacaktır.
Şimdi diyelim ki bize 3 adet Analog giriş lazım diğerleri Digital olabilir. +5V ve GND de referans voltajları olarak kullanılacak.
Bu durumda tabloya bakar isek 0100 değeri tam istediğimiz ayarlamayı yapabiliyor. Tablonun en son hanesinde ilk değer kaç
Analog giriş olduğunu / işaretinden sonraki değer ise harici referans voltaj girişi adedini gösteriyor. Seçtiğimiz değerde burası
3/0 olarak görülmektedir. Anlamı 3 adet Analog giriş ve sıfır referans voltajı var demek. Zaten biz Pic’in kendi voltaj girişlerini
kullanmak istediğimizden gerçektende bize sıfır referans girişi lazımdır.
Pic’in voltaj girişleri referans voltajı olarak seçildiğinde Pic’e giren Analog voltaj değerinin 5 Volt’u aşmamasına dikkat edilmelidir.
Bu şekilde tablonun kullanılmasını anlattıktan sonra bu aşamada tüm girişlerin Digital seçilmesi konusunda değinmek isterim.
Analog girişlerin Digital olarak kullanılması istenir ise tablodan sağ tarafta 0/0 değerinin bulunduğu satırda PCFG3:PCFG0
değeri 0111 (Desimal 7) olarak görülür. Demek ki ADCON1=7 veya ADCON1=%0111 dediğimiz zaman Pic 17F877 nin
Analog girişleri iptal edilerek normal Digital giriş çıkışa dönüştürülmektedir. A/D çeviricisi bulunan Piclerde aksine bir komut
bulunmaz ise ilk açılışta A/D pin’ler Analog olarak açılırlar. Dolayısıyla bu pinleri Digital kullanmak isterseniz mutlaka
Adcon1=7 komutunu vermeniz gerekir.
Bu kadar bilgi bir örnek üzerinde çalışmamız için yeterlidir. Şimdi bir örnek program yapalım.

Örnek Program:
Bu programımız AN0 yani PORTA.0 bacağına bağlayacağımız bir potansiyometre üzerinden voltaj okuması yapılmasını sağlayacaktır. 

resim

Şimdi Programımızı yazalım
‘****************************************************************
‘* Name : ADC.BAS
‘* Author : [ETE]
‘* Notice : Copyright (c) 2005 [ETE]
‘* : All Rights Reserved
‘* Date : 20.04.2005
‘* Version : 1.0
‘* Notes :
‘****************************************************************
TRISA=%00000001
TRISB=0
TRISC=0
TRISD=0
‘——————————————————————————-
@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, XT_OSC
‘——————————————————————————-
DEFINE LCD_DREG PORTB ‘LCD data bacakları hangi Porta bağlı?
DEFINE LCD_DBIT 4 ‘LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG PORTB ‘LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 3 ‘LCD Enable Bacağı Hangi bite bağlı ?
define LCD RWREG PORTB ‘LCD R/W Bacağı Hangi Porta bağlı?
define LCD_RWBIT 2 ‘LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG PORTB ‘LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 1 ‘LCD RS bacağı Hangi Bite bağlı ?
DEFINE LCD_BITS 4 ‘LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES 2 ‘LCD Kaç sıra yazabiliyor
‘——————————————————————————-
DEFINE ADC_BITS 10 ‘A/D çevirim sonucu kaç bit olacak
DEFINE ADC_CLOCK 3 ‘Clock kaynağı (3=rc)
DEFINE ADC_SAMPLEUS 100 ‘Örnekleme zamanı mikro saniye cinsinden.
‘——————————————————————————-
ADCON1=%10001110 ‘7. bit 1 yapıldı 10 bit sonuç almak için.
‘——————————————————————————-
HAM var word ‘ADC den okunan ham Digital değer.
VOLT var word ‘16 bit değişken tipi seçtik kullanacağımız değer 10 bit olacak.
Mvolt var byte
‘——————————————————————————-
Low PORTB.2 ‘ LCD R/W line Low (W), şemada direkt GND ye bağlanabilir.
LCDOut $FE,1 ‘ LCD de CLS yapar
pause 200 ‘ LCD nin açılması için gerekli süredir.
‘——————————————————————————-
BASLA:
ADCIN 0,HAM ”0 nolu kanaldan Analog değeri oku ve RAW değişkenine aktar.
BAK: IF ADCON0.2=1 THEN BAK ‘Çevirme işlemi tamamlanınca Adcon0.2=0 olacak.
lcdout $FE,1,” HAM =”,# HAM
Ham=ham+1 ‘Hesap kolaylığı açısından Ham değerini bir artırdık

‘Okunan değer 0-5 volt için 0-1024 olacağından okunacak değer başına volt de
ğeri
‘ 5/1024 =0,0048828 olacaktır. Sayı çok küçük olduğundan bu değeri 1000 ile
‘çarpmalıyız. O halde (Okuma/V)= 4,8828 bu değeri 256 ile çarpar isek
‘4,8875 x 256 = 1250 değerini buluruz. Bu değeri kullanarak 32 bit işlem yapabiliriz. ‘1250 değeri (5/1024)*256 değerine karşılık gelmektedir.
’sonuçta ADC HAM değerini bu sayı ile çarpıp 256′ya bölersek sonucu elde etmiş oluruz.
‘ancak sonuç 32 bitlik sınırda olduğundan bu işi 32 bit çarpma ile yapıyoruz ve orta
‘baytı aldığımızda ise zaten sayının 256′ya bölünmüş halini aldığımızdan başka bir
‘işlem yapmadan sonucu elde etmiş oluruz.
Volt=(ham */ 1250)/100 ‘Ham ile 1250 yi 32 bit olarak çarp ve 100′böl
Mvolt=Volt // 10 ‘Mvolt= Volt MOD 10
‘Burada yeni bir komut veya işlem şekli görüyorsunuz. MOD alma yani (//) kalan bulma
‘Bir sayını başka bir sayıya bölünmesinden sonra kalan miktarı bulma işlemine MOD
‘alma denir. Örnek W=A//1000 , A’yı 1000′e böl kalanı W değişkenine koy anlamındadır.
‘bizde yukarıda Mili volt değerini bulmak için volt (10 ile çarpılmış halini) 10′a
‘bölüp kalanı Mvolt değişkenine yerleştiriyoruz.
Volt=Volt/10
LCDOUT $FE,$C0,” VOLT=”,#VOLT,”,”,# Mvolt
PAUSE 500
GOTO BASLA
ADC işlemlerinde ölçümler genelde çok kararlı olmaz. Bir biri arkasına yapılan ölçümlerde ufak
tefek farklılıklar görülebilir. Bu nedenle çoğunlukla ortalama alma metodu kullanılır. Aynı yerde
birden fazla ölçüm alınır ve sonuçlar toplanır. Sonuçta kaç adet ölçüm yapılmış ise toplam, o sayıya
bölünür. Örnek vermek gerekir ise;
For I=1 To 10
ADCIN 0,HAM
TOPLAM=TOPLAM+HAM
NEXT I
HAM=TOPLAM/10
Sonuçta Ham değeri 10 adet ölçümün ortalamasını gösterecektir ve oldukça kararlı bir değer olacaktır.
ADC çevirme işlemlerinde en önemli husus elde edilen Ham değerin istenen değere çevrilmesi için oluşturulacak
formülün bulunmasıdır. Örneğin bir sıcaklık ölçümü yapıyorsunuz ve bir ısı sensörü değerini ölçüyorsunuz.
8 bitlik bir işlemde 0-255 arası değerler , 10 bitlik bir işlemde 0-1023 arası değerler bulacaksınız. Peki bu
değerleri nasıl sıcaklık değeri olarak göstereceksiniz. İşin önemli noktası burası.
Hemen şu hesaplamayı yapmalısınız. 8 bit hesaplama için , Sensör den okunabilecek en yüksek değer 255
olacaktır. Peki bu değer kaç derece sıcaklığa eşdeğerdir?. Yani Sensör ün gösterebileceği maksimum sıcaklık
ne olacaktır. Bunu sensör bilgilerinden (bilgi formu veya üretici bilgilerinden) alacaksınız. Diyelim ki 120
dereceye eş değerdir. O halde birim okuma başına düşen sıcaklık değeri 120/255 =0,470 derece olacaktır.
Bunu Pic de kullanabilmek için 0,470 x100 = 47 olarak bir değer elde edilecektir. Demek ki ben okuduğum
değeri 47 ile çarpıp sonucu 100 e bölersem sıcaklığı bulabilirim.
O halde sensör den okunan 134 dijital değerinin sıcaklık karşılığı ne olacaktır diye sorduğumuzda formülümüz bize;
Sıcaklık =(134 x 47)/100=62,98 derece olarak bulunacaktır.
ADC konusunda söylenecek son söz olarak üzerinde ADC çevirici bulunan her Pic farklı özellikler taşıyabilir.
En azından Analog pinlerinin ayarlanması işlemi farklı olabilir. Bu nedenle farklı Pic ler ile çalışırken mutlaka
bilgi formlarında belirtilen ADC özelliklerine göz atmanızı tavsiye ediyorum.
Diğer bir husus da program başında verilen ADC DEFINE parametrelerinin ayarlanmasıdır.
Bunlar;
DEFINE ADC_BITS 10 ‘A/D çevirim sonucu kaç bit olacak
DEFINE ADC_CLOCK 3 ‘Clock kaynağı (3=rc)
DEFINE ADC_SAMPLEUS 100 ‘Örnekleme zamanı mikro saniye cinsinden.
Sırası ile tekrar gözden geçirirsek;
DEFINE ADC_BITS 10
ADC çevirim sonucunun kaç bitlik olacağını ayarlamaktadır. Sonuç 8 bit ise buraya 8 , 10 bit ise buraya
10 yazılmalıdır. Tabiiki kullanılacak değişken tespit edilen Bit değerine uygun olmalıdır.
DEFINE ADC_CLOCK 3 ‘Clock kaynağı (3=rc)
Adc çevrim işlemlerinde her bit karşılığı bir Clock palsı ile belirlenir. Clock kaynağı olarak Pic in osilatörü
veya dahili RC osilatör kullanılır. ADC işlemlerinde Bit başına çevirim süresi yaklaşık 1,6 mikro saniye olmalıdır.
Pic in kendi osilatörü kullanılacak ise bu süreyi tutturmak için sistemi çalıştıran kristal frekansına göre bir hesap
yapılıp gerekli parametre bulunmalı ve buraya yazılmalıdır. Şimdi örnek bir hesap yapalım. Bu hesapta
kullanabileceğimiz formül şöyledir;
Tçevirim= X/Fosc.
Burada X değeri 2 veya 8 veya 32 olabilmektedir. Fosc ise kristal frekansı olup MHZ cinsindendir.
Tçevirim=1,6 us. Olduğuna göre şimdi diyelim ki kristal frekansımız 4 Mhz ve Pic’in osilatörü nü kullanacağız.
Hesaba göre ;
(00) Tcevirim=2/4 = 0,5 us çıkar 1,6 dan çok küçük olduğu için uygun değildir.
(01) Tcevirim=8/4 = 2 us çıkar 1,6 dan büyük ve yakın olduğu için kullanılabilir.
(10) Tcevirim=32/4 = 8 us çıkar 1,6 dan çok büyük olduğu için uygun değildir.
Kullanılabilir olan 8 değerinin Define komutundaki karşılığı (%01=1) 1 dir.O halde komut
DEFINE ADC_CLOCK 1 ‘olacaktır.
Aynı hesabı 20 MHz için yapar isek;
(00) Tcevirim=2/20 = 0,1 us çıkar 1,6 dan çok küçük olduğu için uygun değildir.
(01) Tcevirim=8/20 = 0,4 us çıkar 1,6 dan çok küçük olduğu için uygun değildir.
(10) Tcevirim=32/20 = 1,6 us çıkar 1,6 ile aynı olduğundan çok uygundur.
O halde komut; (%10=2)
DEFINE ADC_CLOCK 2 ‘olacaktır.
Kristal osilatör ün uygun olmadığı durumlarda (%11=3) bu komut 3 olarak verilerek dahili RC osilatör
kullanılır. En çok kullanılan seçenek budur.
Son olarak;
DEFINE ADC_SAMPLEUS 100 komutunu inceleyelim.
ADC çevirim işleminin dahili bir kondansatörün önce şarj edilip sonra deşarj olma süresinin ölçüldüğünü
söylemiş idik. Belirtilen ADC_SAMPLEUS süresi ADC işleminin başlatılmasını müteakip yani ADON bit inin
set edilmesini müteakip uygulanan bir gecikme süresidir ve bir yerde kondansatörün şarj süresi olarak açıklanır.
Genelde 50-100 us dolayındaki süreler çevirim için uygun gelmektedir.
Son bir örnek vererek ADC konusunu bitirelim.
Örneğimiz 5K değerinde bir termistör ün ısı sensörü olarak kullanımına ait bir örnek olacaktır. Termistör
değerini ölçerek ekranda buna karşılık gelen sıcaklık değerini göstermeye çalışacağız.
Kullanacağımız termistör NTC (Negative Temperature Coefficient) tipi bir termistör olacak yani sıcaklık arttıkça
direnç değeri azalacak. Birde PTC tipleri mevcut olup bunlarda sıcaklık arttıkça direnç değeri de artmaktadır.

Programa geçmeden önce bazı varsayımlarımız olacak. 5 K lık termistör ’ün değeri 25 oC de ölçülen değeridir.
Varsayalım ki 0 oC de ki değeri 6 K olsun. 50 oC de ise 3 K olsun. Bu kriterleri kullanarak programımızı yazalım.
Amacımız bu termistör ü kullanarak bir termometre yapmak olacaktır.
Önce devremizi verelim 

resim

5 K lık termistör 0 derecede 6 K olacağı ve 50 derecede 3K ya düşeceği için yaklaşık 3K lık bir direnç sabit kalmakta
yalnızca 3 K lık bölüm değişmektedir. O nedenle şemada 5 K lık termistör 3K (Pot) + 3K sabit Direnç olarak gösterilmiştir.
ÖRNEK PROGRAM : TERMISTOR.BAS
‘****************************************************************
‘* Name : TERMISTOR.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 21.04.2005 *
‘* Version : 1.0 *
‘* Notes : *
‘* : *
‘****************************************************************
TRISA=%00000001
TRISB=0
TRISC=0
TRISD=0
‘————
——————————————————————-
@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, XT_O
SC
‘——————————————————————————-
DEFINE LCD_DREG PORTB ‘LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT 4 ‘LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG PORTB ‘LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 3 ‘LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD RWREG PORTB ‘LCD R/W Bacağı Hangi Porta bağlı?
DEFINE LCD_RWBIT 2 ‘LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG PORTB ‘LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 1 ‘LCD RS bacağı Hangi Bite bağlı ?
DEFINE LCD_BITS 4 ‘LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES 2 ‘LCD Kaç sıra yazabiliyor
DEFINE ADC_BITS 10 ‘A/D çevirim sonucu kaç bit olacak
DEFINE ADC_CLOCK 3 ‘Clock kaynağı (3=rc)
DEFINE ADC_SAMPLEUS 100 ‘Şarj zamanı mikro saniye cinsinden.
‘——————————————————————————-
ADCON1=%10001110 ‘7. bit 1 yapıldı 10 bit sonuç almak için.
‘——————————————————————————-
ISI VAR word
HAM VAR WORD
ONDA VAR BYTE
‘——————————————————————————-
Low PORTB.2 ‘ LCD R/W line Low (W), şemada direkt GND ye bağlanabilir.
LCDOut $FE,1 ‘ LCD de CLS yapar
pause 200 ‘ LCD nin açılması için gerekli süredir.
‘——————————————————————————-
BASLA:
ADCIN 0,HAM ‘0 nolu kanaldan Analog değeri oku ve RAW değişkenine aktar.
BAK: IF ADCON0.2=1 THEN BAK ‘Çevirme işlemi tamamlanınca Adcon0.2=0 olacak.
lcdout $FE,1,”HAM =”,# HAM
‘50 derecede okunan ADC değeri 256 ve 0 derecede okunan 146 olduğundan
‘0-50 derece arası okunan değer farkı 110 dur (256-146) . O halde her bir derece
‘için okunması gereken değer 110/50=2,2 olacaktır. Pic e uyarlamak için
‘okunan değeri 10 ile çarpıp 22 ye bölersek direkt sıcaklığı bulmuş olacağız.
‘ondalık değeri de hesaplamak için 10 yerine 100 ile çarpıyoruz.
ISI=((HAM-146)*100)/22
onda=ISI//10
ISI=ISI/10
LCDOUT $FE,$C0,” ISI=”,#ISI,”,”,#onda,”`C”
pause 500
goto basla

www.picproje.com ‘dan alıntıdır.

Pic Programlama

Bu çalışmada günümüzde artık hemen her dalda kullanılan mikroişlemcilerin özellikleri ve çalışma prensipleri üzerinde durulmuştur. Son yıllarda adını sıkça duymaya başladığımız PIC mikroişlemciler ve bunların içerisinden de kullanım özellikleri çok fazla olan PIC 16F87X mikroişlemcisi konu edilmiştir. PIC mikroişlemcilerin tercih sebepleri ve konu olan bu serinin diğer serilerden olan üstünlükleri, donanımsal olarak iç yapısı, programlanması konuları ele alınmıştır. Bu serinin diğer serilerden farklı en belirgin özellikleri EEPROM hafızası ve ADC özelliğinin bir arada bulunmasıdır. Programlama açısından ise PIC mikroişlemcilerin genel programlanmaları anlatılmıştır. Komutların kullanımı hakkında geniş bir bilgi verilmiştir.

1-GİRİŞ

1.1 MİKROİŞLEMCİLER

Mikrobilgisayarlar, günlük yaşantımızda kullanım alanları gün geçtikçe artmaktadır. Bir mikrobilgisayarın temel yapısı, bir diğerinden pek farklı değildir. 1960’larda bilgisayarlar, fiyatlarının çok yüksek olması nedeni ile sadece büyük şirketler, gelişmiş üniversiteler ve devlet daireleri tarafından kullanılabiliyordu. Yarı iletken teknolojisindeki hızlı gelişmeler neticesinde, 1960 lardaki bilgisayar kapasitesi günümüzde 10 dolardan daha ucuz olan mikroişlemci denilen tümleşik devrelere sığdırılmaktadır. Bir mikroişlemci kullanılarak tasarımlanan bilgisayara mikrobilgisayar denilmektedir. Geri kalanını oku »

Pic C Programlama

Sabitler

Data Yönlendirme yazmaçlarının ( register) Kullanımı:
set_tris_a (deger);
set_tris_b (deger);
set_tris_c (deger);
set_tris_d (deger);
set_tris_e (deger);

Örnek1:
set_tris_a(15); // komut satırı i le A portunun 0,1,2,3. bitleri giris, 4. biti çıkıs olarak ayrlanmıs oldu.
Örnek2:
Set_tris_a(0b00001111); // yukarıdakinin ikilik sistemde (binary) olarak yazılışı.
Örnek3:
SET_TRIS_A (2); // Satırı ile A portunun 1. biti giris, digerleri çıkıs olarak ayarlandı.

Portlara bilgi Gönderimi :
output_a (deger);
output_b (deger);
output_c (deger);
output_d (deger);
output_e (deger);

Örnek1:
output_b (15); // satırı i le b portu hem çıkıs yapılır. Hemde B portunun uçlarına 15 gönderilir.
Komutun assembly dilindeki karsılıgı ;
BSF STATUS,5
MOVLW B’00000000’
MOVWF TRISB
BSF STATUS,5
MOVLW B’00001111’
MOVWF PORTB

Örnek2:
tekrar:
char x=0;
output_a(x);
x=x+1;
goto tekrar;

Bu örnekte yapılmak istenen x sayısını degistirerek çıkıs uçlarına göndermektir. Örnekte her döngüde çıkıs
degeri 1 artacak sekilde düzenlenmistir.

OUTPUT_BIT( ) Komutu: -stenilen herhangi bir portun herhangi bir ucunu 0 ya da 1 yapmak için kullanılır.
Kullanımı: OUTPUT_BIT( pin,deger);
Örnek:
OUTPUT_BIT(PIN_B0, 0 ); // satırında B portunun 0. biti 0 gönderildi.

OUTPUT_HIGH( ) Komutu: -stenilen bir ucun yüksek yani 1 olmasını saglar.
Kullanımı: output_high(deger);
output_high(PIN_A0); // A portunun 0. biti 1 yapıldı.

OUTPUT_LOW( ) Komutu: -stenilen bir ucun 0 olmasını saglar.
Kullanımı:
output_low(deger);
output_low(PIN_A0); // A portunun 0. bitini 0 yapar.

INPUT( ) Komutu: herhangi bir ucun giris olarak ve giristen alınacak degerin degerlendirilebilmesi için
kullanılır.
Kullanımı:
a = input(PIN_A0); //a degiskenine A portunun 0.biti esitlendi. Giristen alınacak bilgi a degiskeninde
kullanılabilir.

BIT_TEST( ) Komutu: Belirtilen bir registerin bitini kontrol etmek için kullanılır.
Kullanımı:
bit_test(x,3); // x registerinin 3.bitini test eder.

Program Yazımı:
Program basında mutlaka bulunması gerekenler.
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
Örnek 1: B portunun 0. bitine baglı led diyodu 250 ms aralıklarla yakıp söndüren program.
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
void main() {
tekrar:
output_bit(PIN_B0,1);
delay_ms(250);
output_bit(PIN_B0,0);
delay_ms(250);
goto tekrar;
}

Örnek 2: B portundaki tüm ledleri 250 ms aralıklarla yakıp söndüren program.
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
void main() {
tekrar:
output_b(255);
delay_ms(250);
output_b(0);
delay_ms(250);
goto tekrar;
}

Örnek 3: A portunun 0. bitine baglı olan butona basıldıgında B portuna balı olan ledi yakan buton
bırakıldıgında ledi söndüren program.
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
void main() {
char a;
tekrar:
a=input(PIN_A0);
output_b(a);
goto tekrar;
}

Örnek 4: B portuna baglı led diyodları binary olarak saydıran program.
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
void main() {
char a;
tekrar:
output_b(a);
a=a+1;
delay_ms(250);
goto tekrar;
}

if Komutu : Kelime karsılıgı “eger”dir. C Dilinde if deyimini kullanmak için su yol izlenir.
Önce if deyimine bir ifade verilir. Bu ifade degerlendirilir ve islemin sonucu dogru ise if deyiminden
sonra gelen satır çalıstırılır. Dogru degilse çalıstırılmaz.
Kullanımı:
/f(sart)
Kosul dogru oldugunda çalıstırılacak satır ;
Örnek:
if(a<2)
goto tek;
else eklenerek kullanmak:
if komutunda sart saglanırsa bir ifade çalıstırılır. Sart saglanmazsa çalıstırılmaz. Fakat else
kullanarak sartın saglanmadıgı durumlarda yapılması gereken islem belirtilir.
Kullanımı:
if(sart)
Kosul1;
else
Kosul2;
Örnek:
if (x==25)
x=1;
else
x=x+1;

örnek program:
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
void main()
{
tek:
if(input(PIN_A0)==1)
output_b(255);
else
output_b(1);
goto tek;
}

While Komutu : Belirtilen sart geçerli oldugu müddetçe islem tekrarlanır.
Kullanımı:
While(sart)
{
islemler;
}
Örnek:
while(x<200)
{
output_a (255);
}
x degiskeni 200 den küçük oldugu sürece parantez içerisindeki komut satırları tekrarlanır.
while(a<4)
{
a=0;
a++;
output_b (1);
}
yukarıdaki komut satırları B portuna 1 bilgisini 4 defa gönderir.
Do while komutu: while döngüsüne çok benzer ve aynı mantıkla çalısır. While komutunda kosul
döngüye girmeden önce yapılıyordu. Yani önce kosul kontrol ediliyor, eger dogru olarak
degerlendirilir ise döngüye giriliyordu. do while döngüsünde ise önce döngüye girilir, döngü en az bir
kere çalıstırılır, kosul kontrolü ise döngü sonunda yapılır.
Kullanımı:
Do
{
çalıstırılacak satırlar;
} while (sart);
Örnek:
do
{
a++;
output_b(255);
} while(a!=10);
Bu örnekte a sayısı bir arttırılarak b portuna gönderilir. Eger a 10 olursa isleme alt satırlardan devam
edilir. 10 degilse tekrar arttırılır.

Örnek program:
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
void main()
{
char a=0;
do
{
a=a+1;
delay_ms(250);
output_b(a);
} while(a!=3);
delay_ms(500);
output_b(255);
tek:
goto tek;
}

For Komutu : Belirlenen sınırlar içerisinde istenilen islemleri yapmak için kullanılır.
x=0;
for(a=0; a<10;a=a+2)
{
x=x+1;
output_a (x);
}
yukarıdaki örnekte alt sınır 0 (a=0), üst sınır 10 (a<10) ve a nın her döngüde artıs
miktarıdır.(a=a+2)
0 dan 10 ye kadar her döngüde 2 arttırarak 5 defa B portuna her defasında x e baglı olarak farklı
bilgiler gönderir. 0, 1,2,3,4 bilgileri B portuna sırasıyla gönderilir.

Örnek program
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
void main()
{
char a,x=0;
for(a=0; a<10;a++)
{
x=x+1;
output_b (x);
delay_ms(250);
}
}

switch deyimi:
if deyiminin kullanımına çok benzer.iç içe if deyimlerinin kullanılması gereken yerlerde switch deyimi
kullanmak daha dogru olur. Fakat bu olay switch deyiminin if deyiminden daha üstün oldugunu göstermez. Her
ikisinin de üstün oldugu kullanım alanları vardır.
Kullanımı:
Switch( kosul) {
case sabit 1: çalıstırılacak satır;
break;
case sabit 2: çalıstırılacak astır;
break;
}

Örnek: a degiskenine baglı olarak a nın 0,1,2 durumlarda b portuna 0,1,2 bilgisini gönderen program.
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
void main() {
char a=0;
tek:
switch (a)
{
case 0 : output_b(0);
delay_ms(250);
break;
case 1 : output_b(1);
delay_ms(250);
break;
12
case 2 : output_b(2);
delay_ms(250);
break;
}
a=a+1;
goto tek;
}

break ve continue deyimleri:
Tüm döngüler içerisinde kullanılan iki deyimdir.
Break deyimi; içinde kullanıldıgı döngüyü sonlandırmak için kullanılır. Program içerisinde break
komutu görüldügüne döngü içerisindeki islemler tamamlanmadan döngü sonuna gidilir.
Örnek:
Char a=0;
while (a<5) {
output_b(255);
delay_ms(250);
break;
a=a+1;
}
Örnekte ilk olarak a degiskeni kontrol edilir. a degeri 5 ten küçük oldugu için b portuna 255 gönderilir
daha sonra 250ms beklenir ve islem bitirilir. Break komutu olmasaydı bu islem a nın 5 degerine
ulasmasına kadar devam edecekti.
Continue deyimi de benzer özellikler gösterir. Program içerisinde program akısının döngü basına
dönmesini saglar.
Örnek:
char a=0;
while(a<5) {
output_b(255);
continue;
a++;
}
Örnekte a nın 5 ten küçük oldugu kontrol edilir. b portuna 255 gönderilir. Continue komutu görülünce
döngü basına dönülür dolayısıyla b portuna sürekli 255 gönderilmis olunur.
Sonsu döngüler:
tek :
goto tek;
ya da
char a=2;
while(a>1) {
………
……
}
burada a nın yani 2 nin 1 den büyük oldugu durumlarda parantez içerisindeki islemler
gerçeklestirilecek yani sürekli devam edecek.

PIC VE LCD KULLANIMI
LCD ALT PROGRAMI
//// f Clear display ////
//// n Go to start of second line ////
//// b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
// LCD pins D0-D3 are not used and PIC D3 is not used.
// Un-comment the following define to use port B
#define use_portb_lcd TRUE
struct lcd_pin_map { // This structure is overlayed
BOOLEAN enable; // on to an I/O port to gain
BOOLEAN rs; // access to the LCD pins.
BOOLEAN rw; // The bits are allocated from
BOOLEAN unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
#if defined(__PCH__)
#if defined use_portb_lcd
#byte lcd = 0xF81 // This puts the entire structure
#else
#byte lcd = 0xF83 // This puts the entire structure
#endif
#else
#if defined use_portb_lcd
#byte lcd = 6 // on to port B (at address 6)
#else
#byte lcd = 8 // on to port D (at address 8)
#endif
#endif
#if defined use_portb_lcd
#define set_tris_lcd(x) set_tris_b(x)
#else
#define set_tris_lcd(x) set_tris_d(x)
#endif
#define lcd_type 2 // 0=5×7, 1=5×10, 2=2 lines
#define lcd_line_two 0×40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0×20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE low,high;
16
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
17
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
18
address=0;
address+=x-1;
lcd_send_byte(0,0×80|address);
}
void lcd_putc( char c) {
switch (c) {
case ‘f’ : lcd_send_byte(0,1);
delay_ms(2);
break;
case ‘n’ : lcd_gotoxy(1,2); break;
case ‘b’ : lcd_send_byte(0,0×10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}

Örnek: ilk satırda sabit bir ifade ikinci satırda yine sabit ifade fakat A portunun 2 bitine baglı olan
butona basıldıgında kayarak geçen bir yazı yazan program.

#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#endif
#include
char a,b,c,d,e,f;
char x,x1,x2,x3,x4,x5,x6;
char i=250;
void main() {
lcd_init();
tek:
x=input(PIN_A2);
lcd_putc(“fMEHMET ASIK “);
lcd_putc(“nPIC16F84 PROJESi “);
delay_ms(250);
if(x==0) goto basla;
else goto tek;
basla:
lcd_putc(“fMEHMET ASIK “);
x1=24;
for(a=0;a<30;a++)
{
lcd_gotoxy(x1,2);
lcd_putc(“CUKUROVA “);
x1–;
20
delay_ms(i);
}
lcd_putc(“n “);
x2=24;
for(b=0;b<30;b++)
{
x2–;
lcd_gotoxy(x2,2);
lcd_putc(“UNIVERSITESI “);
delay_ms(i);
}
lcd_putc(“n “);
x3=24;
for(c=0;c<30;c++)
{
x3–;
lcd_gotoxy(x3,2);
lcd_putc(“ADANA MESLEK “);
delay_ms(i);
}
lcd_putc(“n “);
x5=24;
for(e=0;e<30;e++)
{
x5–;
lcd_gotoxy(x5,2);
lcd_putc(“YUKSEK OKULU “);
21
delay_ms(i);
}
lcd_putc(“n “);
goto tek;
}

ÖRNEK: A portunun 2 bitine baglı olan butona basıldıgında B, basılmadıgında ise A yazdıran
prgram.

#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#endif
#include
char x;
void main() {
lcd_init();
tek:
x=input(PIN_A2);
x=x+65;
lcd_putc(x);
delay_ms(50);
goto tek;
}

DAHİLİ EEPROM KULLANIMI:
Pic 16F84 de 64 Byte dahili EEPROM vardır. EEPROM Elektrikle silinebilir yazılabilir bellek
oldugundan program yazımında istenilen bilgiler yazdırılır ve istendiginde bu bilgiler kullanılır, ya da
silinebilir.
PIC C dilinde dahili EEPROM u kullanabilmek için EEPROM yazma ve EEPROM okuma komutlarını
bilmek, yazdırılacak ya da okunacak adresleri tespit etmek gerekir.
EEPROM yazma:
EEPROM hafızaya herhangi bir sey yazmak için include dosya kullanmak gerekmez. Nasıl ki
portlara dogrudan bilgi gönderiliyorsa EEPROM a da bilgi gönderilebilir. EEPROM bilgisi zaten
16F84.h dosyası içerisinde mevcuttur. Komutun kullanımı;
Write_eeprom(adres,deger); Seklindedir.
Adres olarak 0-63 arası bir deger yazılabilir. (Toplam 64 Byte oldugundan)
Deger olarak ise 0-255 arası bir deger yazdırılabilir.
Adres olarak 63ten, deger olarak 255 ten büyük sayı yazıldıgında derleyici bir hata vermez fakat
sonuç olarak bir islem yaptırılamaz.
Örnek : write_eeprom(0,65);
Satırı ile dahili EEPROM un 0. adresine 65 ( A ) yazdırılmıs olunur.
EEPROM okuma:
EEPROM u okumak için sadece adres belirtilecektir.
Komutun kullanımı;
read_eeprom(adres); seklindedir.
Adres degeri yine 0-63 olmalıdır. Aksi takdirde bir deger okuyamayız.
Örnek Program:
/
/// Dahili EEPROM kullanımı için yazılmıstır. /////////
//// EEPROM a yazılan bir yazı okunarak lcd ekrana /////////
//// yazdırılıyor. /////////

#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=20000000)
#include
char k;
void main() {
char adres, deger;
adres=0;
deger=65;
lcd_init();
t
ek:
write_eeprom( adres, deger);
adres++;
deger++;
delay_ms(25);
k=read_eeprom(63);
lcd_putc(k);
goto tek;
}

HARİCİ EEPROM KULLANIMI:
#if defined(__PCM__)
#include <16F84.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#endif
#include
#include <2416_1.c>
void main() {
char a,b,c,k;
a=0;
b=65;
lcd_init();
init_ext_eeprom();
tek:
write_ext_eeprom(a, b);
a++;
b++;
delay_ms(200);
k=read_ext_eeprom(10);
lcd_putc(k);
goto tek;
}

Mehmet Aşık