Bilgi Paylaşıldığında güzeldir

19 Mart 2013 Salı

Pic Basic Öğreniyorum 2


5.ders:
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 PIC16F877 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’lerdeADCON register’i denilen 8 bitlik bir yazmaç bulunmaktadır. Genellikle bu yazmaç ADCON1 adı ile isimlendirilir.
Şimdi PIC16F877 nin ADCON1 yazmaç’ını inceleyelim.
2: ADCON1 REGISTER (ADDRESS 9Fh)

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.


Ş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 veyaADCON1=%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.
Bu durumda 1 adet Analog giriş gerekiyor. PCFG3:PCFG0 değeri olarak tablodan 1110 değerini seçiyoruz. Bu seçenek tek Analog giriş (AN0-RA0) verdiği gibi Pic in voltaj girişlerini de referans voltajı olarak kullanmamızı sağlamaktadır. Devremiz aşağıdaki gibi olacaktır.



Ş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
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_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 ‘Ş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



5.ders  Proteus ve hex dosyaları  
Download

6.ders:

KESME (INTERRUPT) KULLANIMI: Tüm bilgisayarlar ve mikroislemci sistemlerinde kullanılan bir özelliktir.Basitçe açıklamak gerekirse, bir mikroislemciye kesme anında neler yapması gerektigi bir program bölümü seklinde verilir. Açıkçası mikro islemci kesme oluştugu anda yaptıgı isi tamamen bırakarak kesme bölümüne gider ve orada gösterilen isleri yapar. Kesme bölümünün sonunda tekrar geriye dön komutunu alır ve önceden yaptıgı ise kaldıgı yerden devam etmek üzere döner.
Bu olayı günlük hayatımızda yasadıgımız bir örnekle açıklayalım isterseniz. Diyelim ki bir evde yasıyorsunuz ve bir gün tüm aileyi topladınız. Amacınız aileye bir yangın olması durumunda ne yapılması gerektigini ögreteceksiniz. Burada yangının meydana gelmesi bir kesme olayı olacaktır. Normal yasama düzeninde hiç yangın olmaz ise kesme oluşmayacak demektir. Ama oluşma ihtimali her zaman olacaktır. Simdi bir aksam yemegi esnasında yangın çıktıgını varsayalım. Kesme oluşacak ve herkes önceden ögretildigi gibi görevinin basına kosacak. Yangın söndürülecek ve her kes yemege geri dönecektir. iste tipik bir kesme olayına
örnek. Kesme olayını kısaca açıkladıktan sonra Pic islemcilerinde hangi olayların kesme yaratabilecegine bir göz atalım.
RB0/INT KESMESİ:
En çok kullanılanlardan birisi PortB.0 pininde meydana gelen lojik seviye degisikliginin oluşturacagı kesme dir. Option Yazmaçının 6. biti önceden ayarlanarak kesmenin sıfırdan – bir konumuna geçiste mi yoksa bir konumundan – sıfır konumuna geçiste mi oluşturulacagı belirlenir.
OPTION_REG.6=0 olur ise RB0 da düsen kenarda kesme oluşur.
OPTION_REG.6=1 olur ise RB0 da yükselen kenarda kesme oluşur.
Düsen veya yükselen kenar terimi bir clock palsının kenar sekli olarak anlasılmalıdır. Kesme isleminin aktif edilebilmesi için INTCON (interrupt control registeri) yazmaçı kullanılır.
Örnegin RB0 kesmesinin aktif hale getirilebilmesi için;
INTCON.4=1 yapılmalı ve daha sonra ;
INTCON.7=1 degeri 7 nolu bite verilerek tüm kesmeler açılmalıdır.
Bu iki deger tek bir komutlada verilebilir. Söyle,
INTCON=%10010000
Bu kesme aktif hale getirildikten sonra sayet bir kesme oluşur ise INTCON yazmaçı nın 1 nolu biti 0 konumundan 1 konumuna geçer. Bu bit sayet tekrar 0 konumuna program içinde getirilmez ise yeniden bir kesme oluşmaz. Bu nedenle programın KESME bölümünde bu bit sıfırlanmalıdır. RB0/INT Kesme kullanımını toparlamak gerekir ise;
RB0/INT kesmesini kullanmak için yapılması gerekenler sırası ile;
- Programın bas kısmına ON INTERRUPT GOTO KESME komutu verilerek kesme oluştugunda programın gidecegi yer (KESME) belirlenir.
RB0 pini giris olarak ayarlanacak
- Gerekir ise Option Yazmaçının 7. biti 1 veya 0 yapılarak pullup dirençleri istege göre ayarlanacak.
- Option Yazmaçının 6 biti 1 veya 0 olarak ayarlanarak kesmenin düsen kenar veya yükselen kenardamı olacağına karar verilecek.
- Intcon yazmaçına INTCON=%10010000 degeri verilerek kesme aktif hale getirilecek.
- Kesme bölümüne baslarken DISABLE komutu verilerek kesme anında yeniden kesme oluşumuna imkan verilmeyecek.
- Kesme bölümünde INTCON.1=0 komutu verilerek kesmeden dolayı 1 olan bayrak tekrar sıfırlanır ve sonradan yeni kesme oluşmasına imkan tanınır.
- Kesme bölümünün sonunda RESUME komutu verilerek programın kesme oluşmasından önceki yerine dönmesi saglanır.
- En sona ENABLE komutu yazılarak kesmeden dönüldükten sonra tüm kesmeler aktif hale getirilir.
Simdi de ögrendiklerimizi bir örnek vererek açıklayalım. Örnek Programımız RB0 bacagına baglı bir tus yardımı ile RA.0 bacagına baglı olan bir led’i yakıp söndürsün. Program içinde tusa basıldı mı? seklinde bir komut vermeden direkt kesme özelliginden yararlanacagız.
Yani RB0 bacagını sürekli 1 konumunda tutacağız (pullu up ile). Dolayısıyla bu bacagı tusa basarak sıfıra çekersek kesme oluşacak ve kesme bölümünde de led’i toggle komutu ile yanıksa söndürecegiz, sönük ise yakacagız. Tabiiki seçim olarak RB0/INT bacagı düsen kenar da kesme oluşacak sekilde ayarlanacaktır. Önce semamızı verelim;





iste Programımız;

‘****************************************************************
‘* Name : KESME-RB0.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 23.04.2005 *
‘* Version : 1.0 *
‘* Notes : *
‘* : *
‘****************************************************************
PORTA=0
TrisA=%00000000
TrisB=%00000000
‘—————————————————————–
@ DEVICE pic16F628 ‘islemci  16F628
@ DEVICE pic16F628, WDT_on  ‘Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON  ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Koruma kapalı
@ DEVICE pic16F628, MCLR_OFF  ‘MCLR pini kullanılmıyor.
@ DEVICE pic16F628,  INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘—————————————————————–
ON INTERRUPT GoTo KESME ‘kesme oluşursa KESME adlı etikete git.
OPTION_REG=%0000000 ‘dahili  Pull up dirençleri aktif edildi ayrıca pullup direncine gerek yok
INTCON=%10010000 ‘Tüm  Kesmeler aktif ve RB0/INT kesmesi aktif
TRISB=%00000001 ‘PortB.0  giris digerleri çıkıs yapıldı.
TRISA=%00000000 ‘A portu  tamamı çıkıs yapıldı.
CMCON=7 ‘16F628 de  komparatör pinleri iptal hepsi giris çıkıs
‘—————————————————————–
SYMBOL TUS=PORTB.0
SYMBOL LED=PORTA.0
‘——————————————————————-
BASLA: ‘Ana program  bölümünde program bir sey yapmayacak
pauseus 100 ‘kesme  oluşmadıgı müddetçe program
goto basla ‘ bu satırlar  arasında dolasır
DISABLE ‘yeniden kesme  oluşması önleniyor
KESME: ‘program buraya  geldiginde kesme oluşmus demektir.
TOGGLE LED ‘LED konum  degistirdi
PAUSE 1
INTCON.1=0 ‘RB0/INT Bayragı (flag) silindi.
Resume ‘geldigin yere dön
Enable ‘kesmeler yeniden  aktif.
End
‘————————————————————————
B portunda dahili pullup dirençleri vardır ve OPTION Yazmaçının 7. biti bunların aktif olup olmamasını kontrol eder. Sayet bu bit 0 ise dirençler aktif, 1 ise dirençler devrede degildir. Sanırım örnek her seyi açıkça anlatıyor. Burada özellikle dikkat edilecek yer ana program bölümünde pauseus 100 komutundan baska bir komut olmadıgıdır. Normal olarak program kesme oluşuncaya kadar sürekli Basla etiketi ile Goto basla komutu arasında dönüp duracaktır. Buraya kadar açıklananlar yalnızca RB0/INT kesmesinin kullanımına örnektir.
PORTB (RB4-RB7) DEGİSİKLİK KESMESİ :
Bu kesme tipinde RB4-RB7 bacaklarının mevcut konumlarında oluşacak bir degisiklik sonucunda da kesme oluşturulmaktadır. Bu kesme PORTB nin RB4-RB7 arası bacaklarının tamamının giris yapılması halinde geçerlidir. Bacaklardan birisi çıkıs yapılır ise kesme iptal olur.
Kesme bir kere aktif hale getirilir ise bu 4 adet bacak degeri sürekli pic tarafından okunur. Okunan deger bir önceki ile karsılastırılır. Sayet fark var ise kesme oluşur. Kesme de oluşan RBIF bayragının silinmesi için PortB nin bir kere programcı tarafından mutlaka okutulması gerekir. Aksi taktirde bayrak silinemez ve sürekli kesme oluşur.
Tabiiki yalnızca PortB nin okunması bayragı silmeye yetmeyecektir. Ayrıca RBIF bayragının
kesme bölümünde silinmesi de gerekir. RB PORT (Rb4-Rb7) Degisiklik Kesmesinin oluşması İçin Gerekenler :
Programın bas kısmına ON INTERRUPT GOTO KESME komutu verilerek kesme oluştugunda programın gidecegi yer (KESME) belirlenir.
- RB4-RB7 pinleri mutlaka giris olarak ayarlanacak
- Intcon yazmaçının 3 biti bu kesme için ayrılmıstır. Bu bit 1 yapılarak kesme aktif edilir.INTCON=%10001000 degeri verilerek kesme aktif hale getirilecek.
- Kesme bölümüne baslarken DISABLE komutu verilerek kesme anında yeniden kesme oluşumuna imkan verilmeyecek.
- Kesme Bölümünde DURUM=PORTB seklinde port degeri okunacak
- Kesme bölümünde INTCON.0=0 komutu verilerek kesmeden dolayı 1 olan bayrak tekrar sıfırlanır ve sonradan yeni kesme oluşmasına imkan tanınır.
- Kesme bölümünün sonunda RESUME komutu verilerek programın kesme oluşmasından önceki yerine dönmesi saglanır.
En sona ENABLE komutu yazılarak kesmeden dönüldükten sonra tüm kesmeler aktif hale getirilir
Bu kesmeyi bir örnekle açıklayalım. Bu defa yine PortA.0 pinine bir LED baglı olsun. PortB.7 pinine bir Tus baglayalım ve bu sefer tus, pulldown yani GND ye çekili olsun. Tusa basılınca PortB.7 pinine High
uygulayalım.
İste baglantı semamız;



Program RB (4-7) Degisiklik Kesmesi:
 ‘****************************************************************
‘* Name : KESME-RBCH.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 23.04.2005 *
‘* Version : 1.0 *
‘* Notes : *
‘* : *
‘****************************************************************
PORTA=0:portb=0
TRISB=%11110000 ‘PortB tamamı giris yapıldı.
TRISA=%00000000 ‘A portu  tamamı çıkıs yapıldı.
‘—————————————————————–
@ DEVICE pic16F628 ‘islemci  16F628
@ DEVICE pic16F628, WDT_on  ‘Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON  ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Koruma kapalı
@ DEVICE pic16F628, MCLR_off  ‘MCLR pini kullanılmıyor.
@ DEVICE pic16F628,  INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘—————————————————————–
ON INTERRUPT GoTo KESME  ‘kesme oluşursa KESME adlı etikete git.
OPTION_REG=%10000000 ‘dahili  Pull up dirençleri iptal edildi
INTCON=%10001000 ‘Kesmeler  aktif ve RB CHANGE kesmesi aktif
CMCON=7 ‘16F628 de  komparatör pinleri iptal hepsi giris çıkıs
‘—————————————————————–
DURUM VAR BYTE
SYMBOL TUS=PORTB.0
SYMBOL LED=PORTA.0
SYMBOL RBIF=INTCON.0
‘——————————————————————-
BASLA: ‘Ana program bölümü
DURUM=PORTB
PAUSEUS 100
GOTO BASLA
DISABLE ‘yeniden kesme  oluşması önleniyor
KESME: ‘ burada kesme oluştu  demektir.
TOGGLE LED ‘LED konum  degistirdi
PAUSE 300
DURUM=PORTB ‘PortB degeri okundu
RBIF=0 ‘INTCON.0=0 yapıldı  yani RB CHANGE Bayragı (flag) silindi.
RESUME ‘geldigin yere dön.
ENABLE ‘kesmeler yeniden  aktif.
End
TMR0 KESMESİ : Ram bellegin 01 adresinde bulunan özel bir yazmaçdır. Genellikle adı üstünde zamanlayıcı olarak kullanılır. 8 bitlik bir sayıcıdır. Yazılabilir okunabilir. Programlanabilen bir özel bölücüsü (prescaler) vardır. Harici veya dahili clock palsları ile sayım yapabilir.
Sayma yönü daima artan yöndedir. Bu sayıcı veya zamanlayıcı 255 degerini astıgı zaman degeri tekrar sıfır olur ve bu anda bir kesme oluşturulabilir. Bu sayıcının diger önemli bir özelligi ise arka planda yani ana programdan bagımsız çalısmasıdır. Ana program çalısırken veya kesme oluştugu andan
itibaren saymasına devam eder.
OPTION Yazmacının ilk üç biti frekans bölme (prescaler) ayarlaması için kullanılır. Bu üç bitin aldıgı degerlere göre bölücünün aldıgı degerler asagıda gösterilmistir. Bu bölücü aynı zamanda WDT içinde kullanıldıgından tabloda WDT için bölücü degerleride gösterilmistir.
Tablodan da anlasılacagı üzere sinyal kaynagından gelen palsların TM0 sayıcısını 1/1 yani direkt saydıracagı bir konum mevcut degildir. Özellikle dısarıdan bir sinyal kaynagından gelen palsların sayılmasında lazım olacak olan bu husus için OPTION yazmacının 3. biti 1 (bir) yapılarak frekans bölme islemi WDT için yapılır.
Bu bir nevi aldatmadır. Bölme WDT için yapılınca Frekans bölücü TM0 için Bay-Pass edilmis yani atlanmıs olur. Dolayısıyla gelen sinyaller 1/1 olarak Timer0 tarafından sayılır. Bunu yapacagımız örnekte görecegiz.TM0 sayısının kullanılması için bazı parametrelerin önceden ayarlanması gerekiyor. Bunlar sırası ile;
1. Sayıcının sayabilmesi için gerekli olan clock sinyalinin kaynagı ne olacaktır?. Bu kaynak dahili osilatör olabilecegi gibi standart olarak PortA.4 /TOCKI bacagı kullanılarak dısarıdan bir sinyal kaynagı ile beslenebilir. Bu seçim OPTION yazmacının 5. biti olan TOCS biti ile yapılır.
TOCS biti = 0 ise sinyal kaynagı dahili osilatör dür. TOCS biti = 1 ise sinyal kaynagı PortA.4 pinin den giren harici sinyal kaynagıdır.
2. Harici sinyal kaynagı seçilir ise, sayacın düsen kenarda mı yoksa yükselen kenarda mı sayma isini yapacagı OPTION yazmacının 4. biti olan TOSE biti ile ayarlanır.
TOSE Biti = 0 ise düsen kenarda sayma
TOSE Biti = 1 ise Yükselen kenarda sayma yapılır.
3. Frekans bölme islemi TMR0 için mi yoksa WDT için mi geçerli olacaktır? Bunu seçmek için OPTIONyazmacının 3. biti olan PSA biti kullanılır.
PSA Biti = 0 ise Frekans Bölme TMR0 için geçerli,
PSA Biti = 1 ise Frekans Bölme WDT için geçerli olur.
4. Son olarak da Frekans bölme kullanılacak ise degeri ayarlanır. Bunun içinde OPTION yazmacının ilk 3 bitinin kullanıldıgını söylemistik. Tabloda verdigimiz degerlerden biri seçilerek OPTION yazmacına yazılır.
5. Programın bas kısmına ON INTERRUPT GOTO KESME komutu verilerek kesme oluştugunda programın gidecegi yer (KESME) belirlenir.
6. INTCON yazmacının 5. biti bu kesme için ayrılmıstır. Bu bit 1 yapılarak kesme aktif edilir.
7. Kesme bölümüne baslarken DISABLE komutu verilerek kesme anında yeniden kesme oluşumuna imkan verilmeyecek.
8. Kesme bölümünde INTCON.2=0 komutu verilerek kesmeden dolayı 1 olan bayrak tekrar sıfırlanır ve sonradan yeni kesme oluşmasına imkan tanınır.
9. Kesme bölümünün sonunda RESUME komutu verilerek programın kesme oluşmasından önceki yerine dönmesi saglanır.
10. En sona ENABLE komutu yazılarak kesmeden dönüldükten sonra tüm kesmeler aktif hale getirilir. Burada bir konuyu açıklamakta fayda görüyorum. Dahili veya harici osilatör kullanılması durumunda, frekans degerinin Pic’e baglı kristal degerinin dörtte biri olacağını bilmeniz gerekiyor. Diyelimki Pic 4 MHz lik bir kristal ile çalısıyor. O halde TMR0 için kullanılacak sinyal kaynagı 1 MHz frekansa sahip olacaktır.
Dahili osilatör ve Frekans bölücü pek çok uygulamalarda kullanılır. Özellikle hassas zamanlama islerinde önemli bir kullanım alanı vardır. Bunların basında Pic’in bir saat olarak kullanılması gelir. Dahili veya harici ösilatör ve frekans bölücü kullanılarak pic’in her bir saniyede bir kesme oluşturmasını saglayabiliriz. Sayet bu zamanı hassas bir sekilde ayarlayabilir isek dogru çalısan bir saat yapabiliriz. Simdi bunu bir örnek ile açıklayalım.
Yapacagımız örnek de 4 MHz de çalısan bir PIC16F628 kullanacagız. Dahili sinyal kaynagını kullanarak gelen sinyali 64’e bölecegiz. Bu durumda pic, TMR0’ ile 0 dan baslayıp 255’e kadar sayıp kesme oluşturabilmesi için ;
1 us x 64 x 256 = 16384 us süre kullanacaktır. 1 sn = 1000 ms ve oda 1000.000 us ye esit oldugundan sayet 1.000.000 us degerini 16384’e bölersek 61 degerini buluruz. O halde her kesme oluştugunda bir baska degiskeni saydırır ve bunun degeri 61 den 62 ye geçtigi anda degerini sıfırlayıp saniye degerini bir artırırsak bir saniyelik saat palslarını yakalamıs oluruz. Bunu bir programda kullanarak da saat yapabiliriz.
Bu örnek için bir semamız asagıdadır.





Programa geçmeden önce gerekli parametrelerimizi tespit edelim; Tespitlerimizin etki alanı OPTIONYazmacı olacağından tüm tespitleri Binary olarak bu yazmaca isleyecegiz.
1. Sinyal kaynagımız dahili osilatör olacaktır. O halde TOCS (5.bit) 0 olacaktır.
OPTION_REG=%00000000
2. Frekans Bölme islemi TMR0 için olacak olup 3. bit 0 olacaktır.
OPTION_REG=%00000000
3. Frekans bölme (prescaler) degeri 64 olacak olup bunun TMR0 için bit karsılıgı 101 dir.
OPTION_REG=%00000101
4. TMR0 kesmesini kullanacagımızdan INCON yazmacının 5. biti high olacaktır. Tüm Kesmeleri açmak için INTCON 7. biti high olacağından bu iki durumu tek komutta toparlarsak, INTCON=%10100000 seklinde bir komut yazmamız gerekir. Bu asamadan sonra programımızı verelim.
‘****************************************************************
‘* Name : KESMETMR0.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 23.04.2005 *
‘* Version : 1.0 *
‘* Notes : *
‘* : *
‘****************************************************************
PORTA=0:portb=0
TRISB=%00000000 ‘PortB tamamı çıkıs yapıldı.
TRISA=%00000000 ‘A portu  tamamı çıkıs yapıldı.
‘—————————————————————–
@ DEVICE pic16F628 ‘islemci  16F628
@ DEVICE pic16F628, WDT_OFF  ‘Watch Dog timer kapalı
@ DEVICE pic16F628, PWRT_ON  ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Koruma kapalı
@ DEVICE pic16F628, MCLR_off  ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628,  INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘—————————————————————–
DEFINE LCD_DREG PORTB ‘LCD  data bacakları hangi porta baglı?
DEFINE LCD_DBIT 4 ‘LCD data  bacakları hangi bitten baslıyor?
DEFINE LCD_EREG PORTB ‘LCD  Enable Bacagı Hangi Porta baglı?
DEFINE LCD_EBIT 3 ‘LCD  Enable Bacagı Hangi bite baglı ?
define LCD RWREG PORTB ‘LCD  R/W Bacagı Hangi Porta baglı?
define LCD_RWBIT 2 ‘LCD R/W  Bacagı Hangi bite baglı ?
DEFINE LCD_RSREG PORTB ‘LCD  RS Bacagı Hangi Porta baglı ?
DEFINE LCD_RSBIT 1 ‘LCD RS  bacagı Hangi Bite baglı ?
DEFINE LCD_BITS 4 ‘LCD 4 bit  mi yoksa 8 bit olarak baglı?
DEFINE LCD_LINES 2 ‘LCD Kaç  sıra yazabiliyor
‘————————————————————————-
ON INTERRUPT GoTo KESME  ‘kesme oluşursa KESME adlı etikete git.
OPTION_REG=%10000101 ‘Pull  up dirençleri İPTAL- Bölme oranı 1/64.
INTCON=%10100000 ‘Kesmeler  aktif ve TMR0 kesmesi aktif
TMR0=0
CMCON=7 ‘16F628 de komparatör pinleri iptal hepsi giris çıkıs
‘—————————————————————————-
SAYAC VAR BYTE
SN VAR BYTE
DAK VAR BYTE
SAAT VAR BYTE
GUN VAR BYTE
‘—————————————————————————–
CLEAR ‘tüm degiskenler  sıfırlandı
PAUSE 200
LCDOUT $FE,1
LOW PORTB.2 ‘LCD -R/W bacagı LOW’a çekildi.
‘—————————————————————————–
BASLA:
LCDOUT $FE,$84,DEC2 SAAT,”:”,DEC2  DAK,”:”,DEC2 SN
GOTO BASLA

DISABLE
KESME:
SAYAC=SAYAC+1 ‘kesme sayacı 1 sn= 61(sayac) x 256 (Tmr0) x 64  (bölme)
IF SAYAC=61 then ‘61 adet  kesme olunca 1 sn. süre geçiyor.(999424 us)
SAYAC=0 ’sayaç sıfırlanıyor
SN=SN+1 ’saniye degeri bir  artırılıyor
IF SN=60 THEN ’saniye 60  olmus ise 1 dakika süre geçti o halde
SN=0 ‘ saniye sıfırlanıyor
DAK=DAK+1 ‘ dakika degeri  bir artırılıyor
IF DAK=60 THEN ‘dakika 60  olmus ise 1 saat süre geçti
DAK=0 ‘ dakika sıfırlanıyor
SAAT=SAAT+1 ‘ saat degeri  bir artırılıyor
IF SAAT=24 THEN ’saat 24  olmus ise 1 gün geçti
SAAT=0 ’saat sıfırlanıyor
GUN=GUN+1 ‘gün degeri bir  artırılıyor
IF GUN=365 THEN GUN=0 ‘gün  365 olmus ise
ENDIF ‘gün sıfırlanıyor 1  yıl geçti
ENDIF
ENDIF
ENDIF
INTCON.2=0 ‘TMR0 Kesme bayragı sıfırlanıyor
RESUME
ENABLE
END
‘———————————————————————————–
Her ne kadar hesap sonucunda kesmenin oluşturacagı gecikme yaklasık 1 sn hesaplanmıs isede pratikte program komutlarınında bir gecikmeye sebep olacağı unutulmamalıdır. Yukarıdaki programda KESME bölümünde bir çok komut bulunmaktadır. Makine dilinde her bir komut yaklasık (4MHz de) 1 us süre almaktadır. Bu nedenle hesaplama dogru olsa da saat ileri gidebilir veya geri kalabilir. Bunun için SAYAC degeri her 61 kesme yerine 60 – 59 -58 kesmede bir saniye artırımı yaptırılabilir. En iyisi programın yazılması tamamlanınca bir dogru çalısan bir saat yardımı ile süre karsılastırması yapılmalı ve gerekirse SAYAC degeri ile oynanarak hassas bir ayarlama yapılmalıdır.
Burada ikinci bir örnek daha verecegiz ve saat’in baska ilerde nasıl kullanılacagına bakacagız. Diyelim ki 4 adet tus ile kontrol edilen 4 adet rölemiz var ve bunlar bir takım sistemleri çalıstırıyorlar. Her bir röle ayrı bir sistemi çalıstırıyor ve biz hangi sistemin ne kadar çalıstıgını bilmek istiyoruz. İste yazacagımız program 4 adet tus yardımı ile 4 adet röleyi çalıstıracak ve arka planda ise TMR0 kesmesi yardımı ile saatimiz çalısacak.
Bu programda ayrıca yeni bir degisken tipi ile tanısacagız. Dizi degiskeni. Dizi degiskenleri aynı isimle açılırlar ancak her bir degiskenin bir indeks denilen parametresi vardır. Indeks ayrı bir degisken altında saklanabilir ve degeri degistirilerek istenilen dizi degiskenine kolaylıkla ulasılabilir. Kullanımı degisken tanımlarında söyle yapılmaktadır.
DEGER var Byte [4] burada deger adlı degiskenin 4 ayrı indeksli çesidi vardır. Bunlar ;
DEGER[0] – DEGER [1] – DEGER [2] ve DEGER [3] dür.
Önce programla ilgili semamızı verelim;



Dikkat edilirse semada röle yerine logic prop baglanmıstır. Bunların yerine asıl devrede birer role baglanacaktır. Ancak asıl amacımız programın islevini göstermek oldugundan detaya girilmemistir.
İste programımız;

‘****************************************************************
‘* Name : KESME-R0LE.BAS *
‘* Author : [E.Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 23.04.2005 *
‘* Version : 1.0 *
‘* Notes : *
‘* : *
‘****************************************************************
PORTA=0:portb=0
TRISB=%00001111 ‘PortB (RB4-RB7) çıkıs digerleri giris yapıldı.
TRISA=%00000000 ‘A portu  tamamı çıkıs yapıldı.
‘—————————————————————–
@ DEVICE pic16F628 ‘islemci  16F628
@ DEVICE pic16F628, WDT_OFF ‘Watch Dog timer kapalı
@ DEVICE pic16F628, PWRT_ON ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF  ‘Kod koruma kapalı
@ DEVICE pic16F628, MCLR_off  ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628,  INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘—————————————————————–
DEFINE LCD_DREG PORTA ‘LCD  data bacakları hangi porta baglı?
DEFINE LCD_DBIT 0 ‘LCD data  bacakları hangi bitten baslıyor?
DEFINE LCD_EREG PORTA ‘LCD  Enable Bacagı Hangi Porta baglı?
DEFINE LCD_EBIT 7 ‘LCD  Enable Bacagı Hangi bite baglı ?
DEFINE LCD_RSREG PORTA ‘LCD  RS Bacagı Hangi Porta baglı ?
DEFINE LCD_RSBIT 6 ‘LCD RS  bacagı Hangi Bite baglı ?
DEFINE LCD_BITS 4 ‘LCD 4 bit  mi yoksa 8 bit olarak baglı?
DEFINE LCD_LINES 2 ‘LCD Kaç  sıra yazabiliyor
‘————————————————————————-
ON INTERRUPT GoTo KESME  ‘kesme oluşursa KESME adlı etikete git.
OPTION_REG=%10000101 ‘Pull  up dirençleri İPTAL- Bölme oranı 1/64.
INTCON=%10100000 ‘Kesmeler  aktif ve TMR0 kesmesi aktif
TMR0=0
CMCON=7 ‘16F628 de komparatör pinleri iptal hepsi giris çıkıs
‘—————————————————————————-
SAYAC VAR BYTE
SN VAR BYTE[5]
DAK VAR BYTE[5]
SAAT VAR BYTE[5]
GUN VAR BYTE
DURUM var byte
I VAR WORD
ESKI VAR BYTE
ROLE VAR BYTE
‘—————————————————————————–
CLEAR ‘tüm degiskenler  sıfırlandı
PAUSE 200
LCDOUT $FE,1
‘—————————————————————————–
BASLA:
LCDOUT $FE,$84,DEC2  SAAT[0],”:”,DEC2 DAK[0],”:”,DEC2 SN[0]
DURUM=PORTB & %1111
IF DURUM>0 THEN PORTB=DURUM
ESKI=PORTB | DURUM*16
ROLE=NCD ESKI ‘NCD KOMUTU  SAYIDAKİ EN YÜKSEK HİGH OLAN BİTİ VERİR
ROLE=((ROLE>0)&%1)*(ROLE-4)  ‘BİR ÇOK İSİ GÖREN TEK BİR KOMUT
LCDOUT $FE,$C0,”ROLE=”,#ROLE,”  “,DEC2 SAAT[ROLE],”:”,DEC2
DAK[ROLE],”:”,DEC2 SN[ROLE]
PORTB=ESKI
FOR I=0 TO 2000
PAUSEUS 10
NEXT I
GOTO BASLA
DISABLE
KESME:
SAYAC=SAYAC+1 ‘kesme sayacı 1 sn= 61(sayac) x 256 (Tmr0) x 64  (bölme)

IF SAYAC=61 then  ‘61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
SAYAC=0 ’sayaç sıfırlanıyor
SN[0]=SN[0]+1
IF ROLE=0 then ATLA
SN[ROLE]=SN[ROLE]+1 ’saniye degeri bir artırılıyor
ATLA: IF SN[0]=60 THEN  ’saniye 60 olmus ise 1 dakika süre geçti ohalde
SN[0]=0
SN[ROLE]=0 ‘ saniye sıfırlanıyor
DAK[0]=DAK[0]+1
DAK[ROLE]=DAK[ROLE]+1 ‘ dakika degeri bir artırılıyor
IF DAK[0]=60 then ‘dakika 60  olmus ise 1 saat süre geçti
DAK[0]=0
DAK[ROLE]=0 ‘ dakika sıfırlanıyor
SAAT[0]=SAAT[0]+1
SAAT[ROLE]=SAAT[ROLE]+1 ‘ saat degeri bir artırılıyor
IF SAAT[0]=24 THEN ’saat 24  olmus ise 1 gün geçti
SAAT[0]=0
SAAT[ROLE]=0 ’saat sıfırlanıyor
GUN=GUN+1 ‘gün degeri bir  artırılıyor
IF GUN=365 THEN GUN=0 ‘gün  365 olmus ise
endif ‘gün sıfırlanıyor 1  yıl geçti
ENDIF
ENDIF
ENDIF
INTCON.2=0 ‘TMR0 Kesme bayragı sıfırlanıyor
RESUME
ENABLE
END
‘—————————————————————————–
Sayac=61 satırında 61 sayısı 1 sn lik süreyi ayarlamaktadır. Program komutlarındaki gecikmeler nedeni daha hassas bir ayarlama gerekebilir. Bir saatle birlikte kontrol edilerek pic saati geri kalıyorsa degeri azaltılmalıdır. İleri gidiyor ise artırılmalıdır. Programla iligli genel açıklamalar; Bu programda ileri programlama teknikleri kullanılmıstır. Program satırlarını esas alarak açıklamaya çalısalım.
‘——————————————————————————————————–
LCDOUT $FE,$84,DEC2 SAAT[0],”:”,DEC2 DAK[0],”:”,DEC2 SN[0]
‘——————————————————————————————————–
Programda saat için 5 adet indeks li degisken kullanılmıs idi. Bunun amacı her bir röle için ayrı bir zaman tutmak ve sıfır ile çalısan indeks degerini de ana saat için kullanmaktır. Yani saat(0) sistemin ana saati olacak Saat(1-4) arası ise her bir röleye ait olacaktır. Yukarıdaki komutta görüldügü gibi [0] indeksi kullanılmıs ve dolayısıyla sistem ana saati LCD üst satırında ekrana verilmistir.
‘——————————————————————————————————–
DURUM=PORTB & %1111
‘——————————————————————————————————–
Bu komutta Tusların hangisine basıldıgını kontrol etmek için tek bir komut kullanılmıstır. PORTB degeri okunarak 15 (%1111) sayısı ile AND islemi uygulanmıstır. Dolayısıyla PortB nin ilk 4 biti filtre edilerek ayrılmıs olacak ve bu bitlerden hangisi 1 ise (tusa basılmıs ise) belirlenecektir.
‘——————————————————————————————————–
IF DURUM>0 THEN PORTB=DURUM
‘——————————————————————————————————–
Burada herhangi bir tusa basılmıs ise eski basılmıs olanı iptal etmek ve yenisini devreye sokmak için bu komut kullanılmıstır.
‘——————————————————————————————————–
AKTIF=PORTB | DURUM*16
‘——————————————————————————————————–
Burada basılan tusa paralel olarak hangi rolelin aktif hale getirilecegi hesaplanmaktadır. Bir yerde basılan tuşun bit degeri 4 bit sola kaydırılarak PortaB ye verilmektedir. Hangi rölenin aktif oldugunu ise asagıdaki komut hesaplamaktadır.
‘——————————————————————————————————–
ROLE=NCD AKTIF ‘NCD KOMUTU SAYIDAKİ EN YÜKSEK HİGH OLAN BİTİ VERİR
‘——————————————————————————————————–
NCD komutu bir sayı içindeki en yüksek degerlikli high olan bitin konumunu verir. Örnek vermek gerekir iseSAYI=%00010000 ise NCD SAYI komutu bize 5 sayısını verecektir. En yüksek high 5. sıradaki 1 dir. Bu komut yardımı ile basılan tusa göre hangi rolenin aktif oldugunu belirliyoruz. Ancak bu belirleme bize PORTB deki sırayı verecektir.
Yani 4-8 arası bir deger. Halbuki biz 1. Role – 2. Role … 4.Role demek isteriz. Dolayısıyla bu degeri 1-4 arası degere indirgememiz gerekir. Burada islem aslında basit Hesaplanan degerden 4 çıkartır isek bize 1-4 arası degeri verir. Ancak ya deger 0 (sıfır) ise. Bu durumda 0-4 bize 65531 gibi bir deger verirki buda sistemin hata yapmasına sebep olur. Bu durumda sayet Role degeri sıfır ise bu hesabı yapmadan atlamamız gerekir. Akıllıca bir programlama mantıgı ile bu isi tek komutla halledebiliriz.
‘——————————————————————————————————–
ROLE=((ROLE>0) & %1)*(ROLE – 4) ‘BİR ÇOK İSİ GÖREN TEK BİR KOMUT
‘——————————————————————————————————–
Bu komut bizi birkaç defa if kullanmaktan kurtarır. Bu komut asagıdaki program satırlarının görevini yapmaktadır;
‘——————————————————————————————————–
IF ROLE=0 THEN Hesap yapma ve Ekrana bir sey yazma
IF ROLE>0 then ROLE= Role-4 hesabını yap
‘——————————————————————————————————–
Simdi komut nasıl çalısıyor bir bakalım;
(ROLE>0) & %1 komutunda (ROLE>0) ifadesi bir logik operatör kullanan bir aritmetik ifadesidir. Role>0 ise degeri 255, Role=0 ise degeri 0 dır. Dolayısıyla bunu %1 ile AND islemine tabi tutar isek Role 0 dan büyük olunca degeri 1, sıfıra esit olunca ise degeri 0 olarak gelir. Bu ifadeyi (ROLE-4) ile çarpar isek istedigimizi elde etmis oluruz.
Yani:
1 x (Role-4) burada Role 0 dan büyük oldugundan role degeri 1-4 arası çıkacaktır.
0 x (Role-4) ki burada Role 0 oldugundan sonuç 0 olacaktır.
‘——————————————————————————————————–
LCDOUT $FE,$C0,”ROLE=”,#ROLE,” “,DEC2 SAAT[ROLE],”:”,DEC2 D
DAK[ROLE],”:”,DEC2 SN[ROLE]

‘——————————————————————————————————–
Komutu ile aktif olan role ile o röleye ait saat degeri ekrana getirilmektedir.
‘——————————————————————————————————–
PORTB=AKTIF
‘——————————————————————————————————–
Aktif olan role ekrana verilmektedir. Kesme oluşmasında kolaylık saglamak üzere 20 ms lik gecikme us cinsinden döngü kullanılarak verilmektedir.
‘——————————————————————————————————–
FOR I=0 TO 2000
PAUSEUS 10
NEXT I

‘——————————————————————————————————–
GOTO BASLA
‘——————————————————————————————————–
Goto basla ile program tekrar basa yönlendirilmektedir. Programın Kesme kısmında ise 1 sn lik süre Sayac=61 sayısı ile kontrol edilmekte ve bu süre sonunda Sn=Sn+1 komutu ile degeri bir artırılmaktadır. Sn degerinin 60’ı geçmesi halinde dakika ve paralel olarak saat ve gün degerleri artırılmaktadır.
Buradaki diger önemli nokta ise o andaki ROLE degeri ki burada indeks olarak kullanılmakta esas alınarak o roleye ait saat degeri ise ayrıca saydırılmaktadır. Tabiiki hiçbir role aktif degil ise role degeri 0 olacağından sistem ana saati saydırılmaktadır.

6.ders  Proteus ve hex dosyaları Download


7.ders:

Bu dersimizin konusu Seri İletisim. Konuya seri iletişimin ne oldugunu açıklayarak baslayalım. Dijital bilgi bilindigi üzere bitlerden olusmaktadır. Her bir bit ya 0 (sıfır) yada 1 (bir) olabilmektedir. Bunlar yana yana gelince daha büyük digital bilgiyi olusturmaktadır. Örnegin 8 adet bit 1 adet BAYT bilgisini olusturmakta 16 adet bit ise 1 adet WORD bilgisini olusturmaktadır.
Simdi gelelim bu bilgilerin başka yerlere aktarılması isine. 8 bitlik bir bilginin tek bir seferde başka bir üniteye aktarılması için 8 adet bağlantı ucu kullanırsak yani her bir bit için bir uç kullanır isek bu bir paralel aktarma islemidir. Yine 8 bitlik bir bilgiyi başka bir üniteye tek bir uç kullanılarak aktarmak istersek bu bir seri aktarma islemidir. Her iki sistemde ilave uçlarda olacaktır. Ancak biz sadece bilginin aktarılması için gereken uçlardan bahsediyoruz. İste üzerinde duracagımız konu bu seri bilgi aktarma sistemidir.
Bu sistemde verici ve alıcı ünite bir birlerine tek bir data hattı ile bağlanırlar. Verici gönderdigi bitleri belirli bir formatta yani belirli zaman içinde belirli sayıda bit gönderir. Bu sekilde olusturulan senkronizasyon ile 8 adet bitin gönderilmesi yapılır ve alıcıda bu bitleri teker teker alır. Alıcı ile verici nin bireysel çalısma hızlarının farklılıgından dolayı seri iletişimde bir kural vardır.
Kural birim zaman içinde gönderilen veya alınan bit sayısı ile ifade edilen BAUD RATE yani haberlesme hızı dır. Alıcı ve vericinin aynı senkron içinde alıs verislerinin yapılabilmesi için bu hızın her iki taraf için aynı değere ayarlanması gerekir. Sistemin başka parametreleri de bulunmaktadır. Gönderilen bilginin invert edilmesi her baytın sonunda bir stop biti gönderilmesi , parite kontrolu vs. gibi. İsin teferruatına fazla girmeden konuyla ilgili komutların kullanımına geçecegiz. Basic de seri iletişim komutları birkaç tanedir. Bunları sırası ile açıklayacagız. İlk komutumuz;
SERIN Pin,Mode,{Timeout,Label,}{[Qual...],}{Item…}
Standart Asenkron Seri data giris komutudur. Yani başka bir seri data gönderebilen bir üniteden gelen bilgiyi almak için kullanacagımız komutlardan birisidir. Parametrelerine bakacak olur isek; SERINkomutundan hemen sonra seri datanın alındıgı pin yer almaktadır. Burada PortA.0 veya PortB.2 gibi port pinleri kullanılır. İkinci parametre Mode dir.
Komut yukarıdaki hali ile Mod numaralarının kullanımına imkan tanımaktadır. Sayet komutu Mode isimleri ile kullanmak isterseniz programınızın bas tarafına ; Include “modedefs.bas” Komutunu ilave etmeniz gerekir. Her bir mod da bilginin düzmü yoksa inver edilmis hali ilemi alındıgı bellidir. Sistemin default olarak ayarlanmıs diğer parametreleri şöyledir.
8 data biti , no parity ve 1 stop biti seklindedir. Genel gösterim 8N1 seklindedir. diğer parametre olan ve gerektiginde kullanılmayan Timeout parametresi dir ve 1 ms (milisaniye) cinsinden belirlenir. Anlamı ise burada verilen süre içerisinde herhangi bir data alınmaz ise program Label parametresi ile belirlenen konuma atlar. Dolayısıyla Label’i de açıklamıs oluyoruz. Burada bir program bölümünün ismi (etiketi) verilir .
Bir sonraki parametre qualifier olup belirleyici anlamında kullanılır ve birden fazla olabilir. Genellikle dogru haberlesme yapılabilmesi için gönderilen bilgilerin basına belirli ifadeler yerlestirilir. Bu yerlestirilen bilgilere qualifier denir. Bu bilgiler rakam olabilecegi gibi bir karekter diziside olabilir. En son parametre ise gelen bilginin depolanacagı degisken simidir ve ITEM olarak gösterilmistir.
Buraya kullanacagınız degisken adı yazılacaktır. Örnek vermek gerekir ise ; SERIN PortA.0 , 0 , [“ERO”] , ISI Bu komutta qualifier olarak kullanılan bilgi “ERO” bilgisidir. Program gelen bilgilere sürekli bakacak ve önceden “ERO” bilgisini alır ise arkasından gelen ilk bilgiyi ISI degiskenine koyacaktır. Aksi taktirde ISI degiskeni oldugu gibi kalacaktır. Bu sistem, haberlesmede yanlıs data alımını önleyen güzel bir sistemdir.
Diğer Bir komut SERIN2 komutudur. Serin komutuna benzer bir komuttur. SERIN2 , GIRIS , 396 , [WAIT ("W"), DEC AL] Bu komutda da önce data alıs pini belirlenir ve pin otomatik olarak giris olarak ayarlanır. Daha sonra haberlesme hızı belirlenir.
Bu hız için değişik bir hesaplama mantığı kullanılmaktadır. Formül şöyledir. Haberlesme Hızı= (1.000.000/Baud Rate)-20 Örnek verecek olur isek , 2400 baud için hız hesaplayalım Hız= (1.000.000/2400)-20 = 396 olacaktır. (yukarıdaki komutta yazıldıgı gibi) Daha sonra belirli bir karakter veya karakter dizisinin alınması beklenir. Bu karekterlerden sonrada esas data Bin, hex veya dec formatlı olarak alınır.
diğer bir komut HSERIN komutu olup yalnızca Hardware Serial Port’u (USART) olan Pic’ler için kullanılabilir. Bu port PIC16F628 , PIC16F876, PIC16F877 gibi pic lerde bulunmakta 16F84/A da bulunmamaktadır. Dolayısıyla bu komutu kullanabilmemiz için öncelikle kullandıgımız Pic’in bu porta sahip olup olmadıgını ögrenmemiz gerekecektir. Komutun kullanım sekli şöyledir. HSERIN {ParityLabel,}{Timeout,Label,}[Item{,...}] Bu komutun parametreleri Define komutu ile belirlenir. Bunlar; DEFINE HSER_RCSTA 90h (alma yazmacının Enable edilmesi)
DEFINE HSER_TXSTA 20h (gönderme yazmacının Enable edilmesi)
DEFINE HSER_BAUD 2400 (Haberlesme hızının belirlenmesi)
Komutun kullanım sekli genelde asagıdaki sekilde dir HSERIN [BILGI, DEC ZX] Bu komutta tüm parametreler DEFINE komutu ile verilmistir. Dolayısıyla parametre olarak yalnızca Bilgi isimli bir degisken ve arkasından Desimal olarak alınacak olan ZX degiskeni görülmektedir.
Bu komutun en önemli özelligi giris pinlerinin USART özelligine bağlı olarak önceden belirlenmis olmasıdır. Bu pinlerin hangisi oldugu Datasheetler de gösterilmektedir ve kullanıcı tarafından degistirilemez. Dolayısıyla komutun kullanımında pin adı görmezsiniz. Komutun başka bir kullanılıs sekli asagıda gösterilmektedir.
HSERIN 300,ATLA,[WAIT ("ER"),AL]
Bu komutta Timeout süresi 300 ms olarak verilmis ve bu süre sonunda programın ATLA isimli etikete gitmesi saglanmıstır. Komut gelen bilgiler arasında ER karakterlerini arayacak buldugu anda pesinden gelen bilgiyi AL degiskenine yerlestirecektir. Simdiye kadar vermis oldugumuz komutlar data alıs komutları idi. Aynı komutların bir de Data gönderme komutları vardır ve tek fark datanın gönderilmesi dir. Bu komutlarda bir data gönderme pini belirlenir.
HSEROUT komutunda bu pin standart olup degistirilemez. Ancak Serout veya serout2 komutlarında kullanıcı tarafından istenildigi sekilde tanımlanır. Seri haberlesme konusunda son olarak önemli bir konuya dikkatinizi çekmek istiyorum. Pic ve benzeri cihazlarda lojik seviyeler TTL seviyesindedir. Yani bir (1) sinyali +5V , sıfır (0) sinyali ise GND seviyesindedir.
Bu cihazlar kendi aralarında haberlesir iken arada herhangi bir seviye düzenleyici sistem gerekmez. Zira high olarak gönderilen sinyal her iki taraf için +5V dur. Low olan ise GND seviyesindedir. Ancak pic ve benzeri cihazlar bir PC ile haberlesmesi gerektiginde gönderilen veya alınan sinyallerin seviyelerinin düzeltilmesi gerekir. Zira PC lerde High sinyali -12V , low sinyali ise +12 V dur.
Bu is için RS232 çevirici entegresi kullanılması gerekiyor. Genellikle adı MAX 232 veya CP232 olarak geçer. Bu entegrenin RS232 giris ve çıkıs bacakları bulunmaktadır. Dolayısıyla Pic den gelen sinyali (+5V veya 0V – High veya Low) PC nin anlayacagı seviyelere (-10V veya +10v) çevirir. Aynı sekilde PC den gelen sinyalleri de Pic’in anlayacagı seviyelere çevirmektedir.
Dolayısı ile Pic-PC arası yapılacak seri haberlesme devrelerinde bu çeviricinin kullanılması
gerekir. Komutlarla ilgili bu kadar bilgi verdikten sonra örneklerimize geçelim; İlk örnegimiz basit bir Seri iletişim örnegi olacak. SERIN ve SEROUT komutlarını kullanarak bir rolenin çalıstırılmasını gerçeklestirecegiz.
Bunun için 2 adet Pic li devre kullanacagız. Birinci devremiz verici olarak çalısacak ve üzerinde yalnızca iki adet tus bulunacaktır. diğer devremiz ise alıcı olarak çalısacak ve üzerinde 2 adet LED ve 2 adet Role bağlı olacaktır. Önce şemamızı verelim;
Proje 7/1 : Seri – Ver – Al


İlk programımız SERI-VER.BAS

‘****************************************************************
‘* Name : SERI-VER.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 11.05.2005 *
‘* Version : 1.0 *
‘* Notes : SERI-AL.BAS programının vericisidir. *
‘* : *
‘****************************************************************
@ DEVICE pic16F628 ‘islemci  16F628
@ DEVICE pic16F628, WDT_on  ‘Watch Dog timer kapalı
@ DEVICE pic16F628, PWRT_ON ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Protek kapalı
@ DEVICE pic16F628, MCLR_off  ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628,  INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘——————————————————————————
CMCON=7 ‘16F628 de  komparatör pinleri iptal hepsi giris çıkıs
OPTION_REG.7=0 ‘Dahili  pull-up lar AKTİF yapıldı ayrıca pull-up direncine gerek yok
PortA=0
TrisA=%00000000
PortB=0
TrisB=%00000011
‘——————————————————————————
SYMBOL CIKIS=PORTA.0
SYMBOL TUSA=PORTB.0
SYMBOL TUSB=PORTB.1
VER VAR BYTE
‘——————————————————————————
PAUSE 200
VER=0
‘——————————————————————————
BASLA: VER=0
IF TUSA=0 THEN
VER=88
gosub gonder
WHILE TUSA=0
WEND
endIF
IF TUSB=0 THEN
VER=66
gosub gonder
WHILE TUSB=0
WEND
endif
PAUSE 100
GOTO BASLA

‘—————–ALT PROGRAMLAR——————————-
GONDER:
SEROUT2 CIKIS,396,["E","T","E",ver]
SEROUT2 CIKIS,396,["E","T","E",ver]
return
END
İkincisi ise SERI-AL.BAS ,

‘*****************************************************************
‘* Name : SERI-AL.BAS *
‘* Author : [E.T.E] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 13-02-2005 *
‘* Version : 41.00 *
‘* Notes : SERI-VER.BAS PROGRAMININ ALICISIDIR*
‘* : *
‘*****************************************************************
PORTA=0
PORTB=0
TRISA=%00000001 ‘A portu A.0 giris diğerleri çıkıs yapıldı.
TRISB=%00000000 ‘B portu  tamamı çıkıs yapıldı.
‘—————————————————————–
@ DEVICE pic16F628 ‘islemci  16F628
@ DEVICE pic16F628, WDT_on ‘Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON  ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Koruma kapalı
@ DEVICE pic16F628, MCLR_OFF  ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628,  INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘—————————degiskenler——————————
AL VAR BYTE
GIRIS VAR PORTA.0
ROLEA VAR PORTB.0
ROLEB VAR PORTB.1
LEDA VAR PORTB.6
LEDB VAR PORTB.7
‘—————————–B A S L A N G I Ç —————————
CMCON=7
CLEAR
PAUSE 500
PORTB=0 ‘tüm çıkıslar low seviyesinde
‘——————————————————————————-
BASLA:
SerIn2 GIRIS,396,[WAIT ("ETE"),AL]
IF AL=88 THEN
TOGGLE LEDA
TOGGLE ROLEA
ENDIF
IF AL=66 THEN
TOGGLE LEDB
TOGGLE ROLEB
ENDIF
PAUSE 200
GOTO BASLA
END
Seri haberlesme isinde en önemli faktörlerin basında alıcı ile vericiyi aynı anda karşı karşıya getirmektir. Bunun muhtelif yolları vardır. Senkronizasyon denilen bu islem için genelde kullanılan yöntem önden bir uyandırma sinyalinin gönderilmesi arkasından belirleme datası ve onun arkasından ise esas gerekli olan data nın gönderilmesidir.
Uyandırma sinyali nedir diyeceksiniz buna genellikle preambl sinyali denilmektedir. Uyandırma sinyali bir sinyal kombinasyonudur. Muhtelif sekillerde olabilir. Benim kullandıgım ve olumlu netice aldıgım kombine sinyal asagıdaki sekildedir.
- İlk sinyal %10101 seklinde bir sinyal arkasından %00000 ve onun arkasından ise %11111 seklinde bir sinyal dir. Bunun komut karşılıgı; SEROUT2 CIKIS,396,[REP$AA5,REP$005,REP$FF5]
Haberlesmeye baslamadan önce bu komut verilerek karşı taraftaki devrenin alıs moduna geçmesi saglanır. Bu komutun arkasından esas göndermek istediginiz bilgiler gönderilir. Önce belirleme bilgisi yani; (”E”),(”T”),(”E”) bilgisi burada bir belirleme bilgisidir.
Örnek;
SerOut2 CIKIS,396,[("E"),("T"),(”E”),EKLE]
Pesinden esas göndermeniz gereken bilgi veya bilgiler dizisi gönderilir. Sonuçta yukarıdaki örnekte EKLE adlı degisken de yer alan değer göndermek istedigimiz bilgi olmaktadır.
Senkron konusunda hata yapılmaması için genelde gönderme komutu birkaç defa arka arkaya tekrarlanır. Sayet yazılan program satırı çok az ise tek komut da yeterli olabilir. Ancak uzun programlarda gönderme komutunun artırılması gerekir.
Örnek olarak;
SerOut2 CIKIS,1646,[("E"),("R"),EKLE]
SerOut2 CIKIS,1646,[("E"),("R"),EKLE]
SerOut2 CIKIS,1646,[("E"),("R"),EKLE]
SerOut2 CIKIS,1646,[("E"),("R"),EKLE]
SerOut2 CIKIS,1646,[("E"),("R"),EKLE]
Örnekte görüldügü gibi en az 5 defa tekrarlanmasında yarar vardır. Bir mahsuru olmadıgı gibi yararı vardır.
Alma komutu tek olabilir. Çünkü senkron saglandıktan sonra gelen sinyallerden birini mutlaka görüp alacaktır. Bu kadar açıklama dan sonra daha komplike bir Seri haberlesme programına geçelim.
Diyelim ki bir televizyona uzaktan kumanda devresi yapmak istiyoruz. Bu devre ile televizyonu açıp kapatmak, volum kontrolu yapmak ve hem Kanal+ ve Kanal- tuşlarını kullanarak kanallar arasında gezinmek hemde sabit kanal (1-5) tuşlarını kullanarak kanal seçmek istiyoruz. İki adet pic kullanacagız. Bu sefer 16F84A kullanalım. Çünki devrenin aslı 16F84 ile yapılmıs idi. Devre şemasını vermeden önce bazı konulara açıklık getirmek gerekiyor.
Volum kontrolu ve program gezinmesi yapacagız. Volum kontrolu için digital pot kullanabilirdik. Ancak program kontrolü açısından bu iside kendimiz yapalım istiyoruz. Hem Volum kontrolu hemde program
gezinmesi için 4051 (Analog swich) kullanacagız.
4051’in ABC adres bacakları 1 adet giris-çıkıs bacagı ve bu bacagın seçilen adrese göre Analog olarak bağlanabildigi 8 adet giris-çıkıs bacagı bulunmaktadır. Volum kontrolu için 16 kademe volum elde etmek üzere 2 adet (2×8=16) 4051 kullanacagız ve toplamda 16 adet volum seviyemiz olacak. Program gezinme için toplam 8 adet kanal çıkısımız olacak.
Bahsini ettigim projeyi bizzat uygulama fırsatım oldu. Sistem hala basarı ile çalısmaktadır. İsin mantıgını izah edecek olur isek, verici olarak çalısan pic üzerinde bulunan ;
- açma / kapama tusuna basıldıgında karşı taraftaki pic de bir pin high / low olacak. (toggle çalısma)
- Volum+ tusuna basıldıgında volum artacak yani 2 adet 4051 çıkısları sırası ile konum degistirecek.
- Aynı sekilde Volum- tusuna basıldıgında yapılan isin tersi yapılacak.
- Program+ tusuna basıldıgında program kademesi bir artacak. Basılı tuttukça artam devam edecek.
- Program- tusuna basıldıgında bu sefer seçim isi terse dönecek.
- Sabit program seçme tuşlarından birine basıldıgında ise ilgili tusa karşılık gelen pin karşı tarafta toggle olarak çalısacak. Ancak bu pin açık olan diğer pinleri iptal edip yanlıca kendisi çıkıs verecek. Bir ayrıntıyı daha izah etmekte fayda görüyorum. İki pic arasındaki bağlantıda bir inverter (NOT) kullanılmıstır. Aslında gerekli olmayan bu elemanı Seri haberlesme komutlarında alıcı veya vericiden birini invert edilerek kullanılmasını göstermek amacı ile yaptım.
İste şemamız. Biraz karısık gibi gelebilir ama iyice takip edilirse kimin nereye bağlı oldugu kolaylıkla görülecektir.
Önce Verici Kısmına ait programı verelim;

‘****************************************************************
‘* Name : Verici4.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 11.05.2005 *
‘* Version : 1.0 *
‘* Notes : ALICI4.BAS programının vericisidir. *
‘* : *
‘****************************************************************
INCLUDE “MODEDEFS.BAS”
TRISA=%11110
TRISB=255
OPTION_REG.7=1 ‘pull-up lar iptal
‘——————————————————————————-
CIKIS VAR PORTA.0
VER VAR BYTE
TUS VAR BYTE
POZ VAR BIT
poz=0
‘——————————————————————————-
START : VER=0
TUS=PORTB
IF TUS =1 Then BIR ‘basılan veya basılı tutulan tusun değeri
IF TUS =2 Then IKI ‘burada  okunuyor
IF TUS =4 Then UC
IF TUS =8 Then DORT
IF TUS =16 Then BES
IF TUS =32 Then ALTI
IF TUS =64 Then YEDI
IF TUS =128 Then SEKIZ
POZ=0:GoTo START
BIR: IF POZ=1 Then START ‘on/off tusu basılı tutuluyor ise islem  yapma
POZ=1
VER=11
GoTo EXIT ‘On/off tusuna ilk basıldı tus değeri=11 gönder.
IKI: VER=22
GoTo EXIT ‘Volum+ tusuna basıldı tus değeri=22 , gönder
UC: VER=33
GoTo EXIT ‘Volum- tusuna basıldı tus değeri=33, gönder
DORT: VER=44
GoTo EXIT ‘Program+ tusuna basıldı Tus değerini gönder
BES: VER=55
GoTo EXIT ‘Program- tusuna basıldı tus değerini gönder
ALTI: IF POZ=1 Then START ‘Sabit Program tuşları toggle yapacak
POZ=1
VER=66
GoTo EXIT
YEDI: IF POZ=1 Then START ‘Sabit program tuşları toggle yapacak.
POZ=1
VER=77
GoTo EXIT
SEKIZ:IF POZ=1 Then START ’sabit program tuşları toggle yapacak
POZ=1
VER=88
EXIT: SerOut CIKIS,T2400,[("A"),VER,13,10] ‘tus değerini gönder,  değer ters çevrilmemistir
GoTo START
END
Program kısa oldugu için preambl sinyali kullanmadık. Simdi Alıcı Kısmını verelim;

‘****************************************************************
‘* Name : Alıcı4.BAS *
‘* Author : [Erol Tahir Erdal] *
‘* Notice : Copyright (c) 2005 [ETE] *
‘* : All Rights Reserved *
‘* Date : 11.05.2005 *
‘* Version : 1.0 *
‘* Notes : Verici4.BAS programının alıcısıdır. *
‘* : *
‘****************************************************************
TRISA=%00001
TRISB=0
GIRIS VAR PORTA.0
VOLUM VAR BYTE
ARA VAR BYTE
PROG VAR BYTE
ERO VAR BYTE
KON VAR BYTE
NE VAR BIT
SES VAR BYTE
POZ VAR BYTE
AL VAR BYTE
‘——————————————————————————-
INCLUDE “MODEDEFS.BAS”
PORTB=0
PORTA=0
Read 0,VOLUM ‘volum değeri Pic’in eepromundan sıfır nolu adresten  okunuyor
IF VOLUM=255 Then ’sayet  herhangi bir değer önceden kayıt edilmemis ise
VOLUM=3 ‘default volum  seviyesini 3 kabul ediyoruz.
EndIF
Read 1,PROG ‘hangi programın seçili bırakıldıgını yine eeprom 1  adresten
IF PROG=255 Then ‘okuyoruz  ve herhangi bir program kayıtlı degil ise
PROG=0 ‘default program=0  kabul ediyoruz.
EndIF
KON=VOLUM>>3 ‘Volum konumu ara değer
SES=VOLUM-(KON*8): ‘volum  esas değeri
ARA=(SES+PROG*8)+128-(KON*64) ‘hem program hemde ses değeri 8 bit olarak
PORTB=ARA ‘toparlanıp PortB  ye yazılıyor.
‘——————————————————————————-
START : AL=0
Serin GIRIS,N2400,[ "A" ],AL ‘Basılan tus bilgisini al
IF AL=11 Then BIR ‘basılan  tus değeri 11 ise Bir’e git
IF AL=22 Then IKI ‘22 ise  IKI ye git
IF AL=33 Then UC ‘33 ise UC e  git
IF AL=44 Then DORT ‘44 ise  DORT’ e git
IF AL=55 Then BES
IF AL=66 Then ALTI
IF AL=77 Then YEDI
IF AL=88 Then SEKIZ
POZ=0
GoTo START
BIR: Toggle PORTA.1 ‘ON / OFF ‘On/off çıkısı toggle yapıldı
CIK:GoTo START
IKI:VOLUM=VOLUM+1 ‘ volum tusuna basılmıs volum bir artırıldı
IF VOLUM>15 Then ’sayet  15 den büyük ise 15 de kal
VOLUM=15
EndIF
‘Volum<8 1.4051="" ise="">8 ise 2.ci 4051 devrede olacak
VOLKAY:KON=VOLUM>>3 ‘Kon=%00001101 ise  Kon=%00000001 oluyor
SES=VOLUM-(KON*8)  ‘Ses=13-(8×1)=5 bulunuyor.
ARA=PORTB & 56 ‘ARA  değeri program seçimi için 4051′in adresi
ARA=ARA+SES+128-(KON*64)  ‘Volum ABC değeri + Prog ABC değeri +
PORTB=ARA ‘Volum 4051 seçim  değeri tamamı PortB ye yazılıyor
Write 0,VOLUM ‘yeni Volum  değeri EEPROM’a yazılıyor
Pause 44
GoTo START
UC: VOLUM=VOLUM-1 ‘Volum- tusuna basılmıs değer bir azaltılıyor
IF VOLUM=255 Then ‘değer  sıfırı geçerse tekrar sıfırda kalıyor.
VOLUM=0
EndIF
GoTo VOLKAY ‘degisen volum değerini kayıt et
DORT: PROG=PROG+1 ‘program  tusuna basılmıs bir artır.
IF PROG>7 Then
PROG=0
EndIF
PORKAY: ARA=PORTB & 199 ‘199=%11000111 olup 4051 select ve  adres değerini al
ERO=PROG<<3 span="" style="color: green; margin: 0px; padding: 0px;">‘yeni  program değerini hesapla ve kayıt et
ARA=ARA+ERO ‘PROG=6 olsun ERO=%00011000 oldu PORTB=ARA ‘ARA=Volum ABC + Prog ABC ve Selec değerleri toplamı Write 1,PROG ‘Önce porta yazılıyor Prog değeri Eeproma kayıt ediliyor Pause 74 GoTo START BES: PROG=PROG-1 IF PROG=255 Then ‘PROGRAM ASAGI PROG=7 EndIF GoTo PORKAY ALTI: Toggle PORTA.2 ’sabit program tuşlarından birine basılmıs GoTo START YEDI: Toggle PORTA.3 GoTo START SEKIZ:Toggle PORTA.4 GoTo START end
Programlarda özellikle Alıcı programında bazı hesap satırları var bunların açıklanmasında fayda görüyorum.
şemadan görülecegi üzere, B portu B0-B1-B2 pinleri ile Volum için çalısan 2 adet 4051 entegresini adreslemektedir. Adres değeri 0-15 arasında degismekte olup 0-7 arasındaki değerler ilk 4051’i adreslemekte 8-15 arasındaki değerlerde ise otomatik olarak ikinci 4051 seçilerek adres değeri bu entegrenin kullanacagı (0-7) değerine indirgenerek kullanılmaktadır.
B portunun B3-B4- ve B5 nolu pinleri ise program seçimi için kullanılan 4051 entegresini adreslemektedir. Kalan B6 ve B7 pinleri ise Volum entegrelerinden hangisi seçilecek ise onu aktif hale getirmek için kullanılmaktadır (chip Select). Simdi hesap sistemini inceleyelim. Önce Volum kayıt bölümüne bakalım;
KON=VOLUM>>3 ilk satırda bu komut bulunmaktadır. Volum değerini 3 bit saga kaydırıp yeni değeri KONadlı degiskene yerlestir anlamındadır. Neden bu isi yaptıgımızı bir sonraki satırda açıklayacagız. Sonra gelen satırda ;
SES=VOLUM-(KON*8) seklinde bir islem var. 2 adet 4051 entegremiz var ama her ikiside aynı adreslemeyi kullanıyor. Dolayısıyla adres olarak verecegimiz değer 0-7 arasında olacaktır. Halbuki bizim Volum değerimiz 0-15 arasında değişiyor. Bu hesap ile Ses seviye adreslemesini volum değerine bağlı olarak 0-7 seviyesine düsürmekteyiz.
Diyelim ki Volum seviyemiz 14 olsun. Bu durumda KON= 14 >> 3 = %00001110 değeri %0000001olacaktır. Yani KON=1 olacaktır. SES=14 – (1*8) = 6 yani volum için 4051 adres değeri 6 (%00000110 )olacaktır. ARA=PORTB & 56 (56=% 00111000 dir ve bu program seçme adres değeridir)ARA=ARA+SES+128-(KON*64) Volum için hangi 4051 seçili olacak buna 128-(Kon*64) hesabı karar vermektedir.
Örnegimizde Kon=1 idi 64*1=64 olup 128-64=64 olacaktır. Dolayısıyla B6 veya B7 den hangisi Low ise ona bağlı entegre seçilmis olmaktadır. Bu hesap sonucunda B7’ye bağlı olan entegre seçilmis olacak çünki volum değeride 14 idi yani 7 den büyük idi. Volum değeri 8 den küçük olur ise yukarıdaki hesap 128 olarak çıkacak olup böylece ilk 4051 seçilmis olur otomatikman. Böylece PortB deki tüm bitlerin durumunu hesap etmis oluyoruz.
Bunları toplar isek; ARA= ARA + 6 + 64 = ARA+70 olarak bulunan değer direkt Port B ye yazılarak islem
tamamlanır. Benzer bir hesap Program tusuna basılınca da yapılmaktadır. Bu hesabın çözümünüde size
bırakıyorum.
Bu program içinde geçen ara komutlara bir göz atmakta fayda var. Bunların basında READ ve WRITEkomutları geliyor.
Pic lerin pek çogunda eeprom hafızası oldugunu hepimiz biliyoruz. Bazı durumlarda bu hafızaları kullanmak gerekir. Elektrik ile yazılıp silinen bir hafıza oldugundan yazılan bir değer özellikle silinmedikten sonra Pic’in voltajını da kesseniz silinmez. Bu yüzden saklanması gereken bilgiler burada saklanabilir. Bu programda da Volum ve Program değerleri bu hafıza da saklanmıstır. Bu sayede televizyonu kapattıgınız anda hangi programda kaldınız ise ve volum seviyeniz ne ise tekrar açtıgınızda aynı seviyelere ulasmıs oluyorsunuz.
Simdi gelelim komutlar nasıl kullanılıyor.Pic hafızaları 8 bitlik yani 1 baytlık hafızadır. Her hafızanın 0 (sıfır) dan baslayan bir adres numarası vardır. Bu adres numarası kullanılarak istenilen bir adresteki hafızaya ulasılabilir.Hafıza ya yazma için kullandıgımız komut WRITE dır. Parametreleri Adres ve yazılacak değerdir. Yani komut;
WRITE 0 (adres), BILGI (yazılacak değer) olarak çalısmaktadır. Hafıza dan okuma yapmak için kullandıgımız komut ise READ komutudur. Aynı sekilde adres ve değer parametresi vardır.
Kullanılıs sekli;
READ 0(adres), BILGI (okunacak değer) olarak dır. Yazma ve okuma islemi yaklasık 10 ms kadar bir sürede yapılır. Sayet program içinde kesme kullanılıyor ise hatalar ortaya çıkabilir. Bunu önlemek için bu komutlardan önce kesme iptal edilmelidir (disable ile degil direkt iptal) . İslemden sonra kesme tekrar açılmalıdır.



7.ders  Proteus ve hex dosyaları Download

8.ders:
Bu dersimizde Pic mikro işlemcilere dışarıdan bağlanan aletleri inceleyeceğiz. Dışarıdan bağlanabilen aletler olarak;
1. Tuş takımları (keyboard)
2. LED display ler
3. Port Çoğullayıcılar

1. TUŞ TAKIMI KONTROLU:

Tuş takımları matriks bağlantı şeklinde çalışırlar. Yatay ve dikey hatları vardır. Tuşun birisine basıldığı zaman tuşun bağlı olduğu yatay hat ile dikey hat tuş üzerinden kısa devre edilir. Hatlardan birisini siz lojik olarak kontrol edersiniz diğerine ise lojik olarak bakarsınız. Bir örnekle açıklamak daha uygun olacak sanırım Diyelim ki aşağıdaki şekilde bir tuş takımını kontrol etmek istiyoruz.
Amacımız basılan tuşun değerini ekranda göstermek tabii ki sonra bu değerleri bir işte kullanmak. Tuş takımında 1-2-3 numaralarla işaretlenen dikey hatları PortB de 1-2-3 nolu pinlere bağlayıp bunları giriş olarak ayarlıyoruz. A-B-C-D olarak işaretlenen yatay sıraları ise PortB de 4-5-6 ve 7 nolu pinlere bağlayıp bu pinleri de çıkış olarak ayarlıyoruz.
Burada önemli olan bir nokta var. Giriş olarak ayarlanmış pinlerin ya pull-up veya pull-down yapılması gerekmektedir. Biz örneğimizde PortB nin kendisinde olan Pull-Up dirençlerini kullanarak giriş pinlerini Pull-Up’lı olarak kullanacağız. Şimdi gözünüzde canlandırmanızı isteğim bir durum var. Dikey hatlar pull-up lı olarak High seviyesinde bekliyorlar.
Yatay hatların hepsinde çıkış olarak ayarlandı ve bunların hepsine de High uyguluyoruz. Sonuçta tuş takımına baktığımız anda yatay ve dikey hatların tamamı lojik-1 seviyesinde olduğunu görüyoruz. Şimdi basılan tuşu tespit etme işine başlayabiliriz. A ile isimlendirilen Yatay hattı (çıkış olarak ayarlanmış idi) LOW yapıyoruz. Tuş takımında şimdi yalnızca A yatay hattı LOWLOW olur. seviyesindedir. Şimdi bakalım, şayet ben 1 nolu tuşa basar isem ne olur? Tabiiki yatay hat ile dikey hat kısa devre olacağından 1 nolu dikey hat hemen
Şayet 2 nolu tuşa basar isem bu defada 2 nolu dikey hat LOW olur. Aynı şekilde 3 nolu tuşa basar isem 3 nolu dikey hat LOW olur. işte bu özellikten yararlanarak basılan tuşu tespit edebiliriz.
işe şöyle başlarız;
LOW YATAY-A ‘Önce A yatay hattını LOW yaparız. IF Dikey-1=0 Then TUS=1 ‘Şayet Dikey-1 LOW ise demek ki basılan Tuş=1 dir. IF Dikey-2=0 Then TUS=2 ‘Şayet Dikey-2 LOW ise demek ki basılan Tuş=2 dir. IF Dikey-3=0 Then TUS=3 ‘Şayet Dikey-2 LOW ise demek ki basılan Tuş=3 dür.
Buraya kadar 1. yatay sıradaki tuşları kontrol etmiş olduk. Şimdi 2. yatay sıradakileri kontrol edelim,
LOW YATAY-B IF Dikey-1=0 Then TUS=4 ‘Şayet Dikey-1 LOW ise demek ki basılan Tuş=4 dir. IF Dikey-2=0 Then TUS=5 ‘Şayet Dikey-2 LOW ise demek ki basılan Tuş=5 dir. IF Dikey-3=0 Then TUS=6‘Şayet Dikey-2 LOW ise demek ki basılan Tuş=6 dür.
Buraya kadar 2. yatay sıradaki tuşları da kontrol etmiş olduk. Şimdi 3. yatay sıradakileri kontrol edelim,
LOW YATAY-C IF Dikey-1=0 Then TUS=7 ‘Şayet Dikey-1 LOW ise demek ki basılan Tuş=7 dir. IF Dikey-2=0 Then TUS=8 ‘Şayet Dikey-2 LOW ise demek ki basılan Tuş=8 dir. IF Dikey-3=0 Then TUS=9‘Şayet Dikey-2 LOW ise demek ki basılan Tuş=9 dür.
Buraya kadar 3. yatay sıradaki tuşları da kontrol etmiş olduk. Şimdi 4. yatay sıradakileri kontrol edelim,
LOW YATAY-D IF Dikey-1=0 Then TUS=11 yani ( * ) tuşu‘Şayet Dikey-1 LOW ise demek ki basılan Tuş=11 dir. IF Dikey-2=0 Then TUS=0 ‘Şayet Dikey-2 LOW ise demek ki basılan Tuş=0 dır. IF Dikey-3=0Then TUS=12 yani ( # ) tuşu‘Şayet Dikey-2 LOW ise demek ki basılan Tuş=12 dir.
Bu şekilde tuşların tamamını kontrol etmiş oluyoruz. işin temeli bu kadardır. Kısaca tekrarlamak gerekir ise ya dikey yada yatay hatların tamamını giriş olarak ayarlayın. Bunları giriş yaptınız ise , Pull-up (veya Pull-down) dirençleri ilave edin.
Matriks in diğer ucundaki hatları ise çıkış olarak ayarlayın. Sonra sıra ile çıkış olarak ayarladığınız sıraları lojik seviyesini değiştirerek girişte aynı değişikliği arayın. Olan var ise aynı hatlara bağlı tuş basılmış demektir.
Şimdi tuş konusu ile ilgili program örneğimizi verelim.

‘**********************************************
 
‘* Name : TUSTAKIMI.BAS *
‘* Author : [E.T.E] *
‘* Notice : Copyright (c) 2005 Ete] *
‘* : All Rights Reserved *
‘* Date : 24.06.2005 *
‘* Version : 1.0 *
‘* Notes : *
‘* : *


‘****************************************************


trisa=%00000000
trisb=%00001110


@ device pic16f628a
@ device pic16f628a, wdt_off
@ device pic16f628a, pwrt_on
@ device pic16f628a, protect_off
@ device pic16f628a, mclr_off
@ DEVICE pic16F628a, INTRC_OSC_NOCLKOUT


CMCON=7
OPTION_REG.7=0 ‘pull-up dirençleri aktif
tus var word


Define LCD_DREG PORTA
Define LCD_DBIT 0
Define LCD_RSREG PORTA
Define LCD_RSBIT 4
Define LCD_EREG PORTA
Define LCD_EBIT 6
Define LCD_BITS 4
Define LCD_LINES 2


Symbol YATAY_A= PORTB.4
Symbol YATAY_B= PORTB.5
Symbol YATAY_C= PORTB.6
Symbol YATAY_D= PORTB.7

Symbol DIKEY_1= PORTB.1
Symbol DIKEY_2= PORTB.2
Symbol DIKEY_3= PORTB.3


Tus=0
Pause 200
Lcdout $fe, 1

BASLA:
PORTB =254
YATAY_A=0
If DIKEY_1=0THEN
Tus=1:GOSUB EKRAN
While DIKEY_1=0
Wend
Endif


If DIKEY_2=0 Then
Tus=2:GOSUB EKRAN
While DIKEY_2=0
Wend
Endif


If DIKEY_3=0 Then
Tus=3:GOSUB EKRAN
While DIKEY_3=0
Wend
Endif
High YATAY_A
YATAY_B=0
If DIKEY_1=0 Then
Tus=4:GOSUB EKRAN


While DIKEY_1=0
Wend
Endif


If DIKEY_2=0 Then
Tus=5:GOSUB EKRAN
While DIKEY_2=0
Wend
Endif


If DIKEY_3=0 Then
Tus=6:GOSUB EKRAN
While DIKEY_3=0
Wend
Endif


High YATAY_B
YATAY_C=0
If DIKEY_1=0 Then
Tus=7:GOSUB EKRAN
While DIKEY_1=0
Wend
Endif


If DIKEY_2=0 Then
Tus=8:GOSUB EKRAN
While DIKEY_2=0
Wend
Endif


If DIKEY_3=0 Then
Tus=9:GOSUB EKRAN
While DIKEY_3=0
Wend
Endif


High YATAY_C
YATAY_D=0
If DIKEY_1=0 Then
Tus=11:GOSUB EKRAN
While DIKEY_1=0
Wend
Endif


If DIKEY_2=0 Then
Tus=0:GOSUB EKRAN
While DIKEY_2=0
Wend
Endif
If DIKEY_3=0 Then
Tus=12:GOSUB EKRAN
While DIKEY_3=0
Wend
Endif
High YATAY_D
pause 100
Goto BASLA
EKRAN:


Lcdout $fe,1,”Tus= “,#tus
pause 50
RETURN
END

2. LED DISPLAY KONTROLU:

Led display ler 7 segment display ler olarak piyasada isimlendirilmektedirler. Genelde ortak Anot ve ortak Katot bağlantılı tipleri mevcuttur. Ortak Anot olanlar ortak şase olarak + beslemeyi, Ortak Katot olanlar ise ortak şase olarak GND yi kullanırlar. Biz örneklerimizde ortak katot display’i inceleyeceğiz. Tercihimiz yalnızca anlatım kolaylığı açısındandır. 7 segment display in A-B-C-D-E-F-G olarak adlandırılan pin uçları vardır. Her bir pin’e High uygulanır ise bağlı olduğu segment ışıldar.
Bu sistemle display üzerinde sayılar oluşturulur. Normal olarak her bir display in (Ortak Anot veya Katot) kendi sürücüleri vardır. Bu sürücüler genelde ABCD olarak BCD (Binary Coded Desimal) olarak sürülürler. Yani siz ABCD girişlerine bir rakam verirseniz yonganın diğer ucu display’e bağlı olduğundan verdiğiniz rakam display’de görülür. Ancak bu sürücüler yalnızca 0-9 arası rakamları görüntüleyebilirler. Bunun dışında displayin gösterebileceği karakterleri gösteremezler. Bu nedenle Pic işlemcilerle birlikte bu sürücüler genelde kullanılmaz.
Bu kadar teorik bilgi verdikten sonra konunun Pic işlemcilerle olan alakasına geçelim. Pic işlemcilerle bu tip display leri kullanırken birkaç teknik kullanılır. Şayet özel karakter yazdırılmayacak ise genelde 4511 tipi bir sürücü kullanılır. Bu sürücünün çıkışları LATCH yani kilitli olduğundan pic ile kullanmaya ve mültipleks çalışmaya son derece elverişlidirler. Özel karakterlerin kullanılması durumunda yine Latch (kilit) leri olan shift register (seriden paralele çevirici) kullanmak en uygunu olacaktır. Bu konuda da en iyi yongalardan biriside 74HC595 tir.
Öncelikle 4511 li bir uygulamayı inceleyelim. işin temelinde görüntülenmesi gereken her bir bilgi (dijit) ortak bilgi hatta verilir. Sonradan bu bilginin istenen led display’de görüntülenmesini sağlamak amacı ile yalnızca o displayin latch (kilidi) açılarak ortak hattan gelen bilginin çıkışa aktarılması sağlanır. Bu bilgi tekrar değiştirilinceye kadar çıkışta kalacağı için display’de bir titreme (yanma¬sönme) olmadan istenen bilgi görüntülenmiş olur.
Şekilde görülen devre bir encoder den gelen palsları sayan bir devredir. Sayılan değer led display den görüntülenmektedir. Şekilde görüldüğü gibi, 4511 lerin ABCD girişleri ortak hatlar olarak kullanılmış ve bu girişler Pic 16F628 ‘in PortA da 0-1-2 ve 3 nolu port uçlarına bağlanmıştır. 4511 lerin segment çıkışları led display’lere bağlanmış ve en önemlisi 4511 lerin LatchEnable (LE) uçlarının her biri pic in bir pinine bağlanmıştır.
Şimdi, 4511 lerin tüm ABCD girişleri ortak bağlantı şeklinde olduğundan Pic den ABCD bilgisi olarak bir bilgi çıkarırsak ve latch ları enable (LOW a çekilir ise) yaparsak verdiğimiz bilgi tüm displaylarda görülür. Örneğin 2 bilgisini oluşturacak şekilde ABCD girişlerine %0010 bilgisini verirsem tüm display’lerde 2 rakamını görürüm.
Şayet ben 2 rakamının yalnızca ilk (soldan birinci) displayda görülmesini ister isem o zaman yalnızca ilk 4511’in LE ucunu (normalde sürekli HiGH da duruyor) önce Low yapar sonra tekrar High yaparım. Diğerlerine dokunmam. Bu durumda ilk display de 2 rakamını okurum. Diğerleri önceden ne kayıtlı ise o rakamları göstermeye devam ederler. işte bu teknik ile son derece hızlı bir şekilde ve ekranda titreme olmaksızın rakamlar görüntülenebilir.
Şimdi konuyla ilgili program örneğimizi yapalım. Aşağıdaki programda iki tane buton var. Ayrıca 2 adet Led display göreceksiniz. Tuşlardan üstte olana basılınca sayı bir artırılacak ve artırılan sayı ekranda görülecek. Alttakine basılınca da sayı bir azaltılacak ve yine sayı display de gözlenecek. Önce devremiz;
Kodlar:
Daha öncede belirttiğim gibi 4511 kullanarak yalnızca sayıları display da görüntüleyebiliriz. Aynı display bize C veya
(0) şeklini de gösterebilir veya (-) eksi işaretini gösterebilir. Örnek olarak bir sıcaklık göstergesi yaptık ve display de 23,3 0C şeklini görmek istiyoruz. işte bu durumda 4511 display sürücüsünü kullanamayız. Bu durumda kullanılacak en uygun yonga 74HC595 shift registerdir.
Şimdi bu yonganın kullanımına bir örnek verelim,


Şimdi aynı ekranın diğer karakterler ile nasıl göründüğüne bakalım.
Görüldüğü üzere 74HC595 bize istediğimiz görüntü imkanlarını sağlayabiliyor. Şimdi bu yonganın nasıl çalıştığına ve kontrol edildiğine bir bakalım.
16 Pin li bir yonga olan 74HC595 in en önemli özelliği data bacağı (14 nolu pin) ile Clock bacağı (11 nolu pin) kullanılarak seri yoldan bilgi registerine yazılabiliyor. Ancak yazılan bu bilgi hemen çıkışta görülemiyor. Görülebilmesi için bilgi aktarma bacağı olan (12 nolu pin) pine bir clock palsının uygulanması gerekiyor. Bu özellik bize bu yonganın display sürücüsü olarak kullanılması imkanını veriyor. Basic de Shiftout komutunun olduğunu biliyorsunuz. Bu komut bize datapin, clockpin, mode , (değişkenler) şeklinde kullanılarak 8 bitlik bir bilginin seri olarak gönderilmesini sağlar. Komutun parametrelerinden biri olan Mode ise bilgi göndermede aşağıdaki işlemler için kullanılır;
0. Önce 0 nolu data bitini çıkışa ver ve en sonda 7. biti gönder. Sonuçta Clock Low da kalsın.
1. Önce 7. biti , en sonda 0. biti gönder ve Clock Low da kalsın.
4. Önce 0. Biti, en sonda 7. biti gönder Clock High da kalsın
5. Önce 7. biti ve en sonda 0. biti gönder ve Clock High da kalsın.
74HC595 Shift Register de işlemler kontrol pinleri LOW da iken yapılmaktadır. Bu nedenle biz mode olarak 2. seçeneği seçeceğiz. Bunun Mode değeri 1 dir.
Yonganın kullanımına geçmeden bir LED display de karakterler nasıl oluşuyor bu konuyu biraz incelememiz gerekecek. Sıfır rakamının displayda oluşması için , segmentlere kontrol eden bitlerden,

olması gerekiyor. Aynı şekilde 1 rakamını görebilmek için sağda yer alan 1 ve 2. bitlerin bir diğerlerinin sıfır olması gerektiğini hemen anlamışsınızdır. Yine 3 rakamını oluşturmak için 0,1,2,3 ve 6. bitlerin bir diğerlerinin sıfır olması gerekir. Aynı mantık ile sayılar veya karakterlere göre bitlerin durumunun ne olması gerektiğini aşağıda belirtmekteyiz.

Şimdi 74hc595 yongasına yukarıda belirtilen karakterlerin görüntülenebilmesi için karakterlerin sayı karşılığının nasıl verileceğini inceleyelim.
Önce bir LOOKUP tablosu yapıyoruz. Lookup bir Basic komutudur. indeks kullanılarak indeks değerine karşılık gelen sıradaki değerin tablodan alınmasını sağlar. Bizim Lookup tablomuz aşağıdaki gibi olacaktır. Burada X bizim indeksimiz olacak ve tablodaki sayılarda sırası ile 0,1,2,3,4,5,6,7,8,9, 0,C karakterlerine karşılık gelmektedir. Şimdi X=3 şeklinde X (indeks) değişkenine 3 sayısını verip Lookup tablosuna gönderir isek, 3. sıradaki değer SAYI değişkenine koyularak geri dönecektir. Yani ; X=3:GOSUB LOOKUP şeklinde bir program komutu verir isem dönüşte SAYI=79 olarak gelecektir. Bunu öğrendikten sonra şayet ben göstereceğim karakterlerin sayı karşılıklarını bu tablodan alıp Shift Registere verir isem ve registerin çıkışlarına display bağlar isem istediğim karakteri görüntüleme şansım olacaktır. işte 74HC595 kullanmanın mantıksal temeli budur. Şimdi bir Lookup tablosu oluşturup, bu tablodan aldığımız değeri 74HC595 yongasına yazalım.
X=5 ‘yani görüntülemek istediğim karakter “5” olacaktır. GOSUB TABLO ‘Tabloya git ve 5 indeksine karşılık gelen 109 sayısını SAYI değişkenine koy ve dön SHIFTOUT DataPin , ClockPin ,1, [SAYI] ‘sayı değerini bit-bit clock ve data pinleri kullanarak ilet. HiGH AktarPini (Latch) : PAUSEUS 2 : LOW AktarPini ‘burada registere yazılan sayı bilgisinin aktarma pinine bir
‘pals verilerek yani önce HiGH ve sonra LOW yapılarak çıkışa verilmesi sağlanıyor. TABLO: LOOKUP X,[63,6,91,79,102,109,125,7,127,111,99,57],SAYI :RETURN
Kısaca özetler isek, görüntülemek istediğimiz karakterin sayısal karşılığını tespit edip bu sayıyı Shiftout komutu ile Shift registere yazıyoruz. Sonra, registerin aktarma pinine bir pals uyguluyoruz (HiGH – LOW) ve böylece registere yazdığımız bilgi register çıkışlarına aktarılmış oluyor. Bu bilgi değiştirilinceye kadar çıkışta kalmaktadır. Böylece sürekli olarak display’e verilen bu bilgi sayesinde display de istediğimiz karakterin sürekli görülmesini sağlamış olmaktayız.
işin görüntüleme kısmını öğrendikten sonra geriye istediğimiz display de istediğimiz bir karakterin görüntülenmesini sağlamak kalıyor. Bu işlem bir önceki konuda bahsettiğimiz mantıkla yapılmaktadır. Yani hangi display’e yeni karakter verecek isem sadece onu süren Shift Registerdeki bilgiyi yenilerim . Böylece istediğim display de istediğim görüntüyü elde etmiş olurum. Açıklamalarımızı bir örnek ile pekiştirelim. Konunun başında vermiş olduğumuz devre bir Saat + Termometre devresidir. Program ekranda hem saati hemde sıcaklık değerini görüntülemektedir.
Bu sistemin programı aşağıda verilmektedir.





3. PORT ÇOĞULLAMA :

Bildiğiniz gibi pic işlemcilerin sınırlı sayıda giriş ve çıkış pinleri bulunmaktadır. Bazı durumlarda bu pinler ihtiyacımızı karşılamaz ve daha fazla çıkış veya giriş pinine ihtiyaç duyarız. işte bu gibi durumlarda kullanabileceğimiz yongalar mevcuttur. ilk inceleyeceğimiz konu çıkış çoğullama olacaktır. Diyelim ki birkaç tane port pini kullanarak daha fazla çıkış pinine sahip olmak istiyoruz.
Bu gibi durumlarda kullanabileceğimiz güzel bir yonga var adı 74HC595 shift register. Bu yongayı daha önce saat örneğimizde incelemiş idik. Burada kısaca tekrar nasıl çalıştığını ve bu yongadan nasıl yararlanacağımız açıklayalım. 16 Pin li bir yonga olan 74HC595 in en önemli özelliği, data bacağı (14 no lu pin) ile Clock bacağı (11 no lu pin) kullanılarak seri yoldan bilgi registerine yazılabiliyor.
Ancak yazılan bu bilgi hemen çıkışta görülemiyor. Görülebilmesi için bilgi aktarma bacağı olan (12 no lu pin) pine bir Clock palsının uygulanması gerekiyor. Bu durumda 3 adet pin kullanarak 8 adet çıkış elde edebiliriz demektir. Zira 74HC595 çıkış pinlerini sanki pic’e ait çıkış pinleri olarak kullanabilirim. Bunun için önce hangi pinden High , hangi pinden Low çıkarmak istiyor isem bununun binary karşılığını bulurum.
Örnek vermek gerekir ise; Çıkarmak istediğim bilginin bit karşılığı şöyle olsun %11001100 bu binary sayının desimal karşılığı 204 dür. Demek ki ben 74HC595’e 204 bilgisini seri olarak verirsem ve registere yazılan bu bilgiyi sonradan çıkışa aktarırsam çıkışta %11001100 bilgisini görebilirim.
ilk örneğimiz bahsini ettiğimiz basit örnek olacaktır. Yalnızca 3 adet bacak kullanarak 8 adet çıkış elde edeceğiz. Programda BILGI adında bir değişken tanımlayıp sırasıile 1 – 2 – 4 – 8 – 16 – 32 – 64 – 128değerlerini almasını sağlayacağız. Bu değerler 8 bitlik bir sayının bitlerinin rakam karşılıklarıdır. Bu değerleri verdiğimizde 74 HC 595’in çıkışlarının sırası ile HiGH olduğunu göreceksiniz.
Önce devremizi verelim;




ve programımız;

Burada bir soru sormak isterim. 74HC595’in çıkışlarını 1-8 arası numaralandırırsak, Diyelim ki 3 ve 6. pinlerden High çıkarmak istiyorum. Ne yapmalıyım?.
Cevap basit tabii ki. isteğimin binary karşılığı %00100100 ve desimal karşılığı ise 36 rakamıdır. Dolayısı ile programı aşağıdaki şekilde verir isek istediğimiz yerine gelecektir.
BILGI=36
SHIFTOUT DTA,CLK,1,[BILGI]
HIGH AKTAR
PAUSEUS 5
LOW AKTAR
Bu satırların sonunda istediğim bitler High olacaktır.
Görüldüğü üzere yalnızca 3 bit (pin) kullanarak 8 adet çıkış elde ettik. O halde 6 adet pin kullanır isek toplam 16 adet çıkış yapabiliriz. Bunu da size ödev olarak bırakıyorum.
Giriş Çoğullama için 74165 yongasını kullanacağız. Bu bir paralel yüklemeli 8 bit seri shift Registerdir. Şimdiye kadar gördüğümüz shift registerlerinde data seri girilip çıkış 8 bit paralel olarak alınıyor idi. Şimdi bu işlemin tersini yapacağız.
Yani datayı 8 bit paralel girip bu bilgiyi 8 bit seri bilgi haline çevireceğiz. Girişleri input olarak kullanabileceğimiz için yine 3 adet pin kullanarak 8 adet giriş elde etmiş olacağız. Öncelikle 74165 yongasını biraz incelememiz gerekiyor.
8 adet (D0-D7) data girişi bulunmakta 1 adet Clock girişi (2 nolu pin) 1 adet Data çıkışı (9 nolu pin) ve 1 adet Paralel Load pini (1 nolu pin) bulunmaktadır. Girişler D0-D7 data pinlerinden yapılmakta, Paralel load pinine bir pals uygulanarak giriş bilgilerinin dahili registere yazılması sağlanmakta ve sonradan Clock ve Data pini kullanılarak registerdeki bilgi D7-D0 olarak yani tersten başa doğru seri olarak alınmaktadır. Açıklamalarımızı bir programla uygulayalım.
Önce Devremiz,

Devremiz ve yazacağımız programda amacımız tuşlardan hangisine basarsak karşılığı olan biti PortB de High yapmak. Yani 1 nolu tuşa basmış isem PortB.0 High olacak. Aynı şekilde şayet 8 nolu tuşa basmış isem PortB.7 High olacak.
Şimdi programımızı inceleyelim.

Aslında gördüğünüz gibi program gayet basit ve kısa. Tuşlardan birine bastığım anda bilgi registere aktarılıyor ve seri olarak okunup PortB ye veriliyor. Hepsi bu kadar.
Bir programda hem giriş hemde çıkış çoğullama sı yapabilirsiniz. Bunun için iki ayrı Clock ve iki ayrı data pini sembol olarak tanımlanmalıdır. Tabiiki aktarma pinleri de farklı olacaktır. Bunlara dikkat ettikten sonra program yukarıda verilenler örnek alınarak kolaylıkla yapılabilir.



8.ders  Proteus ve hex dosyaları Download

0 yorum: