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

 

Ders – 9
 
EEPROM VE SENSÖR KULLANIMI
 
Bu dersimizde Pic ile birlikte dışarıdan bağlı hafıza ünitelerinin kullanılmalarını inceleyeceğiz. Ayrıca pic ile birlikte kullanabileceğimiz bazı sensörlerin haberleşme sistemlerini inceleyeceğiz.
 
Önce Eeprom Kullanımına bir göz atalım.
 
Normal olarak sıklıkla kullandığımız pic modellerinde flash tipi eeprom bulunmaktadır. Ancak bazen kendi hafızlarının yetmediği durumlarda pic ile birlikte dışarıdan bağlı hafıza üniteleri kullanılır.
 
Önce pic’in kendi eeprom’u ile nasıl haberleşiyoruz biraz inceleyelim sonra harici eeprom konusuna gireceğiz.
 
Pic’in dahili eepromunun kullanımı ile ilgili birkaç komut var öğrenmeniz gereken. Bunların başında ;
DATA @konum, data, data, data ……
Komutu gelmektedir. Data, pic’in programlanması esnasında hafızasının belirli konumlarına önceden belirli olan sabit bazı bilgilerin yazılması için kullanılır. Örneğin şifre kullanan bazı programlarda ilk (default ) şifrenin girilmesi bu yolla yapılır. Komutun ilk parametresi @Konum ilk bilginin yazılacağı eeprom adresine aittir. Şayet bilgiler birbirini takip eden hafıza adreslerine yazılacak ise her seferinde adres verilmesi gerekmez. Bir kere başta adres verirsiniz sonra yazılacak bilgileri aralarına virgül koyarak sıralarsınız.
Burada dikkat edilecek husus şudur. Pic’i her çalıştırdığınızda bu bilgilerin ilgili hafıza birimlerine yeniden yazılacak olmasıdır. Dolayısıyla şifre girişi gibi işlemlerde şayet şifreyi program içinden değiştirmiş iseniz ve pici yeniden çalıştırırsanız şifreniz tekrar eskiye dönecektir.
 
Aslında yeri gelmişken bu gibi konuları aşmanın bir tekniğini belirtmek isterim. Ancak bunu diğer hafıza komutlarını inceledikten sonra açıklayacağım.
Dahili hafızaya bir bilgi yazmak için;
 
Write adres,Bilgi
 
Şeklinde bir komut kullanırız. Örneğin 0 nolu adrese 12 bilgisini yazmak istersek;
 
Write 0,12    dememiz yeterli olacaktır.
 
Diğer komut eepromdan bir bilgi okuma komutudur.
 
Read adres,Bilgi
 
Şeklinde kullanılır. Yine örnek olarak 0 nolu adreste yazılı olan bilgiyi okuyalım
Read 0,Sayı
 
Okunan değer Sayı isimli değişkene yerleştirilmiş oldu.
 
Yeni programlanmış bir pic’den okunacak hafıza değeri kesinlikle $FF yani 255 olarak gelir. Bu hafızaya henüz bir şey kayıt edilmediği anlamına gelir.
Diyelimki hafızaya şifre yazacaksınız şöyle yapabilirsiniz.
 
Read 0,Sifre                                        ‘ilk hafıza okundu ve değeri Sifre isimli değişkene yerleşti.
İf sifre=255 then                                ‘henüz hafızada kayıtlı bir şey yok ise
   Sifre=2                                              ‘yeni sifre=2 olsun
   Write 0,sifre                                    ‘yeni sifreyi sıfır nolu adrese yaz.
Endif
 
Kısaca önce hafızayı okudunuz. Sonra baktınız hafızaya herhangi bir şey kayıt edilmemiş ise şifreyi belirleyip hafızaya yazdınız.
Pic’i ilk defa çalıştırınca 0 nolu adrese 2 bilgisi yazılır. Daha sonra program içinden sifrenizi değiştirdiniz. Pic’i yeniden çalıştırınca ilgili hafızada 255 den farklı bir sayı olacağı için yeni sifre olarak 2 yazılmayacaktır. Dolayısıyla mevcut şifrenizi korumuş olacaksınız.
 
Son olarak dahili eepromların 8 bit çalıştıklarını ve her bir hafıza adresine 8 bitlik bilgi yazılması gerektiğini hatırlatmak isterim. Kullandığınız bilgi Word tipi yani 16 bit bir değişken ise bilgiyi Değişken.Lowbayt ve Değişken.Highbyte veya Değişken.Byte0 ve Değişken,Byte1 şeklinde 8 er bitlik iki kısma ayırıp o şekilde yazmanız gerekir. Aslında direkt word değişkeni olarak yazabilirsiniz. Bu durumda pic sizin için değişkeni lowbyte ve highbyte olarak ayırıp öyle kayıt edecektir. Ancak okuma yaparken kesinlikle sayının 8’er birlik iki kısım halinde okunması gerekir.
Örnek olarak vermek gerekir ise aşağıdakiler doğrudur.
 
SAYI VAR WORD
 
Sayı=12345                                         ‘Sayımız 16 bit.
 
WRITE 0,SAYI                                   ‘sayıyı 16 bit olarak eeproma yazdık aslında 0 ve 1 nolu adreslere yazıldı
 
READ 0,SAYI.Lowbyte                      ‘sayı nın lowbyte nı okuduk.
READ 1,SAYI.Highbyte                    ‘sayı nın high byte ını okuduk
 
HARİCİ EEPROMLARIN KULLANIMI
 
Dışarıdan bağlanabilen eepromlar genelde uzun depolama ömürleri (yaklaşık 200 yıl) nedeni ile tercih edilirler. Bunların tamamı Seri Senkron haberleşme arabirimi kullanır. Üreticilere göre haberleşme şekilleri farklıdır. Piyasada genelde 3 ayrı tip eeprom bulunmaktadır. Bunlar;
  1. Microwire tipi (Atmel firmasının üretmiş olduğu) 93Cxx (93C66 gibi) eepromlar
  2. SPI tipi haberleşme yapan eepromlar 24LCxxx serisi
  3. I2C tipi haberleşme yapan eepromlar. 24Cxx serisi
 Şimdi bunları sırası ile inceleyelim,
 
1. Microwire Eeprom Kullanımı;
Bu eepromların 2 adet Data pini DI (data-in) ve DO (Data-out) clolck input CI veya SK ile Chip Select CS pinleri bulunmaktadır.
Genelde 3 wire interface yani 3 kablolu veya hatlı arabirim şeklinde tanımlansa da haberleşme için 4 adet hat gerekiyor. Aslında 3 hatlı arabirim denmesinin bir sebebide DI ve DO uçlarının picde aynı ucun kullanılabilmesinden kaynaklanır. DI (Data Giriş) işini yapmak istediğinizde yani Eeproma Data girişi (yazma) yapmak istediğinizde pic deki pin Output yapılmalı, DO yani eepromdan data okuma yapıldığında ise aynı pin Input yapılmalıdır. Böylece Eeprom ile pic arasında 3 hat bağlı olabilmektedir.
 
Eeprom ile haberleşmede 7 adet komut kullanılabilir. Bunlar;
-          ERASE/WRITE ENABLE       ‘Sil/Yazma açık
-          DISABLE                                      ‘ İptal          
-          WRITE                                          ‘ Yaz                                  
-          READ                                           ‘ Oku
-          ERASE                                         ‘ Sil
-          ERASE ALL                                  ‘ Hepsini Sil
-          WRITE ALL                                   ‘ Hepsini Yaz
 
Her bir haberleşme işi bir START işlemi ile başlamalıdır. Start işleminde;
-CS High ve DI High yapılır ve Clock ucu low dan High a dönerken start konumu sağlanmış olur.
Bu yüzden bir işlem yapıldıktan sonra DI ucu daima High da bırakılır. Pic den gelen her bir işlem komutundan sonra CS low’a çekilmelidir. Yalnızca birbirinin ardı sıra (sequential) okuma durumlarında bu işlem yapılmaz.
Eeproma yazmak için
-          önce DI hattından ERASE/WRITE ENABLE komutu gönderilir. Bunun rakam karşılığı %10011 dir.
-          Arkasından bir Write komutu gönderilir (%101)
-          Sonra Adres bilgisi
-          Ve arkasından yazılacak bilgi gönderilir.
-          En sonunda CS Low’a çekilir.
 
 
ERASE/WRITE ENABLE komutu bir çalışma döneminde yalnızca bir kere verilen bir komuttur. Bunun anlamı şudur. Pic ilk çalıştırıldığında bu komut bir defa verilir ise sonraki okuma yazma işlemlerinde yeniden bu komutun verilmesi gerekmez. Ne zaman gerekir, pic’in voltajını dolayısıyla eepromun besleme voltajını kesip yeniden çalıştırdığınızda bu gereklidir.
 
Aynı şekilde Eepromdan okuma yapmak için
 
-          Önce DI hattından bir READ komutu gönderilir (%110)
-          Arkasından okunacak adres bilgisi gönderilir
-          Şayet okuma yapıldıktan sonra CS Low yapılmaz ise yani High da tutulur ise okumanın devam edeceği anlamına gelir . Şayet CS low yapılır ise ondan sonraki okuma komutu yine READ-ADRES bilgisi ile başlamalıdır.
 
Bu hafıza ile ilgili olarak simülsyon imkanımız olmadığı için yalnızca bir örnek program vermekle yetineceğim. Bu tip eepromlar ile haberleşme yapabilmek için SHIFTIN ve SHIFTOUT komutlarını kullanıyoruz.
Komutların nasıl kullanıldıklarını görebilmek için örneğimizi yazalım.
 
 
Örneğimizde Eepromun ilk 8 adresine bir şifreli kilit için gerekli şifre bilgisi yazdıracağımızı varsayacağız.
Sifremiz 8 haneli bir rakam olacak. Ancak biz bunu 2 adet Word değişkeninde saklayacağız.
Kolay anlaşılması açısından şifremizi ;
SIFRE_A=1234
SIFRE_B=5678   ‘tamamı Şifre=12345678 olarak tanımladık
Şeklinde tanımlıyoruz.
 
Örnek Program:
 
Include "Modedefs.Bas"
PORTA=0
TRISB=%00000000   'PortB.0 giriş diğerleri çıkış 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
'---------------------------------------------------------------------
SYMBOL CS=PortB.0       ' Chip select pin
SYMBOL SK=PortB.1       ' Clock pin
SYMBOL DI=PortB.2       ' Data in pin
SYMBOL DO=PortB.2       ' Data out pin
SIFRE_A   VAR BYTE
SIFRE_B   VAR BYTE
ADRS     VAR word
E_GIRIS                Var Byte                            ' Eproma yazılacak bilgi
E_CIKIS                Var Byte                            ' Epromdan okunacak Bilgi
 
EWEN    Con        %10011                              ' Erase/Enable kodu
EWDS   Con        %10000                              ' Disable Kodu
ERAL     Con        %10010                              ' Erase-All Tamamını sil Kodu
WRAL   Con        %10001                              ' Tamamına yaz kodu
ERD                       Con        %1100                 ' Read Kodu
EWR                      Con        %1010                 ' Write Kodu
ERASE Con        %1110                 ' erase Kodu
 
'---------ÖNCE EEPROM WRITE ENABLE YAPILDI------------------------
High CS                                               ' Enable eeprom
Shiftout DI,SK , 1 ,[EWEN5,07]' WRITE ENABLE kodu gönder
Low CS                                 ' Disable eeprom
SIFRE_A=1234
SIFRE_B=5678
 
BASLA:
'-----------------önce ilk sekiz adrese bilgi yazalım-----------------
ADRS=0
E_CIKIS=SIFRE_A DIG 0
GOSUB E_YAZ
ADRS=1
E_CIKIS=SIFRE_A DIG 1
GOSUB E_YAZ
ADRS=2
E_CIKIS=SIFRE_A DIG 2
GOSUB E_YAZ
ADRS=3
E_CIKIS=SIFRE_A DIG 3
GOSUB E_YAZ
'sifre 2. kısım yazılıyor
ADRS=4
E_CIKIS=SIFRE_B DIG 0
GOSUB E_YAZ
ADRS=5
E_CIKIS=SIFRE_B DIG 1
GOSUB E_YAZ
ADRS=6
E_CIKIS=SIFRE_B DIG 2
GOSUB E_YAZ
ADRS=7
E_CIKIS=SIFRE_B DIG 3
GOSUB E_YAZ
 
'----------Şimdide ilk 8 adresteki bilgileri okuyalım--------------------
ADRS=0
GOSUB E_OKU
SIFRE_A=E_GIRIS
ADRS=1
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*10
ADRS=2
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*100
ADRS=3
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*1000
'-----------Sifre 2. kısım okunacak--------------------
ADRS=4
GOSUB E_OKU
SIFRE_B=E_GIRIS
ADRS=5
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*10
ADRS=6
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*100
ADRS=7
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*1000
 
'buraya kadar olan satırlarda Sifre_A=1234 , Sifre?B=5678 olarak okundu
 
END       ‘PROGRAM BURADA SONA ERECEK!!!!!!!!!!!!!!!!!
‘----------------------------------------ALT PROGRAMLAR--------------------------------------------------------
E_YAZ:
       High CS                                        ' Eeprom Enable yapıldı
       Shiftout DI,SK, 1,[EWR4,ADRS,E_CIKIS] '
       Low CS                                          ' Disable the eeprom
                   Pause 10                                          
       Return
     
E_OKU:                High CS                               ' Eeprom Enable yapıldı
        Shiftout DI,SK, 1,[ERD4,ADRS] ' READ komutu ve Adres verildi
        Shiftin DO,SK, 2,[E_GIRIS]  ' Okunan data E_Giris içinde
        Low CS                                         ' Disable eeprom
        Return
               
END     
 
 
SPI TIPI EPROMLARIN KULLANIMI:
 
Aslında Microwire tipi eepromlar ile çok benzerlikleri vardır. Bazı ufak tefek farklılıklar ile haberleşme microwire ile çok benzeşir. Bu yüzden burada açıklama vermek yerine bir örnek program üzerinden açıklamamızı vereceğiz.
 
Microwire tipi eepromlar bölümünde vermiş olduğumuz programı bu sefer SPI tipi ile yapacağız. Böylece izleyenler aralarındaki farkı kolaylıkla görmüş olacaklardır.
 
Örneğimizde Eepromun ilk 8 adresine bir şifreli kilit için gerekli şifre bilgisi yazdıracağımızı varsayacağız.
Şifremiz 8 haneli bir rakam olacak. Ancak biz bunu 2 adet Word değişkeninde saklayacağız.
Kolay anlaşılması açısından şifremizi ;
SIFRE_A=1234
SIFRE_B=5678   ‘tamamı Şifre=12345678 olarak tanımladık
Şeklinde tanımlıyoruz.
 
Programımız;
 
'****************************************************************
Include "Modedefs.Bas"
PORTA=0
TRISB=%00000000   'PortB.0 giriş diğerleri çıkış 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
'---------------------------------------------------------------------
SYMBOL CS=PortB.0                                         ' Chip select pin
SYMBOL SCK=PortB.1                                      ' Clock pin
SYMBOL SI=PortB.2                                          ' Data in pin
SYMBOL SO=PortB.2                                        ' Data out pin
SIFRE_A   VAR BYTE
SIFRE_B   VAR BYTE
ADRS        VAR word
E_GIRIS   Var Byte                                             ' Eeproma Bilgi Yaz
E_CIKIS   Var Byte                                             ' Eepromdan Bilgi oku
 
EYAEN   Con        6                                             ' Eprom Enable kodu
SRYAZ Con        1                                             ' STATUS REGISTER'e yazma kodu
EYAZ     Con        2                                             ' Eproma yazma (WRITE) kodu
EOKU    Con        3                                             ' Epromdan Okuma (READ) kodu
WRDI    Con        4                                             ' Yazma iptal kodu
SROKU Con        5                                             ' STATUS REGISTER okuma kodu
 
SIFRE_A=1234
SIFRE_B=5678
 
BASLA:
'-----------------önce ilk sekiz adrese bilgi yazalım-----------------
ADRS=0
E_CIKIS=SIFRE_A DIG 0
GOSUB E_YAZ
ADRS=1
E_CIKIS=SIFRE_A DIG 1
GOSUB E_YAZ
ADRS=2
E_CIKIS=SIFRE_A DIG 2
GOSUB E_YAZ
ADRS=3
E_CIKIS=SIFRE_A DIG 3
GOSUB E_YAZ
'sifre 2. kısım yazılıyor
ADRS=4
E_CIKIS=SIFRE_B DIG 0
GOSUB E_YAZ
ADRS=5
E_CIKIS=SIFRE_B DIG 1
GOSUB E_YAZ
ADRS=6
E_CIKIS=SIFRE_B DIG 2
GOSUB E_YAZ
ADRS=7
E_CIKIS=SIFRE_B DIG 3
GOSUB E_YAZ
 
'----------Şimdide ilk 8 adresteki bilgileri okuyalım--------------------
ADRS=0
GOSUB E_OKU
SIFRE_A=E_GIRIS
ADRS=1
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*10
ADRS=2
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*100
ADRS=3
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*1000
'-----------Sifre 2. kısım okunacak--------------------
ADRS=4
GOSUB E_OKU
SIFRE_B=E_GIRIS
ADRS=5
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*10
ADRS=6
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*100
ADRS=7
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*1000
 
'buraya kadar olan satırlarda Sifre_A=1234 , Sifre?B=5678 olarak okundu
END
 
E_YAZ:
       low CS                          ' Eeprom Enable yapıldı
       Shiftout SI,SCK,1,[EYAEN]
       HIGH CS                          ' Eeprom disable
       PAUSE 5
       LOW CS                            'Eeprom yeniden enable
       Shiftout SI,SCK,1,[EYAZ, ADRS.Highbyte, ADRS.Lowbyte,E_CIKIS]' Send address and data
                   High CS
       Pause 5                                        
       Return
     
E_OKU:               
        Low CS                            ' Eeprom Enable yapıldı               
        Shiftout SI,SCK,1,[EOKU, ADRS.Highbyte, ADRS.Lowbyte]   ' READ komutu ve Adres verildi
        Shiftin SO,SCK,0,[E_GIRIS] ' Okunan data E_Giris içinde         
        High CS                         ' Disable eeprom
        Return
 
END      
               
I2C TİPİ EEPROMLARIN KULLANIMI:
 
Senkronize seri bus sitemi ile çalışan bu haberleşme şekli yalnızca hafızalar değil diğer bazı cihazların birbirleri veya bu cihazların MCU üniteleri ile haberleşmesinde de kullanılmaktadır.
Haberleşme, her biri çift yönlü (bi-directional) 2 hat üzerinden yapılır. Bunlar SDA Serial Data, ve SCL, Serial Clock olarak tanımlanırlar. Protokolu her zaman olduğu gibi burada incelemeyeceğiz. Yalnızca eeproma nasıl bilgi yazılır ve nasıl okunur bu konuyu açıklığa kavuşturacağız.
Pic Basic de I2C haberleşmesi için direkt komut vardır. Yazma için;
 
I2CWRITE DPIN, CPIN, $A0, 0, [SAYI]
 
Okuma için
 
I2CREAD DPIN,CPIN,$A0,0,[SAYI]
 
Şeklinde komutlar kullanılır.
 
DPIN burada Data pin’ini , CPIN ise Clock pin’ini göstermektedir. Bu pinleri belirledikten sonra Kontrol kodu verilir.
Cihazlara göre değişiklik arz eden bu kod eepromlar için genelde %1010 dır. Adres eepromda yazılacak veya okunacak adresi belirler. Okunacak veya yazılacak bilgi 8 veya 16 bit olabilir (Byte-Word). Bu durumda Adres değişkenide bilgi değişken tipine göre seçilmelidir. Word tipi bir bilgi yazılması veya okunması halinde adres de word tipinde seçilmelidir.
 
Basic de diğer eeprom tiplerine göre daha kolay bir kullanım şekli sunan I2C tipi eepromlarla ilgili örneğimiz yine aynı olacaktır. Önceden yazmış olduğumuz programı bu seferde I2C tipi eepromlar için yazacağız.
 
İşte programımız,
 
'****************************************************************
PORTA=0
TRISB=%00000000   'PortB.0 giriş diğerleri çıkış 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
'---------------------------------------------------------------------
SYMBOL CPIN=PortB.1       ' Clock pini
SYMBOL DPIN=PortB.2       ' Data pini
 
SIFRE_A   VAR BYTE
SIFRE_B   VAR BYTE
ADRS      VAR byte
E_GIRIS                Var Byte                            ' Eeproma Bilgi Yaz
E_CIKIS                Var Byte                            ' Eepromdan Bilgi oku
 
KONT    Con        %10100000                       ' Cihaz kodu
 
SIFRE_A=1234
SIFRE_B=5678
 
BASLA:
'-----------------önce ilk sekiz adrese bilgi yazalım-----------------
ADRS=0
E_CIKIS=SIFRE_A DIG 0
GOSUB E_YAZ
ADRS=1
E_CIKIS=SIFRE_A DIG 1
GOSUB E_YAZ
ADRS=2
E_CIKIS=SIFRE_A DIG 2
GOSUB E_YAZ
ADRS=3
E_CIKIS=SIFRE_A DIG 3
GOSUB E_YAZ
'sifre 2. kısım yazılıyor
ADRS=4
E_CIKIS=SIFRE_B DIG 0
GOSUB E_YAZ
ADRS=5
E_CIKIS=SIFRE_B DIG 1
GOSUB E_YAZ
ADRS=6
E_CIKIS=SIFRE_B DIG 2
GOSUB E_YAZ
ADRS=7
E_CIKIS=SIFRE_B DIG 3
GOSUB E_YAZ
 
'----------Şimdide ilk 8 adresteki bilgileri okuyalım--------------------
ADRS=0
GOSUB E_OKU
SIFRE_A=E_GIRIS
ADRS=1
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*10
ADRS=2
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*100
ADRS=3
GOSUB E_OKU
SIFRE_A=SIFRE_A+E_GIRIS*1000
'-----------Sifre 2. kısım okunacak--------------------
ADRS=4
GOSUB E_OKU
SIFRE_B=E_GIRIS
ADRS=5
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*10
ADRS=6
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*100
ADRS=7
GOSUB E_OKU
SIFRE_B=SIFRE_B+E_GIRIS*1000
 
'buraya kadar olan satırlarda Sifre_A=1234 , Sifre?B=5678 olarak okundu
END
 
E_YAZ:
       I2CWRITE DPIN,CPIN,KONT,ADRS,[E_CIKIS]
       Pause 10                                      
       Return
     
E_OKU:               
        I2CREAD DPIN, CPIN, KONT, ADRS, [E_GIRIS]
        RETURN
               
END      
               
 PIC İLE BİRLİKTE SENSÖR KULLANIMI
 
Sensörler hayatımız kolaylaştıran ve zaman zamanda hayranlık duyduğum cihazlardır. Pek çoğu pic ile haberleşebilmektedir.
Burada piyasada en çok kullanılan sensörlerden bazılarının pic ile olan haberleşme konusunu işleyeceğiz.
 
İşe sıcaklık sensörlerinden başlamak istiyorum. Bu konuda en çok kullanılanlardan birisi olan DS18B20 sensörünü ele alacağız. TO92 kılıfında imal edilmiş bulunan sensör one-wire (tek hat veya tek-tel) haberleşme sistemine sahiptir. Üç bacaklı olan sensörün iki bacağı besleme ve kalan son bacağıda Data in ve out bacağı olarak çalışmaktadır. Okunan değerler dijital olarak alınıp formül kullanılarak ısı’ya çevrilmektedir.
 
Konuyu yine bir örnek ile açıklayalım.
 
Örneğimizde Pic 16F628’e bağlı bir sensörün değerlerini okuyacak ve ısı göstergesi şeklinde LCD ekranda göstereceğiz.
 
Önce şemamızı verelim,
 
 
 
 
Program;
 
'****************************************************************
PORTA=0:portb=0
TRISB=%00000001   'PortB.0 giriş diğerleri çıkış yapıldı.
TRISA=0           '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ılmıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak
'-----------------------------------------------------------------
DEFINE LCD_DREG      PORTB    'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT              4                          'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_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 OSC 4
'-------------------------------------------------------------------------
 
CMCON=7    '16F628 de komparatör pinleri iptal hepsi giriş çıkış
'----------------------------------------------------------------------------
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                               ' Holds remainder for + temp C display
X               VAR   WORD      
ISARET_BITI   VAR HAM.Bit11               '   +/- sıcaklık İşaret biti, 1 = olursa eksi sıcaklık
EKSI_ISI     CON 1                                         ' Sıfır altında isaret biti=1 oluyor kontrol için
DERECE     CON 223                                     ' ° işareti
ISARET      VAR BYTE                                  ' ISI değeri için +/- işaret
TEMP         VAR BYTE                                   ' Div32 bit hesap için geçici değişken
SYMBOL COMM_PIN=PORTB.0             ' One-wire Data-Pin "DQ" PortB.0 da
'-----------------------------------------------------------------------------
CLEAR 'tüm değişkenler sıfırlandı
PAUSE 200
LCDOUT $FE,1
 
'-----------------------------------------------------------------------------
 
BASLA:lcdout $fe,2," DS18B20 ile ISI"
      GOSUB SENSOROKU     'SONSÖR OKU VE SICAKLIĞI EKRANA YAZ
      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ı
    ISARET = "+"
    IF ISARET_BITI = EKSI_ISI THEN
       ISARET   = "-" 
      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
    ISI=ISI/1000
    LCDOUT $FE,$C4,ISARET,DEC ISI,".",DEC1 (Float)," ",Derece,"C " '2. satırda ısı
    RETURN
 
END
 

Programdan da görüleceği üzere sensör okunduktan sonra önce sıcaklığın sıfırın altındamı yoksa üstündenmi anlamak için okunan ham değerin 11. bitine bakıyoruz. Bu bit şayet 1 ise sıcaklık eksi demektir. Bu bitin değerine göre program ayrı hesaplama bölümlerine gitmektedir.
Bu programda 32 bit hesaplama işlemi kullanılmaktadır. Kısaca mantığını izah etmek istiyorum.
Hesapla isimli alt programda;
TEMP=($FFFF - HAM+1)*625   şeklinde bir satır mevcuttur. Burada TEMP değişkeni içine 32 bit hesaplama yapacağımız değer yerleştirilmektedir. 32 bitlik hesap komutu bu satırın hemen altında verilmektedir.
Bir örnek hesapla işi daha kolay anlayacığınız umuyorum. -25 dereceye karşılık gelen ham değer $FE6F dir.
Bu formüle göre TEMP= ($FFFF-$Fe6F+1) x 625 = 250.625    , görüldüğü gibi bu hesabın sonucunda TEMP isimli değişknede 250.625 sayısı yer alması gerekir. Ancak bu sayı WORD formatından büyüktür ve 32 bit büyüklüğündedir. Bu yüzden pic bu değişken değerini kendi içinde geçici bir yerde tutar ve bir sonraki satırda verilen hesapda kullanır. Bir sonraki satırda;
       ISI = DIV32 10
Şeklinde bir ifade yer alır. Bu ifadenin anlamı; ISI = TEMP /10 şeklindedir. Yani temp hesabında elde edilen değer 32 bit işlemi ile 10’a bölünmektedir. Dolayısıyla elde edilecek sonuç bizim örneğimize göre;
250.625 / 10 = 25.062 olacaktır. BU sonuç 16 bit dir ve işlemlerimizde kullanabileceğimiz hale gelmiştir.
 
 SHT-11 (SENSIRION) DIGITAL ISI ve NEM SENSÖRÜ
 
Sensirion firmasının üretimi olan bu sensörler I2C prensibine benzer bir mantık ile haberleşme yapmakla beraber tam anlamı ile birebir değildir. Sensör tamamı ile dijital bir sensör olup aynı kılıf içinde hem ısı hemde rutubet sensörünü taşımaktadır. Sıcaklık aralığı -40 ile +123 derece arasında dır. Rutubet ölçümlerinde 0-ile %99,999 hassasiyette ölçüm yapabilmektedir. Ayrıca rutubet ölçümünde sıcaklık kompanizasyonu bulunmaktadır.
 
Örnek programımız aşağıdadır.
 
 


'****************************************************************
 
DEFINE LCD_DREG                         PORTB 'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT                          4                             'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_RSREG       PORTB 'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT        1                             'LCD RS bacağı Hangi Bite bağlı ?
DEFINE LCD_RWREG    PORTB
DEFINE LCD_RWBIT     2
DEFINE LCD_EREG                          PORTB 'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT                           3                             'LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_BITS                           4                             'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES         2                             'LCD Kaç sıra yazabiliyor
OPTION_REG.7=1
@ DEVICE pic16F628
@ DEVICE pic16F628, WDT_ON
@ DEVICE pic16F628, PWRT_ON
@ DEVICE pic16F628, PROTECT_OFF
@ DEVICE pic16F628, MCLR_OFF
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT
'---------------------------değişkenler------------------------------
    Y       VAR     BIT
    KONTROL VAR     BYTE              
    ISI1    VAR     BYTE      
    ISI2    VAR     BYTE      
    U1      VAR     BYTE        
    U2      VAR     BYTE
    C0      VAR     BYTE
    Z       VAR     BYTE
    H0      VAR     HAM.BYTE0
    H1      VAR     HAM.BYTE1
    HAM                  VAR           WORD
    RAW     var     word
    ISI     VAR     WORD
    RUT     VAR     WORD
    P1      VAR     WORD
    P2     VAR     WORD
    P3      VAR     WORD            
    C       VAR     WORD
    B       VAR     WORD
    W       VAR     WORD
    CLK     VAR     PORTA.0
    DTA     VAR     PORTA.1 
    ISARET VAR     BIT   'sensor değeri 0 ise artı, 1 ise eksi
    SIGN    VAR     BIT   'ısı isareti 0 ise artı 1 ise eksi
    HATA    var     BIT
 
 '-----------------------------B A Ş L A N G I Ç ---------------------------   
 
   CLEAR:TRISA=%00111000:TRISB=0:CMCON=7:low PORTB.2
    PAUSE 500:ISARET=0   
    LCDOUT $FE,$40,$6,$9,$9,$6,$0,$0,$0,$0        'derece işareti dataları   
    LCDOUT $FE,$48,$04,$0e,$0e,$0e,$1f,$04,$04,$0
    LCDOut $FE,1
   
   Gosub reset :GOSUB T_START
'-------------------------------------------------------------------------------   
BASLA: 
        KONTROL=%00000011:HAM=0   'SICAKLIK ÖLÇME
        GOSUB OLCUMAL
        Gosub ISIHESAP:GOSUB EKRAN1
        PAUSE 250
 
       KONTROL=%00000101:HAM=0 'RUTUBET ÖLÇME
       GOSUB OLCUMAL
       GOSUB RUTHESAP:GOSUB EKRAN2
        PAUSE 300
        GOTO BASLA
       
'---------------------------------------EKRANA YAZ ------------------------------------------------           
EKRAN1:             LCDOut $FE,2      
                               If ISARET=1 THEN
                                    LCDOut " ISI :-",DEC3 ISI1 , "," , DEC1 ISI2," ",0,"C ":RETURN 
                               EndIF
                               LCDOut " ISI : ",DEC3 ISI1 , "," , DEC1 ISI2," ",0,"C ":RETURN
 
EKRAN2:             LCDOut $FE,$C0:
                                LCDOut " NEM : ",DEC3 U1 , "," , DEC1 U2," % "
                               RETURN                             
'------------------------------- İŞLEM START ------------------------------------------------------
T_START:
        OUTPUT DTA:OUTPUT CLK
        HIGH DTA
        LOW CLK
        PAUSE 1
        HIGH CLK
        LOW DTA
        PAUSE 1
        LOW CLK
        PAUSE 1
        HIGH CLK
        PAUSE 1
        HIGH DTA
        LOW CLK
        RETURN
 
'-----------------------------R E S E T -----------------------------------------------------------
RESET: OUTPUT DTA:OUTPUT CLK':TRISA.0=0:TRISA.1=0'
        high DTA=1
        FOR W=0 TO 9
        HIGH CLK
        pause 1
        LOW CLK
        Next W
        Return
'-----------------------SENSORE KOMUT GÖNDER -----------------------------------
OLCUMAL: GOSUB T_Start
        SHIFTOUT DTA,CLK,1,[KONTROL]
        INPUT DTA
        PULSOUT CLK,10
        HATA=0
        FOR W=0 to 65500
           IF DTA=0 then EXIT
        NEXT W
        HATA=1
EXIT: IF HATA=1 then
         gosub SENSORYOK
       endif
       SHIFTIN DTA,CLK,0,[H1]
       OUTPUT DTA
       LOW DTA
       PULSOUT CLK,10
       INPUT DTA
       SHIFTIN DTA,CLK,0,[H0]
       PULSOUT CLK,10
       RETURN
'----------------------ISI HESAP ALT PROGRAMI-----------------------------------     
ISIHESAP: 
           if ham<4000 then
              ISARET=1 'sıcaklık eksi değerde demek
              ISI1=(4000-HAM)/100
              ISI2=((4000-ham)//100)/10  
              goto ISISON
            endif
           ISI1=(HAM-4000)/100
           ISI2=((HAM-4000)//100)/10
ISISON:    if HAM>16384 then
             ISI1=0:ISI2=0
           endif 
    RETURN
         
'-------------------------RUTUBET HESAP ALT PROGRAMI-------------------------------------------------
 RUTHESAP:
           ISI=ISI1*10+ISI2
           p1=(26542-(54722**ham+ham))**ham-40    
           P2=655+(HAM*5)+(HAM**15917)        
           P3=(P2**(ISI*10+2480))-(P2**2730)+P1   ' kompanse edilmiş değer
           U1=p3/10:U2=p3//10
           IF ham>3710 THEN
              u1=0:U2=0
              GOTO SENSORYOK
           ENDIF 
           return
'---------------------------------------------------------------------------------- 
         
SENSORYOK: LCDOUT $FE,$02,"   SENSOR YOK   "
           LCDOUT $FE,$C0," LUTFEN TAKINIZ " 
           PAUSE 1500              
           RETURN
        END   
 
  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