ALbaTRoS
29-01-2007, 20:40
ŞİFRELİ KAPI KİLİDİ UYGULAMASI
Bu uygulamada kullanıcı bir tuş takımı aracılığı ile mikrokontrolör ile iletişim kurabilmektedir.Kullanıcı, arabirim aracılığı ile şifresini ya da şifre değiştirmek isteğini kontrolöre bildirebilmektedir. Kontrolör tuş takımından okuduğu kodların anlamlarını çözerek kullanıcının isteği doğrultusunda gerekli işlemleri yerine getirebilmektedir. Çalışmanın bu bölümünde uygulamaya ilişkin donanım ve yazılım aşamaları hakkında bilgi verilmiştir. Yazılımın tamamı ise gerekli açıklamaları ve akış diyagramı ile birlikte ekler kısmında yer almaktadır. Tablo 3.1 de projenin gerçeklenmesi için gerekli olan malzeme tablosu verilmiştir.
3.1 Kullanıcı Arabirimi (Tuş Takımı)
Tuş takımı genellikle matris biçiminde yerleştirilmiş olan tuşlardan oluşur. Şifreli kapı kilidi uygulamasında kullanılan tuş takımı 4 x 3 lük bir matris biçimindedir.
Şekil 3.2’de 4x3 standart tuş takımı ile mikrokontrolör arasındaki donanım yapısı verilmiştir. Görüldüğü gibi tuş takımı matrisine ait 4 satır doğrudan mikrokontrolöre bağlanmıştır. Satırlara bağlı olan değil ve (NAND) kapısı herhangi bir tuşa basıldığında kesme üretmek amacıyla bağlanmıştır.
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Tuş takımının satırlarının okunabilmesi amacıyla satırların bağlı olduğu iskele kapıları alıcı olarak koşullanmıştır. Eğer hiç bir tuşa basılmamış ise bu 4 satırın bağlı olduğu kapılardan lojik 1 değeri okunur. Çünkü her satır bir direnç üzerinden kapılara bağlanmıştır. Ancak herhangi bir tuşa basılırsa bu tuşun bağlı olduğu satır hattı lojik 0 değerine düşeceği için kapıların okunması halinde 1111 değeri okunmaz.
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Şekil 3.2: Tuş takımının mikrokontrolör ile bağlantısı
Tuş takımının satırlarına bağlanmış olan dirençlerin değerlerinin büyük seçilmesi daha uygun olacaktır. Bir tuşa basıldığında kısa devre meydana geldiğinden çekilen akımın, dolayısıyla güç sarfiyatının az olması için direnç değerleri büyük olmalıdır. Ayrıca direnç değerlerinin küçük seçilmesi halinde (<1000ohm) kesmenin algılanması da güçleşecektir. Çünkü değil-ve kapısının girişlerinin lojik 0 olarak algılanabilmesi için giriş seviye geriliminin belirli bir düzeyin altında olması gerekmektedir.
Tuş takımının 3 adet sütunu ise yine 3 adet kapı tarafından sürülmektedir. Bu sütunların lojik 0 durumunda tutuldukları düşünülürse herhangi bir tuşa basılması halinde tuşun bulunduğu sütun ve satırın kısa devre olması ile ilgili satırın gerilimi de lojik 0 seviyesine düşecektir. Satırların hepsi bir değil-ve kapısı ile mikrokontrolürün kesme girişine bağlı olduğundan tuşa basılması kesme üretilmesini sağlayacaktır. Kesme hizmet programı içerisinde ise hangi tuşa basıldığı belirlenmektedir.
Yukarıdaki donanımın kontrolör tarafından algılanabilmesi için kontrolörün uygun şekilde koşullanması gerekmektedir. Bunun için aşağıdaki koşullamalar yapılmalıdır.
.EQU SATIR_1=0 ; EQU sembolik deyimi ile eşitlikler atanarak program
.EQU SATIR_2=1 ; daha anlaşılır bir yapıya getirilebilir.
.EQU SATIR_3=2
.EQU SATIR_4=3
.EQU SUTUN_1=4
.EQU SUTUN_2=5
.EQU SUTUN_3=6
cbi DDRB,SATIR_1 ; burada satırların okunacağı kapılar alıcı olarak
cbi DDRB,SATIR_2 ; koşullanmaktadır.
cbi DDRB,SATIR_3 ; cbi (clear bit )
cbi DDRB,SATIR_4 ; DDRB B iskelesine ilişkin yönlendirici
cbi PORTD,SATIR_1 ; Bu koşullamalar ise okunacak satırlara ilişkin
cbi PORTD,SATIR_1 ; kapıların dahili pull-up kullanmalarını sağlar.
cbi PORTD,SATIR_1
cbi PORTD,SATIR_1
sbi DDRB,SUTUN_1 ;buradaki koşullamalar ile tuş takımının bağlı
sbi DDRB,SUTUN_2 ;olduğu kapıların verici olarak koşullanması
sbi DDRB,SUTUN_3 ;sağlanmaktadır.
ldi temp,3 ;kesme izninin verilmesi ve kesmenin çıkan kenar
out MCUCR,temp ;tetiklemeli olması için gerekli koşullamalar.
ldi temp,64 ;MCUCR (MCU kontrol saklayıcısı)
out GIMSK,temp ;GIMSK (Genel kesme maskesi saklayıcısı)
sei ;Global kesme izninin verilmesi
Bu koşullamalar altında başlangıçta sütun hatlarının hepsi lojik 0 seviyesinde tutulmaktadır. Bu durumda bir tuşa basılması halinde NAND kapısının çıkışı 0’dan 1’e çıkacağı için ve kesme de çıkan kenarın algılanması ile gerçekleşeceği için kesme hizmet progr..... dallanılır. Kesme hizmet programı içerisinde ise sütun hatları belirli bir anda sadece birisi etkin durumda (lojik 0) olacak şekilde sürülür. Her durumda satırlar okunarak 0 seviyesindeki satır bulunmaya çalışılır. 0 seviyesindeki satır bulunduğunda sürülen sütun da belli olduğundan basılan tuş belirlenir ve tuşun değeri bir saklayıcıya yazılır.
Tuş okuma alt programında öncelikle sütunlar sıra ile belirli bir süre sürülmekte ve satırlar okunmaktadır. Burada sütunların sürülmesinin hemen ardında ik bir gecikme programı çalıştırılmaktadır. Bu gecikme programının çalıştırılmadığı durumda satırların okunması halinde doğru bilgi alınması mümkün olmayacaktır. Çünkü sadece birkaç saat darbesi ardından bir satır 1 seviyesinde 0’a düşecek olsa bile bu durum, program tarafından sezilemeyecektir. Çünkü lojik 0’dan lojik 1’e ya da tersi geçişler belirli bir gecikme ile gerçekleşmektedir.Gecikme programı eğer bir geçiş varsa bu geçişin kesin olarak algılanabilmesini sağlar. Burada akla şu soru gelebilir , “acaba bir tuşa basıldığı halde gecikme programından dolayı tuşun algılanamaması olasılığı var mıdır?”. Tuşun algılanamaması olasılığı yoktur çünkü gecikme programı sadece bir kaç ms’lik bir gecikme sağlamaktadır. Bir insanın bir tuşa basıp elini çekmesi için ise en azından 200ms’lik bir zamana ihtiyaç vardır.Bu durumda basılan tuş kesinlikle
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Şekil 3.3: Tus okuma alt progr..... ilişkin akış diyagramı
3.2. Uygulama İçin Kullanılan Yazılım
Şifreli kapı kilidi uygulamasındaki yazılımda program ilk koşulların belirlenmesinin ardından sonsuz döngüde beklemektedir. Bir tuşa basılıp kesme alınması ile bir kesme hizmet progr..... dallanılmakta ve basılan tuşun belirlenmesinin ardından yapılması gereken işlemler tamamlandıktan sonra kesmeden dönülmekte ve sonsuz döngüde beklemeye devam edilmektedir.Görüldüğü gibi bütün işlemler kesme hizmet programı içerisinde gerçekleştirilmektedir.
Yazılım aslında bir sonlu durum makinası gibi çalışmaktadır. Basılan tuş belirlendikten sonra eğer tuş ‘*’ ise şifre değiştirme durumuna geçilmektedir ve geçilen durum ilgili led ‘ler yakılarak kullanıcıya bildirilmektedir. Şifre değiştirme durumunda iken şifre değiştirme durum led’i ve eski sifrenin girilmesinin beklendiğini belirten durum led’i yakılır. Kullanıcı eski şifreyi girdikten sonra ‘# ’ tuşuna basarak girişi tamamladığını bildirir. Girilen karakterler bir sifre tablosunda tutulmaktadır ve ‘# ‘ tuşunun okunması ile bu tablodaki karakterler ile EEPROM’daki şifre karakterleri karşılaştırılır. EEPROM da 25 adet 5 uzunluklu şifre bulunmaktadır. Yani yapı çok kullanıcılı olarak tasarlanmıştır. Bu nedenle şifre tablosundaki veri ile 25 farklı şifre bloğu karşılaştırılır. Eğer girilen şifre ile EEPROM şifreleri arasında uyuşma söz konusu değilse yine ilk koşullara dönülmektedir. Ayrıca kullanıcının hatalı, eksik ya da fazla veri girişi yaptığı durumlarda da ilk koşullara dönülmektedir. Eski şifrenin doğru olarak okunması halinde ise yeni şifrenin okunması durumuna geçilmektedir ve bu durum bir led ile kullanıcıya iletilmektedir. Yine 5 karakterlik yeni şifre bir tabloda tutulmaktadır. Eğer veri girişinde bir hata söz konusu değilse yeni sifrenin onaylanması için bir daha girilmesinin bekleneceği bir duruma geçilecektir. Bu durum da yine kullanıcının haberdar olması için bir led ile bildirilecektir. Kullanıcının girmiş olduğu iki yeni sifre karşılaştırılarak aynı olup olamadıkları kontrol edilir.Eğer girilen yeni sifreler aynı ise bu sifre ile EEPROM’da bulunan sifre değistirilmektedir.
Eğer kullanıcı doğrudan şifre girmeye başladı ise şifre okuma durumuna geçilmektedir. Bu durum içerisinde iken kullanıcının girmiş olduğu karakterler şifre tablosunda tutulmakta ve ‘# ‘ okununcaya kadar bu durum içerisinde kalınmaktadır. Eğer ‘# ‘ karakteri okunduğunda girilmiş olan şifre formatı doğru ise bu şifre ile EEPROM’da bulunan 25 adet şifre karşılaştırılmaktadır. Eğer şifre doğru ise kapının açılması için ilgili iskele kapısı çıkışı lojik 1 düzeyine çekilmektedir. Yaklaşık olarak 1sn boyunca lojik 1 uygulandıktan sonra ise yine ilk koşullara dönülmektedir.
3.3. Program Durum Diyagramı
Şekil 3.4’te durum diyagramında durumlar arası ilşikiler açık bir şekilde görülebilir.
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Şekil 3.4: Yazılıma ilişkin durum diyagramı
Diyagramdan da görüldüğü gibi çıkış karakteri (‘# ’) alınıncaya kadar bir durum içerisinde kalınmakta ve çıkış karakterinin ardından veri girişi kontrol edilmektedir. Hatalı veri girişi yapılması ilk koşullara dönülmesine neden olmaktadır.İlk koşullarda ise bütün saklayıcılara ilk değerleri yüklenmekte aslında sistem reset’lenmektedir. Böylece yapının devamlılığı sağlanabilmektedir.
Yazılımda durumlar arası geçişler bayraklar ile kontrol altında tutulmaktadır. Uygulamaya ilişkin yazılım ve akış diyagramı ekler kısmında açıklamalı olarak verilmiştir.
3.4 Proje DonanımYapısı
Belirtilen koşulları sağlayan projeye ilişkin ilişkin donanım şeması Şekil3.5’te verilmiştir
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Şekil 3.5: Projeye ilişkin donanım şeması
EK – A PROGRAM AKIŞ DİYAGRAMI
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
EK-B PROGRAM KODU
.include "2313def.inc"
.DEF temp =R16
.DEF tus =R17
.DEF delay1 =R18
.DEF delay2 =R19
.DEF taban =R20
.DEF sayac =R21
.DEF veri =R22
.DEF EEVeri =R23
.DEF EEAdres=R24
.DEF temp2 =R25
.DEF s1 =R0 ;sifre okumak için ve
.DEF s2 =R1 ;sifre degidtirmek için
.DEF s3 =R2 ;alt programlarda kullanılan sayaclar
.DEF s4 =R3
.DEF sifre_dogru =R4 ;bayrak saklayıcısıları
.DEF e_s_dogru =R5
.DEF yeni_sifre_okundu =R6
.DEF yeni_sifreler_esit =R7
.DEF sifre_degistir =R8
.DEF sifre_girme =R9
.DEF hata =R10
.EQU rakam =5 ;sifre buyu bu sabit ile belirlenir.
.EQU SUTUN_1 =0 ;tuş takımı sütunları
.EQU SUTUN_2 =1
.EQU SUTUN_3 =2
.EQU SATIR_1 =3 ;tuş takımı satırları
.EQU SATIR_2 =4
.EQU SATIR_3 =5
.EQU SATIR_4 =6
.EQU s_degistir_LED=0
.EQU eski_s_gir_LED=1
.EQU y_s_1_gir_LED=3
.EQU y_s_2_gir_LED=4
.EQU KAPIYI_AC =5
.EQU S_gir_LED =6
.DSEG
yeni_sifre_1: .BYTE 5 ;Yeni sifre tablosu 1 için 5 byte ayır yeni_sifre_2: .BYTE 5 ;Yeni sifre tablosu 2 için 5 byte ayır sifre_tablo: .BYTE 5 ;sifre tablosuna 5 byte ayır
.CSEG
.ORG 0X00
rjmp RESET ;Power-on Reset
rjmp kesme ;Kesme isteği0(IRQ0)
rjmp RESET ;Kesme isteği1(IRQ1)
rjmp RESET ;Zamanlayıcı 1 yakalama
rjmp RESET ;Zamanlayıcı 1 karşılaştırma
rjmp RESET ;zamanşayıcı 1 taşma
rjmp RESET ;zamanlayıcı 0 taşma
rjmp RESET ;ASİA,Rx coplete
rjmp RESET ;ASİA,veri saklayıcısı boş
rjmp RESET ;ASİA,Tx complete
rjmp RESET ;analog karşılaştırıcı
.CSEG
reset:
cli ;kesme iznini kaldır
;--------------------------------------
;Yığın isaretcisine ilk değerinin verilmesi
;
ldi Temp, low(RAMEND)
out SPL, Temp
;--------------------------------------
;iskele alıcı-verici kosullamaları
;ve ilk değerlerin verilmesi
sbi DDRB,SUTUN_1
sbi DDRB,SUTUN_2
sbi DDRB,SUTUN_3
cbi PORTB,SUTUN_1
cbi PORTB,SUTUN_2
cbi PORTB,SUTUN_3
cbi DDRB,SATIR_1
cbi DDRB,SATIR_2
cbi DDRB,SATIR_3
cbi DDRB,SATIR_4
sbi DDRD,0
sbi DDRD,1
cbi DDRD,2
sbi DDRD,3
sbi DDRD,4
sbi DDRD,5
sbi DDRD,6
cbi PORTD,0
cbi PORTD,1
cbi PORTD,3
cbi PORTD,4
cbi PORTD,5
cbi PORTD,6
;------------------------------------------
;kullanılan sayaclara ilk değerlerinin atanması
ldi temp,0
mov s1,temp
ldi temp,0
mov s2,temp
ldi temp,0
mov s3,temp
ldi temp,0
mov s4,temp
;---------------------------------------------
;bayraklara ilk değer atanması
ldi temp,0
mov e_s_dogru,temp
mov sifre_girme,temp
mov sifre_degistir,temp
mov sifre_dogru,temp
mov yeni_sifre_okundu,temp
mov hata,temp
;----------------------------------------------
;kesme izninin verilmesi
ldi temp,3
out MCUCR,temp
ldi temp,64
out GIMSK,temp
sei ;global kesme izin biti 1'lenir
rjmp anacevrim ;anacevrim'e dallan
anacevrim:
rjmp anacevrim ;anacevrimde program sonsuz döngüde beklemek-
;tedir. Bütün iş kesme hizmet programı
;içerisinde yapılmaktadır.
;================================================= ==========
;kesme hizmet programı
;
;
kesme:
rcall tusoku ;kesme tuş takımından alındığı için
;basılan tuşu "tuşoku" alt programı ile belirle
mov temp,hata ;eğer hata=-1 ise basılan tuş belirlenememiştir
cpi temp,-1 ;bu durumda hata=0 yapılarak kesmeden dönülür.
brne L ;aksi halde kesme hizmet programı çalışmaya devam
ldi temp,0 ;eder.
mov hata,temp
reti
L:
cpi tus,10 ;tus='*' mı?
brne x ;tus='*' değilse x'git
mov temp,sifre_girme
cpi temp,0 ;sifre_girme=1 ve tus="*" ise sonlan
brne sonlan
mov temp,sifre_degistir
cpi temp,0 ;sifre_degistir=1 ise ve yine tus='*'
brne sonlan ;tusuna basılmış ise RESET(sonlan)
ldi temp,1
mov sifre_degistir,temp ;"*" tusuna ilk kez basımış ise
sbi PORTD,S_degistir_LED ;bayrak çekilir ve kullanıcı ledler ile
sbi PORTD,Eski_S_gir_LED ;uyarılır.
bekle:
sbic PIND,2 ;kesme alınan bacak lojik 0 düzeyine
rjmp bekle ;düşene kadar beklenir.(kullanıcının elini rcall dly ;tuştan çekmesi bekleniyor)
reti ;kesmeden dön
x: ;tus!=* ise bu kod yürütülür. mov temp,sifre_degistir
cpi temp,1
brne sifre_okuma ;sifre_degistir!=1 ise sifre_okuma ya git
mov temp,e_s_dogru ;sifre_degistir=1 ise eski sifre okundu mu?
cpi temp,1 ;eski sifre okunmus mu?
brne eski_s_oku ;okunmamıs ise eski sifreyi oku
mov temp,yeni_sifre_okundu ;eski sifre okunmus ise
cpi temp,1 ;yeni sifre okunmus mu?
brne yeni_s_oku ;okunmamıs ise oku
rcall yeni_sifre_2_oku ;okunmus ise yeni sifre 2'yi oku
bekle_1:
sbic PIND,2 ;kullanıcının elini çekmesi bekleniyor.
rjmp bekle_1
rcall dly
reti
sifre_okuma:
ldi temp,1
mov sifre_girme,temp
;sbi PORTD,s_gir_LED
rcall sifre_oku
bekle_2:
sbic PIND,2 ;kullanıcının tuştan elini çekmesi bekleniyor.
rjmp bekle_2
rcall dly
reti
eski_s_oku: ;sifre_degistir=1 ise bu kod parcası
;yürütülür.
rcall eski_sifre_oku
bekle_3:
sbic PIND,2 ;kullanıcını elini çekmesi bekleniyor.
rjmp bekle_3
rcall dly
reti
yeni_s_oku: ;eski sifre okunmus ve dogru ise bu kod
;parcası yürütülür.
rcall yeni_sifre_1_oku
bekle_4:
sbic PIND,2 ;kullanıcını elini çekmesi bekleniyor.
rjmp bekle_4
rcall dly
reti
sonlan:
ldi temp,100
g: rcall dly
dec temp
brne g
bekle_5:
sbic PIND,2
rjmp bekle_5
rcall dly
rjmp RESET
;================================================= ============
;Kesme alındığında hangi tuşa basıldığını bulan kesme hizmet programı
;
;
tusoku:
sec ;eldebayrağı=1 yap
ldi Temp, 0b11111011 ;baslangıçta SUTUN_3 etkin durumda
ldi sayac,0
yeniden_tara:
out PORTB,Temp
rcall dly ;gecikme süresi kadar bekle
sbis PINB, SATIR_1 ;SATIR_1 biti 1 ise tusa basılmamıstır
rjmp S_1 ;bu bit 0 ise tusa basılmıstır.s_1'e git
sbis PINB, SATIR_2 ;SATIR_2 biti 1 ise tusa basılmamıstır
rjmp s_2 ;bu bit 0 ise tusa basılmıstır.s_2'ye git
sbis PINB, SATIR_3 ;SATIR_3 biti 1 ise tusa basılmamıstır
rjmp s_3 ;bit 0 ise tusa basılmıstır.s_3'e git
sbis PINB, SATIR_4 ;SATIR_4 biti 1 ise tusa basılmamıstır
rjmp s_4 ;bit 0 ise tusa basılmıstır.s_4'e git
inc sayac ;sayacı 1 artır
cpi sayac,3 ;sayac!=3 ise bütün sütunlar taranmamıştır.
breq son_1 ;sayac=3 ise tus bulunamdığı için son_1'e git
ror Temp ;diger sutuna bak
rjmp yeniden_tara
son_1:
ldi temp,-1 ;bütün sütunlar tarandığı halde tuş
mov hata,temp ;bulunamadığı için hata=-1 yaz
rjmp son1
s_1: ;tus satır 1'de ise bu kod işlenir
sbic PORTB,SUTUN_1
rjmp else1 ;SUTUN_1=1 ise diger sutunlara bak
ldi TUS,1 ;SUTUN_1=0 ise 1 tusuna basılmıstır.
rjmp bitti
else1:
sbic PORTB,SUTUN_2
rjmp else2 ;SUTUN_2=1 ise diger sutuna bak
ldi TUS,2 ;SUTUN_2=0 ise 2 tusuna basılmıstır.
rjmp bitti
else2:
ldi TUS,3 ;SUTUN_3=0 olduğu için 3 tusuna basılmıstır.
rjmp bitti
s_2: ;tus satır 2'de ise bu kod işlenir
sbic PORTB,SUTUN_1
rjmp else3 ;SUTUN_1=1 ise diger sutunlara bak
ldi TUS,4 ;SUTUN_1=0 ise 4 tusuna basılmıstır.
rjmp bitti
else3:
sbic PORTB,SUTUN_2
rjmp else4 ;SUTUN_2=1 ise diger sutuna bak
ldi TUS,5 ;SUTUN_2=0 ise 5 tusuna basılmıstır.
rjmp bitti
else4:
ldi TUS,6 ;SUTUN_3=0 olduğu için 6 tusuna basılmıstır.
rjmp bitti
s_3: ;tus satır 3'de ise bu kod işlenir
sbic PORTB,SUTUN_1
rjmp else5 ;SUTUN_1=1 ise diger sutunlara bak
ldi TUS,7 ;SUTUN_1=0 ise 7 tusuna basılmıstır.
rjmp bitti
else5:
sbic PORTB,SUTUN_2
rjmp else6 ;SUTUN_2=1 ise diger sutuna bak
ldi TUS,8 ;SUTUN_2=0 ise 8 tusuna basılmıstır.
rjmp bitti
else6:
ldi TUS,9 ;SUTUN_3=0 olduğu için 9 tusuna basılmıstır.
rjmp bitti
s_4: ;tus satır 4'de ise bu kod işlenir
sbic PORTB,SUTUN_1
rjmp else7 ;SUTUN_1=1 ise diger sutunlara bak
ldi TUS,10 ;SUTUN_1=0 ise '*' tusuna basılmıstır.
rjmp bitti
else7:
sbic PORTB,SUTUN_2
rjmp else8 ;SUTUN_2=1 ise diger sutuna bak
ldi TUS,0 ;SUTUN_2=0 ise 0 tusuna basılmıstır.
rjmp bitti
else8:
ldi TUS,11 ;SUTUN_3=0 olduğu için '#' tusuna basılmıstır.
bitti:
son1:
ldi temp,0b11111000
out PORTB,temp
ret
;================================================= =============
;gecikme programı [(3*255)*(250e-9)]*10=2ms (kristal=4MHz)
;
dly: ldi delay2,10
s:
dec delay1
brne s
dec delay2
brne s
ret
;================================================= =============
;kapının açılamsı için şifre girildiğinde bu alt program işlenir
;
sifre_oku:
cpi Tus,10 ;Tus='*' ise RESET
breq son
cpi Tus,11 ;Tus='#' ise ileri_4'e git
breq ileri_4
inc s4 ;sayacı 1 artır
mov Temp,s4
cpi Temp,rakam+1 ;sayac 6 ile karşılaştırılıyor
brmi ekle_4 ;sonuç negatif ise(s4<6)tuşu tabloya ekle
ret ;s4>=6 ise fazla tuş girilmiştir, dön
ekle_4:
cpi Temp,1
brne oku_4 ;eğer ilk tuş ise tablnun adresni
ldi ZL,low(sifre_tablo+64) ;Z işaretcisine yaz
ldi ZH,high(sifre_tablo+64)
oku_4:
st Z+,Tus ;Tusu işaretçi ile gösterilen yere yaz
ret ;dön
ileri_4:
mov Temp,s4
cpi Temp,rakam
;sayaç!=5 ise veri sayısı hatalı,RESET
brne son
clr Temp
mov sifre_dogru,Temp
ldi YL,low(sifre_tablo+64)
ldi YH,high(sifre_tablo+64)
rcall sifre_kar ;girilen sifre ile EEPROM' daki sifre kars.
mov temp,sifre_dogru
cpi temp,1
brne son ;sifre hatalı ise RESET
sbi PORTD,KAPIYI_AC ;sifre dogru oldugu için kapıyı aç
t:
rcall dly ;0,7 sn süresince lojik 1 uygula
dec temp
brne t
k:
rcall dly ;0,7 sn süresince lojik 1 uygula
dec temp
brne k
son:
rcall dly
rjmp RESET
;================================================= =============
;bu altprogragram kullanıcı tarafından girilen sifre ile EEPROM da bulunan sifreleri
;karşılaştırır.Eğer girilen sifre doğru ise sifre_doğru bayrağını 1'ler
Sifre_Kar:
ldi EEadres,$00
mov Taban, EEadres
ldi sayac,rakam
Karsilastir:
rcall EEPROM_OKU
ld Veri, Y+ ;X sifrenin bulundugu tablonun ilk adresi
cp Veri, EEveri ;Tablodaki veri ile sifre verisi aynı mı?
brne esit_degil ;Aynı değilse esit_degil'e git
dec sayac ;aynı ise sayacı azalt
breq esit ;ve esit'e git
inc EEadres ;EEPROM isaretcisini bir artır.
rjmp Karsilastir
esit_degil:
ldi Temp, rakam ;Sifre hatalı olduğu için bir sonraki
add Taban, Temp ;şifre bloğuna geç
cpi Taban, 8
brpl exit ;Taban>126 ise EEPROM sonu olduğu için çık
ldi sayac, rakam
mov Eeadres,taban
ldi YL,low(sifre_tablo+64)
ldi YH,high(sifre_tablo+64)
rjmp Karsilastir
esit:
ldi temp,1
mov sifre_dogru,temp ;şifre doğru olduğundan ilgili bayrak 1'lenir
exit:
ret
;================================================= =============
;sifre degistirilmek istendiginde ilk olarak eski sifrenin girilmesi istenir
;Eski sifrenin okunması bu alt program ile gerçeklenir.
;
eski_sifre_oku:
cpi Tus,10 ;Tus='*' ise RESET
breq son3
cpi Tus,11 ;Tus='#' ise ileri_3' git
breq ileri_3
inc s1 ;sayacı 1 artır
mov Temp,s1
cpi Temp,rakam+1 ;sayac 6 ile karşılaştırılıyor
brmi ekle_3 ;sayac>5 ise veri fazladır tabloya ekleme
ret
ekle_3:
cpi Temp,1
brne oku_3
ldi ZL,low(sifre_tablo+64) ;sifre tablosunun ilk adresi
ldi ZH,high(sifre_tablo+64);z işaretcisine yüklenir.
oku_3:
st Z+,Tus ;okunan tus tabloya yazılır.
ret
ileri_3:
mov Temp,s1 ;tus='#'(sonlanma karakteri) ise bu kod işlenir
cpi Temp,rakam
brne son3 ;sayaç!=5 ise veri sayısı hatalıdır.RESET
clr Temp
mov sifre_dogru,Temp
ldi YL,low(sifre_tablo+64)
ldi YH,high(sifre_tablo+64)
rcall sifre_kar ;girilen sifrenin dogru olup olmadığı bu
;altprogram ile test edilir.
mov Temp,sifre_dogru
cpi Temp,1 ;bayrak çekilmiş mi?
brne son3 ;bayrak!=1 ise hatalı giris, RESET
cbi PORTD,Eski_S_gir_LED ;girilen sifre dogru ise kullanıcının
sbi PORTD,y_s_1_gir_LED ;bundan haberdar olması için ve yeni ;sifrenin okunması için uygun ledler ;yakılır.
ldi temp,1 ;eski sifre doğru olduğu için
mov e_s_dogru,temp ;ilgili bayrak çekilir.
ret
son3:
rjmp RESET
;================================================= =============
;sifre degistirilmek istendiginde yeni girilecek sifre bu alt program ile
;
yeni_sifre_1_oku:
cpi Tus,10 ;Tus ='*' ise RESET
breq son4
cpi Tus,11 ;Tus sonlanma karakteri ise
breq ileri_1 ;yani tus='#' ise ileri git
inc s2 ;sayacı 1 artır
mov Temp,s2
cpi Temp,rakam+1 ;sayacı 6 ile karşılaştır
brmi ekle_1 ;eğer s2<=5 ise tuşu tabloya ekle
ret
ekle_1:
cpi Temp,1 ;eğer ilk sayı okunuyorsa
brne oku_1 ;tablo adresini oku
ldi ZL,low(yeni_sifre_1+64) ;Z işaretcisine tablonun baslangıç
ldi ZH,high(yeni_sifre_1+64) ;adresini yaz
oku_1:
st Z+,Tus ;Tus değerini tabloya yaz
ret
ileri_1:
mov Temp,s2
cpi Temp,rakam ;çıkış karakteri alındığında girilen veri
brne son4 ;sayısı doğru mu? Yanlış ise RESET
ldi Temp,1
mov yeni_sifre_okundu,Temp ;Veri girisi doğru ise bayrak çekilir.
cbi PORTD,y_s_1_gir_LED ;kullanıcının yeni sifreyi onaylamsı
sbi PORTD,y_s_2_gir_LED ;için yeni sifrenin bir daha okunması
;gerekir.Bunun için kullanıcı uygun ledler
;yakılarak yönlendirilir.
ret
son4:
rjmp RESET ;ilk kosullara don
;================================================= =============
;sifre degistirilmek istendiginde yeni sifre onaylanması için bir daha
;bu altprogram ile okunur.Eğer yeni girilen iki şifre aynı ise
;EEPROM' a yazılır.
yeni_sifre_2_oku:
cpi Tus,10 ;tus='*' ise RESET
breq son2
cpi Tus,11 ;Tus='#' ise
breq ileri_2 ;ileri_2'ye git
inc s3 ;sayacı 1 artır
mov Temp,s3
cpi Temp,rakam+1 ;sayacı 6 ile karşılaştır
brmi ekle_2 ;eğer s3<=5 ise tuşu tabloya ekle
ret ;s2>5 ise veri fazladır tebloya ekleme
;ve alt programdan dön
ekle_2:
cpi Temp,1 ;girilen sayı ilk sayı ise
brne oku_2
ldi ZL,low(yeni_sifre_2+64)
ldi ZH,high(yeni_sifre_2+64)
oku_2:
st Z+,Tus
ret
ileri_2:
mov Temp,s3
cpi Temp,rakam ;Çıkış karakteri okunduğunda girilen veri
brne son2 ;sayısı doğru mu? Yanlış ise RESET
clr Temp
mov yeni_sifreler_esit,Temp ;sonucun alınacağı bayrak sıfırlanır.
rcall yeni_sifreleri_karsilastir
mov Temp,yeni_sifreler_esit
cpi Temp,1 ;yeni girilen iki sifre aynı mı?
brne son2 ;değil ise RESET
cbi PORTD,y_s_2_gir_LED
;sbi PORTD,6;degistirildi_LED
rcall dly
rcall Sifreyi_yaz ;aynı ise sifreyi EEPROM'a yaz
son2:
rjmp RESET ;ilk koşullara dön
ret ;Alt programdan dön
;================================================= =============
;yeni girilen iki sifre bu altprogram ile kontrol edilir
;
;
yeni_sifreleri_karsilastir:
ldi sayac,rakam
ldi ZL,low(yeni_sifre_1+64) ;tabloların baslangıç adresleri
ldi ZH,high(yeni_sifre_1+64) ;Z ve Y isaretcilerine yazlır
ldi YL,low(yeni_sifre_2+64)
ldi YH,high(yeni_sifre_2+64)
geri:
ld temp,Z+
ld temp2,Y+
cp temp,temp2
brne quit
dec sayac
brne geri
ldi temp,1
mov yeni_sifreler_esit,temp
quit:
ret
;================================================= =============
;Aşağıdaki alt programlar EEPROM'a veri yazmak ya da
;EEPROM'dan veri okumak için kullanılır.
;
EEPROM_YAZ:
sbic EECR,EEWE
rjmp EEPROM_YAZ
out EEAR,EEADRES
out EEDR,eeveri
sbi EECR,EEMWE
sbi EECR,EEWE
ret
EEPROM_OKU:
sbic EECR,EEWE
rjmp EEPROM_OKU
out EEAR,eeadres
sbi EECR,EERE
sbi EECR,EERE
in eeveri,EEDR
ret
;================================================= ===========
;sifre değiştirilmek istendiğinde yeni girilen iki şifre
;aynı ise bu yeni şifre eski şifrenin yerine yazılır
;taban yeni sifrenin yazılacağı ilk bellek gözünü göstermektedir.
sifreyi_yaz:
ldi sayac,rakam
ldi ZL,low(yeni_sifre_1+64)
ldi ZH,high(yeni_sifre_2+64)
devam_et:
mov eeadres,taban
ld eeveri,Z+
rcall eeprom_yaz
inc taban
dec sayac
brne devam_et
ret
Bu uygulamada kullanıcı bir tuş takımı aracılığı ile mikrokontrolör ile iletişim kurabilmektedir.Kullanıcı, arabirim aracılığı ile şifresini ya da şifre değiştirmek isteğini kontrolöre bildirebilmektedir. Kontrolör tuş takımından okuduğu kodların anlamlarını çözerek kullanıcının isteği doğrultusunda gerekli işlemleri yerine getirebilmektedir. Çalışmanın bu bölümünde uygulamaya ilişkin donanım ve yazılım aşamaları hakkında bilgi verilmiştir. Yazılımın tamamı ise gerekli açıklamaları ve akış diyagramı ile birlikte ekler kısmında yer almaktadır. Tablo 3.1 de projenin gerçeklenmesi için gerekli olan malzeme tablosu verilmiştir.
3.1 Kullanıcı Arabirimi (Tuş Takımı)
Tuş takımı genellikle matris biçiminde yerleştirilmiş olan tuşlardan oluşur. Şifreli kapı kilidi uygulamasında kullanılan tuş takımı 4 x 3 lük bir matris biçimindedir.
Şekil 3.2’de 4x3 standart tuş takımı ile mikrokontrolör arasındaki donanım yapısı verilmiştir. Görüldüğü gibi tuş takımı matrisine ait 4 satır doğrudan mikrokontrolöre bağlanmıştır. Satırlara bağlı olan değil ve (NAND) kapısı herhangi bir tuşa basıldığında kesme üretmek amacıyla bağlanmıştır.
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Tuş takımının satırlarının okunabilmesi amacıyla satırların bağlı olduğu iskele kapıları alıcı olarak koşullanmıştır. Eğer hiç bir tuşa basılmamış ise bu 4 satırın bağlı olduğu kapılardan lojik 1 değeri okunur. Çünkü her satır bir direnç üzerinden kapılara bağlanmıştır. Ancak herhangi bir tuşa basılırsa bu tuşun bağlı olduğu satır hattı lojik 0 değerine düşeceği için kapıların okunması halinde 1111 değeri okunmaz.
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Şekil 3.2: Tuş takımının mikrokontrolör ile bağlantısı
Tuş takımının satırlarına bağlanmış olan dirençlerin değerlerinin büyük seçilmesi daha uygun olacaktır. Bir tuşa basıldığında kısa devre meydana geldiğinden çekilen akımın, dolayısıyla güç sarfiyatının az olması için direnç değerleri büyük olmalıdır. Ayrıca direnç değerlerinin küçük seçilmesi halinde (<1000ohm) kesmenin algılanması da güçleşecektir. Çünkü değil-ve kapısının girişlerinin lojik 0 olarak algılanabilmesi için giriş seviye geriliminin belirli bir düzeyin altında olması gerekmektedir.
Tuş takımının 3 adet sütunu ise yine 3 adet kapı tarafından sürülmektedir. Bu sütunların lojik 0 durumunda tutuldukları düşünülürse herhangi bir tuşa basılması halinde tuşun bulunduğu sütun ve satırın kısa devre olması ile ilgili satırın gerilimi de lojik 0 seviyesine düşecektir. Satırların hepsi bir değil-ve kapısı ile mikrokontrolürün kesme girişine bağlı olduğundan tuşa basılması kesme üretilmesini sağlayacaktır. Kesme hizmet programı içerisinde ise hangi tuşa basıldığı belirlenmektedir.
Yukarıdaki donanımın kontrolör tarafından algılanabilmesi için kontrolörün uygun şekilde koşullanması gerekmektedir. Bunun için aşağıdaki koşullamalar yapılmalıdır.
.EQU SATIR_1=0 ; EQU sembolik deyimi ile eşitlikler atanarak program
.EQU SATIR_2=1 ; daha anlaşılır bir yapıya getirilebilir.
.EQU SATIR_3=2
.EQU SATIR_4=3
.EQU SUTUN_1=4
.EQU SUTUN_2=5
.EQU SUTUN_3=6
cbi DDRB,SATIR_1 ; burada satırların okunacağı kapılar alıcı olarak
cbi DDRB,SATIR_2 ; koşullanmaktadır.
cbi DDRB,SATIR_3 ; cbi (clear bit )
cbi DDRB,SATIR_4 ; DDRB B iskelesine ilişkin yönlendirici
cbi PORTD,SATIR_1 ; Bu koşullamalar ise okunacak satırlara ilişkin
cbi PORTD,SATIR_1 ; kapıların dahili pull-up kullanmalarını sağlar.
cbi PORTD,SATIR_1
cbi PORTD,SATIR_1
sbi DDRB,SUTUN_1 ;buradaki koşullamalar ile tuş takımının bağlı
sbi DDRB,SUTUN_2 ;olduğu kapıların verici olarak koşullanması
sbi DDRB,SUTUN_3 ;sağlanmaktadır.
ldi temp,3 ;kesme izninin verilmesi ve kesmenin çıkan kenar
out MCUCR,temp ;tetiklemeli olması için gerekli koşullamalar.
ldi temp,64 ;MCUCR (MCU kontrol saklayıcısı)
out GIMSK,temp ;GIMSK (Genel kesme maskesi saklayıcısı)
sei ;Global kesme izninin verilmesi
Bu koşullamalar altında başlangıçta sütun hatlarının hepsi lojik 0 seviyesinde tutulmaktadır. Bu durumda bir tuşa basılması halinde NAND kapısının çıkışı 0’dan 1’e çıkacağı için ve kesme de çıkan kenarın algılanması ile gerçekleşeceği için kesme hizmet progr..... dallanılır. Kesme hizmet programı içerisinde ise sütun hatları belirli bir anda sadece birisi etkin durumda (lojik 0) olacak şekilde sürülür. Her durumda satırlar okunarak 0 seviyesindeki satır bulunmaya çalışılır. 0 seviyesindeki satır bulunduğunda sürülen sütun da belli olduğundan basılan tuş belirlenir ve tuşun değeri bir saklayıcıya yazılır.
Tuş okuma alt programında öncelikle sütunlar sıra ile belirli bir süre sürülmekte ve satırlar okunmaktadır. Burada sütunların sürülmesinin hemen ardında ik bir gecikme programı çalıştırılmaktadır. Bu gecikme programının çalıştırılmadığı durumda satırların okunması halinde doğru bilgi alınması mümkün olmayacaktır. Çünkü sadece birkaç saat darbesi ardından bir satır 1 seviyesinde 0’a düşecek olsa bile bu durum, program tarafından sezilemeyecektir. Çünkü lojik 0’dan lojik 1’e ya da tersi geçişler belirli bir gecikme ile gerçekleşmektedir.Gecikme programı eğer bir geçiş varsa bu geçişin kesin olarak algılanabilmesini sağlar. Burada akla şu soru gelebilir , “acaba bir tuşa basıldığı halde gecikme programından dolayı tuşun algılanamaması olasılığı var mıdır?”. Tuşun algılanamaması olasılığı yoktur çünkü gecikme programı sadece bir kaç ms’lik bir gecikme sağlamaktadır. Bir insanın bir tuşa basıp elini çekmesi için ise en azından 200ms’lik bir zamana ihtiyaç vardır.Bu durumda basılan tuş kesinlikle
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Şekil 3.3: Tus okuma alt progr..... ilişkin akış diyagramı
3.2. Uygulama İçin Kullanılan Yazılım
Şifreli kapı kilidi uygulamasındaki yazılımda program ilk koşulların belirlenmesinin ardından sonsuz döngüde beklemektedir. Bir tuşa basılıp kesme alınması ile bir kesme hizmet progr..... dallanılmakta ve basılan tuşun belirlenmesinin ardından yapılması gereken işlemler tamamlandıktan sonra kesmeden dönülmekte ve sonsuz döngüde beklemeye devam edilmektedir.Görüldüğü gibi bütün işlemler kesme hizmet programı içerisinde gerçekleştirilmektedir.
Yazılım aslında bir sonlu durum makinası gibi çalışmaktadır. Basılan tuş belirlendikten sonra eğer tuş ‘*’ ise şifre değiştirme durumuna geçilmektedir ve geçilen durum ilgili led ‘ler yakılarak kullanıcıya bildirilmektedir. Şifre değiştirme durumunda iken şifre değiştirme durum led’i ve eski sifrenin girilmesinin beklendiğini belirten durum led’i yakılır. Kullanıcı eski şifreyi girdikten sonra ‘# ’ tuşuna basarak girişi tamamladığını bildirir. Girilen karakterler bir sifre tablosunda tutulmaktadır ve ‘# ‘ tuşunun okunması ile bu tablodaki karakterler ile EEPROM’daki şifre karakterleri karşılaştırılır. EEPROM da 25 adet 5 uzunluklu şifre bulunmaktadır. Yani yapı çok kullanıcılı olarak tasarlanmıştır. Bu nedenle şifre tablosundaki veri ile 25 farklı şifre bloğu karşılaştırılır. Eğer girilen şifre ile EEPROM şifreleri arasında uyuşma söz konusu değilse yine ilk koşullara dönülmektedir. Ayrıca kullanıcının hatalı, eksik ya da fazla veri girişi yaptığı durumlarda da ilk koşullara dönülmektedir. Eski şifrenin doğru olarak okunması halinde ise yeni şifrenin okunması durumuna geçilmektedir ve bu durum bir led ile kullanıcıya iletilmektedir. Yine 5 karakterlik yeni şifre bir tabloda tutulmaktadır. Eğer veri girişinde bir hata söz konusu değilse yeni sifrenin onaylanması için bir daha girilmesinin bekleneceği bir duruma geçilecektir. Bu durum da yine kullanıcının haberdar olması için bir led ile bildirilecektir. Kullanıcının girmiş olduğu iki yeni sifre karşılaştırılarak aynı olup olamadıkları kontrol edilir.Eğer girilen yeni sifreler aynı ise bu sifre ile EEPROM’da bulunan sifre değistirilmektedir.
Eğer kullanıcı doğrudan şifre girmeye başladı ise şifre okuma durumuna geçilmektedir. Bu durum içerisinde iken kullanıcının girmiş olduğu karakterler şifre tablosunda tutulmakta ve ‘# ‘ okununcaya kadar bu durum içerisinde kalınmaktadır. Eğer ‘# ‘ karakteri okunduğunda girilmiş olan şifre formatı doğru ise bu şifre ile EEPROM’da bulunan 25 adet şifre karşılaştırılmaktadır. Eğer şifre doğru ise kapının açılması için ilgili iskele kapısı çıkışı lojik 1 düzeyine çekilmektedir. Yaklaşık olarak 1sn boyunca lojik 1 uygulandıktan sonra ise yine ilk koşullara dönülmektedir.
3.3. Program Durum Diyagramı
Şekil 3.4’te durum diyagramında durumlar arası ilşikiler açık bir şekilde görülebilir.
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Şekil 3.4: Yazılıma ilişkin durum diyagramı
Diyagramdan da görüldüğü gibi çıkış karakteri (‘# ’) alınıncaya kadar bir durum içerisinde kalınmakta ve çıkış karakterinin ardından veri girişi kontrol edilmektedir. Hatalı veri girişi yapılması ilk koşullara dönülmesine neden olmaktadır.İlk koşullarda ise bütün saklayıcılara ilk değerleri yüklenmekte aslında sistem reset’lenmektedir. Böylece yapının devamlılığı sağlanabilmektedir.
Yazılımda durumlar arası geçişler bayraklar ile kontrol altında tutulmaktadır. Uygulamaya ilişkin yazılım ve akış diyagramı ekler kısmında açıklamalı olarak verilmiştir.
3.4 Proje DonanımYapısı
Belirtilen koşulları sağlayan projeye ilişkin ilişkin donanım şeması Şekil3.5’te verilmiştir
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
Şekil 3.5: Projeye ilişkin donanım şeması
EK – A PROGRAM AKIŞ DİYAGRAMI
[Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.] ([Linkleri görebilmek için kayıt olmanız gerekiyor. http://www.forumturka.net/forum/register.php link'ini alıp browser'ınıza yapıştırmanız yeterlidir.])
EK-B PROGRAM KODU
.include "2313def.inc"
.DEF temp =R16
.DEF tus =R17
.DEF delay1 =R18
.DEF delay2 =R19
.DEF taban =R20
.DEF sayac =R21
.DEF veri =R22
.DEF EEVeri =R23
.DEF EEAdres=R24
.DEF temp2 =R25
.DEF s1 =R0 ;sifre okumak için ve
.DEF s2 =R1 ;sifre degidtirmek için
.DEF s3 =R2 ;alt programlarda kullanılan sayaclar
.DEF s4 =R3
.DEF sifre_dogru =R4 ;bayrak saklayıcısıları
.DEF e_s_dogru =R5
.DEF yeni_sifre_okundu =R6
.DEF yeni_sifreler_esit =R7
.DEF sifre_degistir =R8
.DEF sifre_girme =R9
.DEF hata =R10
.EQU rakam =5 ;sifre buyu bu sabit ile belirlenir.
.EQU SUTUN_1 =0 ;tuş takımı sütunları
.EQU SUTUN_2 =1
.EQU SUTUN_3 =2
.EQU SATIR_1 =3 ;tuş takımı satırları
.EQU SATIR_2 =4
.EQU SATIR_3 =5
.EQU SATIR_4 =6
.EQU s_degistir_LED=0
.EQU eski_s_gir_LED=1
.EQU y_s_1_gir_LED=3
.EQU y_s_2_gir_LED=4
.EQU KAPIYI_AC =5
.EQU S_gir_LED =6
.DSEG
yeni_sifre_1: .BYTE 5 ;Yeni sifre tablosu 1 için 5 byte ayır yeni_sifre_2: .BYTE 5 ;Yeni sifre tablosu 2 için 5 byte ayır sifre_tablo: .BYTE 5 ;sifre tablosuna 5 byte ayır
.CSEG
.ORG 0X00
rjmp RESET ;Power-on Reset
rjmp kesme ;Kesme isteği0(IRQ0)
rjmp RESET ;Kesme isteği1(IRQ1)
rjmp RESET ;Zamanlayıcı 1 yakalama
rjmp RESET ;Zamanlayıcı 1 karşılaştırma
rjmp RESET ;zamanşayıcı 1 taşma
rjmp RESET ;zamanlayıcı 0 taşma
rjmp RESET ;ASİA,Rx coplete
rjmp RESET ;ASİA,veri saklayıcısı boş
rjmp RESET ;ASİA,Tx complete
rjmp RESET ;analog karşılaştırıcı
.CSEG
reset:
cli ;kesme iznini kaldır
;--------------------------------------
;Yığın isaretcisine ilk değerinin verilmesi
;
ldi Temp, low(RAMEND)
out SPL, Temp
;--------------------------------------
;iskele alıcı-verici kosullamaları
;ve ilk değerlerin verilmesi
sbi DDRB,SUTUN_1
sbi DDRB,SUTUN_2
sbi DDRB,SUTUN_3
cbi PORTB,SUTUN_1
cbi PORTB,SUTUN_2
cbi PORTB,SUTUN_3
cbi DDRB,SATIR_1
cbi DDRB,SATIR_2
cbi DDRB,SATIR_3
cbi DDRB,SATIR_4
sbi DDRD,0
sbi DDRD,1
cbi DDRD,2
sbi DDRD,3
sbi DDRD,4
sbi DDRD,5
sbi DDRD,6
cbi PORTD,0
cbi PORTD,1
cbi PORTD,3
cbi PORTD,4
cbi PORTD,5
cbi PORTD,6
;------------------------------------------
;kullanılan sayaclara ilk değerlerinin atanması
ldi temp,0
mov s1,temp
ldi temp,0
mov s2,temp
ldi temp,0
mov s3,temp
ldi temp,0
mov s4,temp
;---------------------------------------------
;bayraklara ilk değer atanması
ldi temp,0
mov e_s_dogru,temp
mov sifre_girme,temp
mov sifre_degistir,temp
mov sifre_dogru,temp
mov yeni_sifre_okundu,temp
mov hata,temp
;----------------------------------------------
;kesme izninin verilmesi
ldi temp,3
out MCUCR,temp
ldi temp,64
out GIMSK,temp
sei ;global kesme izin biti 1'lenir
rjmp anacevrim ;anacevrim'e dallan
anacevrim:
rjmp anacevrim ;anacevrimde program sonsuz döngüde beklemek-
;tedir. Bütün iş kesme hizmet programı
;içerisinde yapılmaktadır.
;================================================= ==========
;kesme hizmet programı
;
;
kesme:
rcall tusoku ;kesme tuş takımından alındığı için
;basılan tuşu "tuşoku" alt programı ile belirle
mov temp,hata ;eğer hata=-1 ise basılan tuş belirlenememiştir
cpi temp,-1 ;bu durumda hata=0 yapılarak kesmeden dönülür.
brne L ;aksi halde kesme hizmet programı çalışmaya devam
ldi temp,0 ;eder.
mov hata,temp
reti
L:
cpi tus,10 ;tus='*' mı?
brne x ;tus='*' değilse x'git
mov temp,sifre_girme
cpi temp,0 ;sifre_girme=1 ve tus="*" ise sonlan
brne sonlan
mov temp,sifre_degistir
cpi temp,0 ;sifre_degistir=1 ise ve yine tus='*'
brne sonlan ;tusuna basılmış ise RESET(sonlan)
ldi temp,1
mov sifre_degistir,temp ;"*" tusuna ilk kez basımış ise
sbi PORTD,S_degistir_LED ;bayrak çekilir ve kullanıcı ledler ile
sbi PORTD,Eski_S_gir_LED ;uyarılır.
bekle:
sbic PIND,2 ;kesme alınan bacak lojik 0 düzeyine
rjmp bekle ;düşene kadar beklenir.(kullanıcının elini rcall dly ;tuştan çekmesi bekleniyor)
reti ;kesmeden dön
x: ;tus!=* ise bu kod yürütülür. mov temp,sifre_degistir
cpi temp,1
brne sifre_okuma ;sifre_degistir!=1 ise sifre_okuma ya git
mov temp,e_s_dogru ;sifre_degistir=1 ise eski sifre okundu mu?
cpi temp,1 ;eski sifre okunmus mu?
brne eski_s_oku ;okunmamıs ise eski sifreyi oku
mov temp,yeni_sifre_okundu ;eski sifre okunmus ise
cpi temp,1 ;yeni sifre okunmus mu?
brne yeni_s_oku ;okunmamıs ise oku
rcall yeni_sifre_2_oku ;okunmus ise yeni sifre 2'yi oku
bekle_1:
sbic PIND,2 ;kullanıcının elini çekmesi bekleniyor.
rjmp bekle_1
rcall dly
reti
sifre_okuma:
ldi temp,1
mov sifre_girme,temp
;sbi PORTD,s_gir_LED
rcall sifre_oku
bekle_2:
sbic PIND,2 ;kullanıcının tuştan elini çekmesi bekleniyor.
rjmp bekle_2
rcall dly
reti
eski_s_oku: ;sifre_degistir=1 ise bu kod parcası
;yürütülür.
rcall eski_sifre_oku
bekle_3:
sbic PIND,2 ;kullanıcını elini çekmesi bekleniyor.
rjmp bekle_3
rcall dly
reti
yeni_s_oku: ;eski sifre okunmus ve dogru ise bu kod
;parcası yürütülür.
rcall yeni_sifre_1_oku
bekle_4:
sbic PIND,2 ;kullanıcını elini çekmesi bekleniyor.
rjmp bekle_4
rcall dly
reti
sonlan:
ldi temp,100
g: rcall dly
dec temp
brne g
bekle_5:
sbic PIND,2
rjmp bekle_5
rcall dly
rjmp RESET
;================================================= ============
;Kesme alındığında hangi tuşa basıldığını bulan kesme hizmet programı
;
;
tusoku:
sec ;eldebayrağı=1 yap
ldi Temp, 0b11111011 ;baslangıçta SUTUN_3 etkin durumda
ldi sayac,0
yeniden_tara:
out PORTB,Temp
rcall dly ;gecikme süresi kadar bekle
sbis PINB, SATIR_1 ;SATIR_1 biti 1 ise tusa basılmamıstır
rjmp S_1 ;bu bit 0 ise tusa basılmıstır.s_1'e git
sbis PINB, SATIR_2 ;SATIR_2 biti 1 ise tusa basılmamıstır
rjmp s_2 ;bu bit 0 ise tusa basılmıstır.s_2'ye git
sbis PINB, SATIR_3 ;SATIR_3 biti 1 ise tusa basılmamıstır
rjmp s_3 ;bit 0 ise tusa basılmıstır.s_3'e git
sbis PINB, SATIR_4 ;SATIR_4 biti 1 ise tusa basılmamıstır
rjmp s_4 ;bit 0 ise tusa basılmıstır.s_4'e git
inc sayac ;sayacı 1 artır
cpi sayac,3 ;sayac!=3 ise bütün sütunlar taranmamıştır.
breq son_1 ;sayac=3 ise tus bulunamdığı için son_1'e git
ror Temp ;diger sutuna bak
rjmp yeniden_tara
son_1:
ldi temp,-1 ;bütün sütunlar tarandığı halde tuş
mov hata,temp ;bulunamadığı için hata=-1 yaz
rjmp son1
s_1: ;tus satır 1'de ise bu kod işlenir
sbic PORTB,SUTUN_1
rjmp else1 ;SUTUN_1=1 ise diger sutunlara bak
ldi TUS,1 ;SUTUN_1=0 ise 1 tusuna basılmıstır.
rjmp bitti
else1:
sbic PORTB,SUTUN_2
rjmp else2 ;SUTUN_2=1 ise diger sutuna bak
ldi TUS,2 ;SUTUN_2=0 ise 2 tusuna basılmıstır.
rjmp bitti
else2:
ldi TUS,3 ;SUTUN_3=0 olduğu için 3 tusuna basılmıstır.
rjmp bitti
s_2: ;tus satır 2'de ise bu kod işlenir
sbic PORTB,SUTUN_1
rjmp else3 ;SUTUN_1=1 ise diger sutunlara bak
ldi TUS,4 ;SUTUN_1=0 ise 4 tusuna basılmıstır.
rjmp bitti
else3:
sbic PORTB,SUTUN_2
rjmp else4 ;SUTUN_2=1 ise diger sutuna bak
ldi TUS,5 ;SUTUN_2=0 ise 5 tusuna basılmıstır.
rjmp bitti
else4:
ldi TUS,6 ;SUTUN_3=0 olduğu için 6 tusuna basılmıstır.
rjmp bitti
s_3: ;tus satır 3'de ise bu kod işlenir
sbic PORTB,SUTUN_1
rjmp else5 ;SUTUN_1=1 ise diger sutunlara bak
ldi TUS,7 ;SUTUN_1=0 ise 7 tusuna basılmıstır.
rjmp bitti
else5:
sbic PORTB,SUTUN_2
rjmp else6 ;SUTUN_2=1 ise diger sutuna bak
ldi TUS,8 ;SUTUN_2=0 ise 8 tusuna basılmıstır.
rjmp bitti
else6:
ldi TUS,9 ;SUTUN_3=0 olduğu için 9 tusuna basılmıstır.
rjmp bitti
s_4: ;tus satır 4'de ise bu kod işlenir
sbic PORTB,SUTUN_1
rjmp else7 ;SUTUN_1=1 ise diger sutunlara bak
ldi TUS,10 ;SUTUN_1=0 ise '*' tusuna basılmıstır.
rjmp bitti
else7:
sbic PORTB,SUTUN_2
rjmp else8 ;SUTUN_2=1 ise diger sutuna bak
ldi TUS,0 ;SUTUN_2=0 ise 0 tusuna basılmıstır.
rjmp bitti
else8:
ldi TUS,11 ;SUTUN_3=0 olduğu için '#' tusuna basılmıstır.
bitti:
son1:
ldi temp,0b11111000
out PORTB,temp
ret
;================================================= =============
;gecikme programı [(3*255)*(250e-9)]*10=2ms (kristal=4MHz)
;
dly: ldi delay2,10
s:
dec delay1
brne s
dec delay2
brne s
ret
;================================================= =============
;kapının açılamsı için şifre girildiğinde bu alt program işlenir
;
sifre_oku:
cpi Tus,10 ;Tus='*' ise RESET
breq son
cpi Tus,11 ;Tus='#' ise ileri_4'e git
breq ileri_4
inc s4 ;sayacı 1 artır
mov Temp,s4
cpi Temp,rakam+1 ;sayac 6 ile karşılaştırılıyor
brmi ekle_4 ;sonuç negatif ise(s4<6)tuşu tabloya ekle
ret ;s4>=6 ise fazla tuş girilmiştir, dön
ekle_4:
cpi Temp,1
brne oku_4 ;eğer ilk tuş ise tablnun adresni
ldi ZL,low(sifre_tablo+64) ;Z işaretcisine yaz
ldi ZH,high(sifre_tablo+64)
oku_4:
st Z+,Tus ;Tusu işaretçi ile gösterilen yere yaz
ret ;dön
ileri_4:
mov Temp,s4
cpi Temp,rakam
;sayaç!=5 ise veri sayısı hatalı,RESET
brne son
clr Temp
mov sifre_dogru,Temp
ldi YL,low(sifre_tablo+64)
ldi YH,high(sifre_tablo+64)
rcall sifre_kar ;girilen sifre ile EEPROM' daki sifre kars.
mov temp,sifre_dogru
cpi temp,1
brne son ;sifre hatalı ise RESET
sbi PORTD,KAPIYI_AC ;sifre dogru oldugu için kapıyı aç
t:
rcall dly ;0,7 sn süresince lojik 1 uygula
dec temp
brne t
k:
rcall dly ;0,7 sn süresince lojik 1 uygula
dec temp
brne k
son:
rcall dly
rjmp RESET
;================================================= =============
;bu altprogragram kullanıcı tarafından girilen sifre ile EEPROM da bulunan sifreleri
;karşılaştırır.Eğer girilen sifre doğru ise sifre_doğru bayrağını 1'ler
Sifre_Kar:
ldi EEadres,$00
mov Taban, EEadres
ldi sayac,rakam
Karsilastir:
rcall EEPROM_OKU
ld Veri, Y+ ;X sifrenin bulundugu tablonun ilk adresi
cp Veri, EEveri ;Tablodaki veri ile sifre verisi aynı mı?
brne esit_degil ;Aynı değilse esit_degil'e git
dec sayac ;aynı ise sayacı azalt
breq esit ;ve esit'e git
inc EEadres ;EEPROM isaretcisini bir artır.
rjmp Karsilastir
esit_degil:
ldi Temp, rakam ;Sifre hatalı olduğu için bir sonraki
add Taban, Temp ;şifre bloğuna geç
cpi Taban, 8
brpl exit ;Taban>126 ise EEPROM sonu olduğu için çık
ldi sayac, rakam
mov Eeadres,taban
ldi YL,low(sifre_tablo+64)
ldi YH,high(sifre_tablo+64)
rjmp Karsilastir
esit:
ldi temp,1
mov sifre_dogru,temp ;şifre doğru olduğundan ilgili bayrak 1'lenir
exit:
ret
;================================================= =============
;sifre degistirilmek istendiginde ilk olarak eski sifrenin girilmesi istenir
;Eski sifrenin okunması bu alt program ile gerçeklenir.
;
eski_sifre_oku:
cpi Tus,10 ;Tus='*' ise RESET
breq son3
cpi Tus,11 ;Tus='#' ise ileri_3' git
breq ileri_3
inc s1 ;sayacı 1 artır
mov Temp,s1
cpi Temp,rakam+1 ;sayac 6 ile karşılaştırılıyor
brmi ekle_3 ;sayac>5 ise veri fazladır tabloya ekleme
ret
ekle_3:
cpi Temp,1
brne oku_3
ldi ZL,low(sifre_tablo+64) ;sifre tablosunun ilk adresi
ldi ZH,high(sifre_tablo+64);z işaretcisine yüklenir.
oku_3:
st Z+,Tus ;okunan tus tabloya yazılır.
ret
ileri_3:
mov Temp,s1 ;tus='#'(sonlanma karakteri) ise bu kod işlenir
cpi Temp,rakam
brne son3 ;sayaç!=5 ise veri sayısı hatalıdır.RESET
clr Temp
mov sifre_dogru,Temp
ldi YL,low(sifre_tablo+64)
ldi YH,high(sifre_tablo+64)
rcall sifre_kar ;girilen sifrenin dogru olup olmadığı bu
;altprogram ile test edilir.
mov Temp,sifre_dogru
cpi Temp,1 ;bayrak çekilmiş mi?
brne son3 ;bayrak!=1 ise hatalı giris, RESET
cbi PORTD,Eski_S_gir_LED ;girilen sifre dogru ise kullanıcının
sbi PORTD,y_s_1_gir_LED ;bundan haberdar olması için ve yeni ;sifrenin okunması için uygun ledler ;yakılır.
ldi temp,1 ;eski sifre doğru olduğu için
mov e_s_dogru,temp ;ilgili bayrak çekilir.
ret
son3:
rjmp RESET
;================================================= =============
;sifre degistirilmek istendiginde yeni girilecek sifre bu alt program ile
;
yeni_sifre_1_oku:
cpi Tus,10 ;Tus ='*' ise RESET
breq son4
cpi Tus,11 ;Tus sonlanma karakteri ise
breq ileri_1 ;yani tus='#' ise ileri git
inc s2 ;sayacı 1 artır
mov Temp,s2
cpi Temp,rakam+1 ;sayacı 6 ile karşılaştır
brmi ekle_1 ;eğer s2<=5 ise tuşu tabloya ekle
ret
ekle_1:
cpi Temp,1 ;eğer ilk sayı okunuyorsa
brne oku_1 ;tablo adresini oku
ldi ZL,low(yeni_sifre_1+64) ;Z işaretcisine tablonun baslangıç
ldi ZH,high(yeni_sifre_1+64) ;adresini yaz
oku_1:
st Z+,Tus ;Tus değerini tabloya yaz
ret
ileri_1:
mov Temp,s2
cpi Temp,rakam ;çıkış karakteri alındığında girilen veri
brne son4 ;sayısı doğru mu? Yanlış ise RESET
ldi Temp,1
mov yeni_sifre_okundu,Temp ;Veri girisi doğru ise bayrak çekilir.
cbi PORTD,y_s_1_gir_LED ;kullanıcının yeni sifreyi onaylamsı
sbi PORTD,y_s_2_gir_LED ;için yeni sifrenin bir daha okunması
;gerekir.Bunun için kullanıcı uygun ledler
;yakılarak yönlendirilir.
ret
son4:
rjmp RESET ;ilk kosullara don
;================================================= =============
;sifre degistirilmek istendiginde yeni sifre onaylanması için bir daha
;bu altprogram ile okunur.Eğer yeni girilen iki şifre aynı ise
;EEPROM' a yazılır.
yeni_sifre_2_oku:
cpi Tus,10 ;tus='*' ise RESET
breq son2
cpi Tus,11 ;Tus='#' ise
breq ileri_2 ;ileri_2'ye git
inc s3 ;sayacı 1 artır
mov Temp,s3
cpi Temp,rakam+1 ;sayacı 6 ile karşılaştır
brmi ekle_2 ;eğer s3<=5 ise tuşu tabloya ekle
ret ;s2>5 ise veri fazladır tebloya ekleme
;ve alt programdan dön
ekle_2:
cpi Temp,1 ;girilen sayı ilk sayı ise
brne oku_2
ldi ZL,low(yeni_sifre_2+64)
ldi ZH,high(yeni_sifre_2+64)
oku_2:
st Z+,Tus
ret
ileri_2:
mov Temp,s3
cpi Temp,rakam ;Çıkış karakteri okunduğunda girilen veri
brne son2 ;sayısı doğru mu? Yanlış ise RESET
clr Temp
mov yeni_sifreler_esit,Temp ;sonucun alınacağı bayrak sıfırlanır.
rcall yeni_sifreleri_karsilastir
mov Temp,yeni_sifreler_esit
cpi Temp,1 ;yeni girilen iki sifre aynı mı?
brne son2 ;değil ise RESET
cbi PORTD,y_s_2_gir_LED
;sbi PORTD,6;degistirildi_LED
rcall dly
rcall Sifreyi_yaz ;aynı ise sifreyi EEPROM'a yaz
son2:
rjmp RESET ;ilk koşullara dön
ret ;Alt programdan dön
;================================================= =============
;yeni girilen iki sifre bu altprogram ile kontrol edilir
;
;
yeni_sifreleri_karsilastir:
ldi sayac,rakam
ldi ZL,low(yeni_sifre_1+64) ;tabloların baslangıç adresleri
ldi ZH,high(yeni_sifre_1+64) ;Z ve Y isaretcilerine yazlır
ldi YL,low(yeni_sifre_2+64)
ldi YH,high(yeni_sifre_2+64)
geri:
ld temp,Z+
ld temp2,Y+
cp temp,temp2
brne quit
dec sayac
brne geri
ldi temp,1
mov yeni_sifreler_esit,temp
quit:
ret
;================================================= =============
;Aşağıdaki alt programlar EEPROM'a veri yazmak ya da
;EEPROM'dan veri okumak için kullanılır.
;
EEPROM_YAZ:
sbic EECR,EEWE
rjmp EEPROM_YAZ
out EEAR,EEADRES
out EEDR,eeveri
sbi EECR,EEMWE
sbi EECR,EEWE
ret
EEPROM_OKU:
sbic EECR,EEWE
rjmp EEPROM_OKU
out EEAR,eeadres
sbi EECR,EERE
sbi EECR,EERE
in eeveri,EEDR
ret
;================================================= ===========
;sifre değiştirilmek istendiğinde yeni girilen iki şifre
;aynı ise bu yeni şifre eski şifrenin yerine yazılır
;taban yeni sifrenin yazılacağı ilk bellek gözünü göstermektedir.
sifreyi_yaz:
ldi sayac,rakam
ldi ZL,low(yeni_sifre_1+64)
ldi ZH,high(yeni_sifre_2+64)
devam_et:
mov eeadres,taban
ld eeveri,Z+
rcall eeprom_yaz
inc taban
dec sayac
brne devam_et
ret