CLEAR
PAUSE 500
PORTB=0 'tüm çıkışlar 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 haberleşme işinde en önemli faktörlerin başında alıcı ile vericiyi aynı anda karşı karşıya getirmektir. Bunun muhtelif yolları vardır. Senkronizasyon denilen bu işlem 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 şekillerde olabilir. Benim kullandığım ve olumlu netice aldığım kombine sinyal aşağıdaki şekildedir.
- İlk sinyal %10101 şeklinde bir sinyal arkasından %00000 ve onun arkasından ise %11111 şeklinde bir sinyal dir. Bunun komut karşılığı;
SEROUT2 CIKIS,396,[REP$AA5,REP$005,REP$FF5]
Haberleşmeye başlamadan önce bu komut verilerek karşı taraftaki devrenin alış moduna geçmesi sağlanır. Bu komutun arkasından esas göndermek istediğiniz bilgiler gönderilir. Önce belirleme bilgisi yani; ("E"),("T"),(”E”) bilgisi burada bir belirleme bilgisidir. Örnek;
SerOut2 CIKIS,396,[("E"),("T"),(”E”),EKLE]
Peşinden esas göndermeniz gereken bilgi veya bilgiler dizisi gönderilir. Sonuçta yukarıdaki örnekte EKLE adlı değişken de yer alan değer göndermek istediğimiz bilgi olmaktadır.
Senkron konusunda hata yapılmaması için genelde gönderme komutu birkaç defa arka arkaya tekrarlanır. Şayet 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üğü gibi en az 5 defa tekrarlanmasında yarar vardır. Bir mahsuru olmadığı gibi yararı vardır.
Alma komutu tek olabilir. Çünkü senkron sağlandıktan sonra gelen sinyallerden birini mutlaka görüp alacaktır.
Bu kadar açıklama dan sonra daha komplike bir Seri haberleşme 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 kullanacağız. Bu sefer 16F84A kullanalım. Çünki devrenin aslı 16F84 ile yapılmış idi.
Devre şemasını vermeden önce bazı konulara açıklık getirmek gerekiyor. Volum kontrolu ve program gezinmesi yapacağız. Volum kontrolu için digital pot kullanabilirdik. Ancak program kontrolü açısından bu işide kendimiz yapalım istiyoruz. Hem Volum kontrolu hemde program gezinmesi için 4051 (Analog swich) kullanacağız. 4051’in ABC adres bacakları 1 adet giriş-çıkış bacağı ve bu bacağın seçilen adrese göre Analog olarak bağlanabildiği 8 adet giriş-çıkış bacağı bulunmaktadır. Volum kontrolu için 16 kademe volum elde etmek üzere 2 adet (2x8=16) 4051 kullanacağız ve toplamda 16 adet volum seviyemiz olacak. Program gezinme için toplam 8 adet kanal çıkışımız olacak.
Bahsini ettiğim projeyi bizzat uygulama fırsatım oldu. Sistem hala başarı ile çalışmaktadır.
İşin mantığını izah edecek olur isek, verici olarak çalışan pic üzerinde bulunan ;
- açma / kapama tuşuna basıldığında karşı taraftaki pic de bir pin high / low olacak. (toggle çalışma)
- Volum+ tuşuna basıldığında volum artacak yani 2 adet 4051 çıkışları sırası ile konum değiştirecek.
- Aynı şekilde Volum- tuşuna basıldığında yapılan işin tersi yapılacak.
- Program+ tuşuna basıldığında program kademesi bir artacak. Basılı tuttukça artam devam edecek.
- Program- tuşuna basıldığında bu sefer seçim işi terse dönecek.
- Sabit program seçme tuşlarından birine basıldığında ise ilgili tuşa karşılık gelen pin karşı tarafta toggle olarak çalışacak. Ancak bu pin açık olan diğer pinleri iptal edip yanlıca kendisi çıkış verecek.
Bir ayrıntıyı daha izah etmekte fayda görüyorum. İki pic arasındaki bağlantıda bir inverter (NOT) kullanılmıştır. Aslında gerekli olmayan bu elemanı Seri haberleşme komutlarında alıcı veya vericiden birini invert edilerek kullanılmasını göstermek amacı ile yaptım.
İşte Şemamız.
Biraz karışık gibi gelebilir ama iyice takip edilirse kimin nereye bağlı olduğu kolaylıkla görülecektir.
Önce Verici Kısmına ait programı verelim;
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 tuşun 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 işlem yapma
POZ=1
VER=11
GoTo EXIT 'On/off tuşuna ilk basıldı tuş değeri=11 gönder.
IKI: VER=22
GoTo EXIT 'Volum+ tuşuna basıldı tuş değeri=22 , gönder
UC: VER=33
GoTo EXIT 'Volum- tuşuna basıldı tuş değeri=33, gönder
DORT: VER=44
GoTo EXIT 'Program+ tuşuna basıldı Tuş değerini gönder
BES: VER=55
GoTo EXIT 'Program- tuşuna basıldı tuş 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] 'tuş değerini gönder, değer ters çevrilmemiştir
GoTo START
END
Program kısa olduğu için preambl sinyali kullanmadık.
Şimdi Alıcı Kısmını verelim;
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 'şayet herhangi bir değer önceden kayıt edilmemiş ise
VOLUM=3 'default volum seviyesini 3 kabul ediyoruz.
EndIF
Read 1,PROG 'hangi programın seçili bırakıldığını yine eeprom 1 adresten
IF PROG=255 Then 'okuyoruz ve herhangi bir program kayıtlı değil 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 tuş bilgisini al
IF AL=11 Then BIR 'basılan tuş 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ışı toggle yapıldı
CIK:GoTo START
IKI:VOLUM=VOLUM+1 ' volum tuşuna basılmış volum bir artırıldı
IF VOLUM>15 Then 'şayet 15 den büyük ise 15 de kal
VOLUM=15
EndIF
'Volum<8 ise 1.4051 >8 ise 2.ci 4051 devrede olacak
VOLKAY:KON=VOLUM>>3 'Kon=%00001101 ise Kon=%00000001 oluyor
SES=VOLUM-(KON*8) 'Ses=13-(8x1)=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- tuşuna basılmış 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 'değişen volum değerini kayıt et
DORT: PROG=PROG+1 'program tuşuna basılmış 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 '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 AŞAĞI
PROG=7
EndIF
GoTo PORKAY
ALTI: Toggle PORTA.2 'sabit program tuşlarından birine basılmış
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üleceği üzere, B portu B0-B1-B2 pinleri ile Volum için çalışan 2 adet 4051 entegresini adreslemektedir. Adres değeri 0-15 arasında değişmekte 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 kullanacağı (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).
Şimdi 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 sağa kaydırıp yeni değeri KON adlı değişkene yerleştir anlamındadır. Neden bu işi yaptığımızı bir sonraki satırda açıklayacağız. Sonra gelen satırda ;
SES=VOLUM-(KON*8) şeklinde bir işlem var. 2 adet 4051 entegremiz var ama her ikiside aynı adreslemeyi kullanıyor. Dolayısıyla adres olarak vereceğimiz 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üşürmekteyiz. Diyelim ki Volum seviyemiz 14 olsun. Bu durumda
KON= 14 >> 3 = %00001110 değeri %0000001 olacaktı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. Örneğimizde 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çilmiş olmaktadır. Bu hesap sonucunda B7’ye bağlı olan entegre seçilmiş 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çilmiş olur otomatikman. Böylece PortB deki tüm bitlerin durumunu hesap etmiş oluyoruz. Bunları toplar isek; ARA= ARA + 6 + 64 = ARA+70 olarak bulunan değer direkt Port B ye yazılarak işlem tamamlanır.
Benzer bir hesap Program tuşuna 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 başında READ ve WRITE komutları geliyor.
Pic lerin pek çoğunda eeprom hafızası olduğunu hepimiz biliyoruz. Bazı durumlarda bu hafızaları kullanmak gerekir. Elektrik ile yazılıp silinen bir hafıza olduğundan 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ıştır.
Bu sayede televizyonu kapattığınız anda hangi programda kaldınız ise ve volum seviyeniz ne ise tekrar açtığınızda aynı seviyelere ulaşmış oluyorsunuz. Şimdi 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 başlayan bir adres numarası vardır. Bu adres numarası kullanılarak istenilen bir adresteki hafızaya ulaşılabilir.Hafıza ya yazma için kullandığı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ışmaktadır.
Hafıza dan okuma yapmak için kullandığımız komut ise READ komutudur. Aynı şekilde adres ve değer parametresi vardır. Kullanılış şekli;
READ 0(adres), BILGI (okunacak değer) olarak dır.
Yazma ve okuma işlemi yaklaşık 10 ms kadar bir sürede yapılır. Şayet program içinde kesme kullanılıyor ise hatalar ortaya çıkabilir. Bunu önlemek için bu komutlardan önce kesme iptal edilmelidir (disable ile değil direkt iptal) . İşlemden sonra kesme tekrar açılmalıdır.