PİC PROJE ÖRNEKLERİ
  Pic Basic Pro Öğreniyoruz 8
 

Pic Basic Ders – 8 

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ı LOW 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 LOW olur.
Ş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. İşte bu özellikten yararlanarak basılan tuşu tespit edebiliriz.
 
İş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=0 Then 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.
İş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.
 
'****************************************************************
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.
İş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 HİGH 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. İş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;
 
 
 
 
Programımız ise şöyle;
 
'****************************************************************
@ DEVICE pic16F84A 'işlemci 16F628
@ DEVICE pic16F84A, WDT_on 'Watch Dog timer kapalı
@ DEVICE pic16F84A, PWRT_ON 'Power on timer açık
@ DEVICE pic16F84A, PROTECT_OFF 'Kod Protek kapalı
@ DEVICE pic16F84A, XT_OSC   ‘4 MHz Kristal osilatör kullandık
 
PortA=0
TrisA=%00000011    ‘portA.0 ve PortA.1 giriş diğerleri çıkış yapıldı
PortB=0
TrisB=%00000000    ‘PortB tamamı çıkış yapıldı.
 
Symbol TUSA=PORTA.0
SYMBOL TUSB=PORTA.1
SAYI     var byte
BIRLER   VAR BYTE
ONLAR    VAR BYTE
 
PORTB=0
SAYI=0
'--------------------------------------------------
 
PAUSE 200
 
 
BASLA:
      IF TUSA=0 THEN                           ‘Şayet ilk tuşa basılmış ise
        SAYI=SAYI+1 
PAUSE 150            ‘Sayı değerini bir artır ve 150 ms bekle
        IF SAYI=100 THEN SAYI=99         ‘Sayı 100 olmuş ise 99 yap çünki 2 digit displayimiz var.
      ENDİF
     
      IF TUSB=0 THEN                             ‘Şayet ikinci tuşa basılmış ise
        SAYI=SAYI-1
        PAUSE 150              ‘Sayı değerini bir azalt ve 150 ms bekle
        IF SAYI=255 THEN SAYI=0           ‘sayı 255 olmuş ise (sıfırdan sonra tekrar 255 olur) sayı yı 0 yap.
      ENDİF
     
      BIRLER=SAYI DIG 0                        ‘Birler hanesi Sayının sıfırıncı digitidir.
      ONLAR= SAYI DIG 1                        ‘Onlar hanesi sayının birinci digitidir.
     
      PORTB=240 | BIRLER                     ‘PortB nin üst 4 biti daima High olmalı bu nedenle 240 kullanıyoruz.
      LOW PORTB.5                                 ‘Birler hanesi 4511 (LE ) sini Low yaptık yeni sayı çıkışta demektir.
      PAUSE 1                                       ‘Biraz bekledik
      HİGH PORTB.5                              ‘Tekrar (LE) yi High yaptık.
      PAUSE 1
   
      PORTB=240 | ONLAR                    ‘PortB ye (240 OR ONLAR) sonucunu koyduk . Şöylede olabilirdi (240+onlar)
      LOW PORTB.4                             ‘ 4511 in (LE) si enable yapıldı    
      PAUSE 1
      HİGH PORTB.4                             ‘ LE, tekrar disable yapıldı
      PAUSE 2
      GOTO BASLA
      END
                
 
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. İş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;
  1. Önce 0 nolu data bitini çıkışa ver ve en sonda 7. biti gönder. Sonuçta Clock Low da kalsın.
  2. Ö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.
 
Karekter
6.bit
5.bit
4.bit
3.bit
2.bit
1.bit
0.bit
Sayı Karşılığı
0
0
1
1
1
1
1
1
63
1
0
0
0
0
1
1
0
6
2
1
0
1
1
0
1
1
91
3
1
0
0
1
1
1
1
79
4
1
1
0
0
1
1
0
102
5
1
1
0
1
1
0
1
109
6
1
1
1
1
1
0
1
125
7
0
0
0
0
1
1
1
7
8
1
1
1
1
1
1
1
127
9
1
1
0
1
1
1
1
111
0
0
1
1
1
0
0
1
99
C
0
1
1
1
0
0
1
57
 
 
Ş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. İndeks 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. İş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.
HİGH  AktarPini (Latch) 
PAUSEUS 2 
LOW AktarPini ‘burada registere yazılan sayı bilgisinin aktarma pinine bir                                               ‘pals verilerek yani önce HİGH 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 (HİGH – 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.
 
İş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.
 
'****************************************************************
PORTA=255:portb=0
TRISB=0   'PortB tamamı giriş yapıldı.
TRISA=%00011111 'A portu tamamı çıkış yapıldı.
'-----------------------------------------------------------------
@ 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 Korum kapalı
@ DEVICE pic16F628, MCLR_off            'MCLR pini Kullanılmıyor.
@ DEVICE pic16F628, XT_OSC
'-----------------------------------------------------------------
'DEFINE OSC 4
'-------------------------------------------------------------------------
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 giriş çıkış
'----------------------------------------------------------------------------
Comm_Pin    VAR    PortA.4                                  ' One-wire Data-Pin "DQ" PortB.0 da
Busy        VAR BIT                                                ' Busy Status-Bit
HAM         VAR   WORD                                       ' Sensör HAM okuma değeri
ISI         VAR WORD                                             ' Hesaplanmış ISI değeri
Float       VAR WORD                                           ' Isı küsurat değeri
X           VAR WORD 
Y           VAR BYTE 
SAYI        VAR BYTE  
SIGN_BITI   VAR HAM.Bit11                                  '   +/- sıcaklık İşaret biti, 1 = olursa eksi sıcaklık
NEGAT_ISI   CON 1                                              ' Negatif_Cold = 1
Deg         CON 223                                                 ' ° işareti
SIGN        VAR BYTE                                            ' ISI değeri için +/- işaret
TEMP        VAR BYTE                                           ' Div32 bit hesap için geçici değişken
SAYAC       VAR BYTE
SN          VAR BYTE
DAK         VAR BYTE
SAAT        VAR BYTE
GUN         VAR BYTE
symbol SEC   =PORTA.0
SYMBOL ASAGI =PORTA.1
SYMBOL YUKARI=PORTA.2
'-----------------------------------------------------------------------------
CLEAR                                                                'tüm değişkenler sıfırlandı
PAUSE 200
Y=1
'-----------------------------------------------------------------------------
 PORTB=0 
BASLA:
       IF Y>10 THEN                             ‘Şayet 10 saniye geçmiş ise
           IF Y>=21 THEN Y=1                ‘Şayet 20 saniye geçmiş ise geçen tekrar 1den başlasın
           GOSUB EKRAN1                    ‘Isı göstermeye git
           GOTO ATLA
       ENDİF       
       GOSUB EKRAN0                        ‘Şayet 10 saniye geçmemiş ise saat göstermeye git.
      
ATLA: if SEC=0 THEN AYAR            'Mode Tuşuna Basılmış İse Ayar'a Git
       GOSUB  SENSOROKU               'Sonsör Oku Ve Sıcaklığı Ekrana Yaz
       GOTO BASLA
 
EKRAN0:HİGH PORTA.3                                       ‘Saati gösterme ekranı, ara ledleri yak.
       X= SAAT DIG 1:GOSUB AL                            ‘Saat onlar hanesinin Sayı karşılığını tablodan al
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]          ‘Sayı değerini Shift Registere yaz
       HİGH PORTB.2:PAUSEUS 2:LOW PORTB.2   ‘Yazılan değeri çıkışa aktar yani display da göster
      
       X= SAAT DIG 0:GOSUB AL                                   ‘Saat birler hanesinin Sayı karşılığını Tablodan al
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]         ‘Sayı değerini Shift Registere yaz
       HİGH PORTB.3:PAUSEUS 2:LOW PORTB.3  ‘Yazılan değeri çıkışa aktar yani display da göster
 
       X= DAK DIG 1:GOSUB AL                              ‘aynı işlemleri Dakika değişkeni için yap
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
       HİGH PORTB.4:PAUSEUS 2:LOW PORTB.4
      
       X= DAK DIG 0:GOSUB AL
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
       HİGH PORTB.5:PAUSEUS 2:LOW PORTB.5
      
       X= sn DIG 1:GOSUB AL                                 ‘aynı işlemleri Saniye göstergesi için yap
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
       HİGH PORTB.6:PAUSEUS 2:LOW PORTB.6
      
       X= SN DIG 0:GOSUB AL
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
       HİGH PORTB.7:PAUSEUS 2:LOW PORTB.7
       RETURN
      
AL:    LOOKUP X,[63,6,91,79,102,109,125,7,127,111,99,57],SAYI :RETURN
 
EKRAN1:LOW PORTA.3                                       ‘ISI gösterme ekranı, ara ledleri söndür.
       SAYI=0                                                         ‘ilk dijit karanlık olacak (0 değeri bunu yapar)
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
       HİGH PORTB.2:PAUSEUS 2:LOW PORTB.2
 
       IF SIGN_BITI = NEGAT_ISI THEN SAYI=64      ‘sıcaklık eksi ise işaret= - olacak değilse boş olacak
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]          ‘işaret değerini registere yaz
       HİGH PORTB.3:PAUSEUS 2:LOW PORTB.3   ‘yazılan değeri display de göster
      
       x=(ISI DIG 1):GOSUB AL                                ‘Sıcaklık değerinin onlar hanesinin sayı karşılığını tablodan al
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]          ‘sayıyı registere yaz
       HİGH PORTB.4:PAUSEUS 2:LOW PORTB.4   ‘Yazılan değeri çıkışa aktar ve display de görünmesini sağla
 
       X=(ISI DIG 0):GOSUB AL                                ‘Aynı işi sıcaklık birler hanesi içinde yap
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]
       HİGH PORTB.5:PAUSEUS 2:LOW PORTB.5
 
       X=10:GOSUB AL                                            ’Tabloda 10.sırada derece işaretinin sayı karşılığı var yani 99
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]          ‘Sayı=99 değerini registere yaz
       HİGH PORTB.6:PAUSEUS 2:LOW PORTB.6  ‘Yazılan değeri display’e aktar.
      
       X=11:GOSUB AL                                            ‘Tabloda 11 sırada C karakteri var onun sayı karşılığını al
       SHIFTOUT PORTB.0,PORTB.1,1,[SAYI]          ‘sayıyı registere yaz
       HİGH PORTB.7:PAUSEUS 2:LOW PORTB.7   ‘Yazılan değeri display’e aktar
       RETURN
      
AYAR:                                                                  ‘Bu bölümde saat ayarı yapılıyor
       WHİLE SEC=0                                               ‘hala Mode (seç) tuşuna basılı ise
       WEND                                                           ‘Bırakılıncaya kadar bekle
HOUR: GOSUB EKRAN0                                      ‘Saat ayarına geçtik ve saati ekrana yazdık.
       LOW PORTA.3                                              ‘Ara ledleri söndürdük (ayar modu anlaşılsın diye)
       IF SEC=0 THEN MINBIR                                 ‘Burada Sec tuşuna basılmış ise Dakika ayarına geç
       IF YUKARI=0 THEN                                        ‘Yukarı tuşuna basılmış ise
          SAAT=SAAT+1                                           ‘saat değerini bir artır.
          IF SAAT=24 THEN SAAT=0                         ‘Saat=24 olmuş ise saat=0 yap
        ENDİF  
        IF ASAGI=0 THEN                                         ‘Aşağı tuşuna basılmış ise
           SAAT=SAAT-1                                           ‘saat değerini bir eksilt
           IF SAAT=255 THEN SAAT=23                     ‘şayet saat tekrar 255 olmuş ise saat=23 yap                       
        ENDİF  
        GOSUB GECIKME                                        ‘biraz gecikme yap
        GOTO HOUR                                                ‘tekrar Saat ayarına dön.
       
MINBIR: WHİLE SEC=0                                         ‘Hala Sec tuşuna basılı ise
        WEND                                                          ‘bırakılıncaya kadar bekle
       
MINUTE: GOSUB EKRAN0                                    ‘Saat değerlerini ekrana yaz.
       LOW PORTA.3
       IF SEC=0 THEN ara
        IF YUKARI=0 THEN
           DAK=DAK+1
           IF DAK=60 THEN DAK=0
        ENDİF
        IF ASAGI=0 THEN
           DAK=DAK-1
           IF DAK=255 THEN DAK=59             
        ENDİF
        GOSUB GECIKME
        GOTO MINUTE
       
SECBIR: WHİLE SEC=0
        WEND
 
GECIKME:
        FOR X=0 TO 1800
        PAUSEUS 100
        NEXT
        RETURN
 
ARA:    HİGH PORTA.3
        WHİLE SEC=0 
        Wend
       
        goto BASLA
               
       
'----------------ISI SENSÖR OKUMA BÖLÜMÜ --------------------------------
SENSOROKU:
           OWOUT   Comm_Pin, 1, [$CC, $44]                               ' ISI değerini oku
Bekle:
           OWIN    Comm_Pin, 4, [Busy]                                                   ' Busy değerini oku
           IF      Busy = 0 THEN Bekle                                          ' hala meşgulmü? , evet ise goto Bekle..!
           OWOUT   Comm_Pin, 1, [$CC, $BE]                              ' scratchpad memory oku
           OWIN    Comm_Pin, 2, [HAM.Lowbyte, HAM.Highbyte]   ' İki byte oku ve okumayı bitir.
           GOSUB   Hesapla
           RETURN
   
Hesapla:                                                          ' Ham değerden Santigrat derece hesabı
    Sign = "+"
    IF SIGN_BITI = NEGAT_ISI THEN
       Sign  = "-" 
       temp=($ffff-ham+1)*625
       ISI = DIV32 10
       GOTO GEC  
    Endif
    TEMP = 625 * HAM        '
    ISI = DIV32 10                                                         ' Div32 hassas derece hesabı için 32 bit bölme yapıyoruz.
 
 
GEC:
    FLOAT = (ISI //1000)/100      ‘aslında burası gereksiz sıcaklık küsurat hesabı
    ISI=ISI/1000                          ‘ısı nın tam değerini hesaplamış olduk.
    RETURN                     
 
DISABLE                                 ‘Burası saat hesabının yapıldığı kesme bölümüdür.
KESME:
      SAYAC=SAYAC+1                         'kesme sayacı 1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=49 Then            '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0                        'sayaç sıfırlanıyor
          SN=SN+1
          Y=Y+1                           'saniye değeri bir artırılıyor
            IF SN=60 THEN            'saniye 60 olmuş ise 1 dakika süre geçti o halde
              SN=0                          ' saniye sıfırlanıyor
               DAK=DAK+1             ' dakika değeri bir artırılıyor
                  IF DAK=60 Then    'dakika 60 olmuş ise 1 saat süre geçti
                     DAK=0                ' dakika sıfırlanıyor
                     SAAT=SAAT+1               ' saat değeri bir artırılıyor
                        IF SAAT=24 THEN 'saat 24 olmuş ise 1 gün geçti
                           SAAT=0                    'saat sıfırlanıyor
                        Endif                    'gün sıfırlanıyor 1 yıl geçti
                  ENDİF
            ENDİF
          ENDİF
CIK:     INTCON.2=0                  'TMR0 Kesme bayrağı sıfırlanıyor
         RESUME
         ENABLE
        
END

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. İşte bu gibi durumlarda kullanabileceğimiz yongalar mevcuttur.
İlk 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.
 
İlk ö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 – 128 değ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’İn çıkışlarının sırası ile HİGH olduğunu göreceksiniz.
 
Önce devremizi verelim;


 
ve Programımız;
 
 
'****************************************************************
PORTA=255:portb=0
TRISB=0   'PortB tamamı giriş yapıldı.
TRISA=%00000000 'A portu tamamı çıkış yapıldı.
'-----------------------------------------------------------------
@ 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 Koruma kapalı
@ DEVICE pic16F628, MCLR_off                      'MCLR pini kullanılıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak
'-----------------------------------------------------------------
CMCON=7
Symbol CLK=PortA.0
SYMBOL DTA=PORTA.1
SYMBOL AKTAR=PORTA.2
BILGI VAR WORD
 
PORTA=0:bILGI=1
'-----------------------------------------------------------------
 
BASLA: IF BILGI=256 THEN BILGI=1
        SHIFTOUT DTA,CLK,1,[BILGI]                   ‘seri olarak bilgi 74HC595 in registerine yazılıyor
        HİGH AKTAR                                           ‘yazılan bilgi çıkışlara aktarılıyor
        PAUSEUS 5
        LOW AKTAR                                           'BILGI ÇIKIŞA AKTARILDI
        BILGI=BILGI*2                                          ‘bir sonraki pin High olacak şekilde bilgi değeri artırıldı
        PAUSE 500
        GOTO BASLA
       
 
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. İsteğ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.

'****************************************************************
PORTA=0:portb=0
TRISB=0   'PortB tamamı giriş yapıldı.
TRISA=%00000000 'A portu tamamı çıkış yapıldı.
'-----------------------------------------------------------------
@ 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_off                              'MCLR pini kullanılıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT      'Dahili osilatör kullanılacak
'-----------------------------------------------------------------
CMCON=7
SYMBOL DTA=PortA.0
SYMBOL CLK=PORTA.1
SYMBOL AKTAR=PORTA.2
BILGI VAR byte
 
PORTA=0
 
BASLA:
      LOW AKTAR:PAUSEUS 1:HİGH AKTAR            'Girişler registere yazıldı
      SHIFTIN dta,clk,0,[BILGI]                                    ‘register içeriği seri olarak alındı
      PORTB=BILGI                                                   ‘alınan bilgi portb ye verildi
      PAUSE 500
      GOTO BASLA

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.
 
 
  Bugün 7 ziyaretçikişi burdaydı!  
 
Bu web sitesi ücretsiz olarak Bedava-Sitem.com ile oluşturulmuştur. Siz de kendi web sitenizi kurmak ister misiniz?
Ücretsiz kaydol