T.C. GAZİ ÜNİVERSİTESİ TEKNİK EĞİTİM FAKÜLTESİ ROBOGAZİ ROBOT TOPLULUĞU ROBOTİK VE PIC DERSLERI III PROTON İLE PIC PROGRAMLAMA ARŞ. GÖR. FECİR DURAN
T.C.
GAZİ ÜNİVERSİTESİ
TEKNİK EĞİTİM FAKÜLTESİ
ROBOGAZİ ROBOT TOPLULUĞU
ROBOTİK VE PIC DERSLERI III
PROTON İLE PIC PROGRAMLAMA
ARŞ. GÖR. FECİR DURAN
NOT: BU NOTLARIN HAZIRLANMASINDA SEÇİL KARABIYIK VE BÜTÜN
ROBOGAZİ EKİBİNİN EMEĞİ GEÇMİŞTİR.
ANKARA
2006
İÇİNDEKİLER
SAYFA
1. BUTONA BASINCA LEDI YAKAN BIRAKINCA SÖNDÜREN PROGRAM........1
2. BUTONA BASINCA LEDLERI YAKAN, TEKRAR BASINCA SÖNDÜREN
PROGRAM...............................................................................................................................2
3. KARAŞIMŞEK ( LEDLERI SIRAYLA YAKAN PROGRAM)..................................4
4. 3 BUTON KULLANILACAK ; 1. BUTONA BASINCA TOGGLE , 2. BUTONA
BASINCA KARAŞIMŞEK , 3. BUTONA BASINCA DA ÖNCE ILK DÖRT BITI
YAKIP SONRA TERSLEYEN PROGRAM.........................................................................6
5. 7 SEGMENT DISPLAYDE BUTONA BASTIKÇA 0-F ARASI SAYDIRAN
PROGRAM...............................................................................................................................9
6. LCD UYGULAMASI.....................................................................................................12
7. WHILE-WEND DÖNGÜSÜYLE KARAŞIMŞEK PROGRAMI..............................14
8. TUŞTAKIMINDAN GIRILEN SÜREYE GÖRE GERI SAYAN PROGRAM FOR-
NEXT DÖNGÜSÜ..................................................................................................................16
9. KEYPAD’DEN GIRILEN KODA GÖRE BAĞLI OLDUĞU LEDI YAKAN
PROGRAM.............................................................................................................................19
10. KEYPAD’DEN GIRILEN KODA GORE BAĞLI OLDUĞU LEDI YAKAN
PROGRAM (CASE-SELECT)..............................................................................................22
11. LCD VE KEYPAD UYGULAMASI(BISKÜVI-MATIK)......................................25
12. RB0 INTERRUPTININ KULLANIMI.....................................................................33
13. RB4-RB7 DEĞIŞIM INTERRUPTININ KULLANIMI.........................................35
14. TIMER1 INTERRUPTININ KULLANIMI.............................................................37
15. PWM’IN KULLANIMI..............................................................................................39
ii
1. BUTONA BASINCA LEDİ YAKAN BIRAKINCA SÖNDÜREN PROGRAM
Device=16F84
TRISA=%00000001 ‘PORTA’nın 1. ucunu giriş
TRISB=%00000000 ‘PORTB’yi çıkış yap
Dim BUTON As PORTA.0 ‘PORTA’nın 0. ucunda buton,
Dim LEDLER As PORTB ‘PORTB de ledler var
ANAPROG:
If BUTON=1 Then ‘butona basınca ledi yak
LEDLER=%11111111
Else
LEDLER=%00000000 ‘bırakınca söndür’
EndIf
GoTo ANAPROG
End
PROTEUS DEVRESİ:
1
2. BUTONA BASINCA LEDLERİ YAKAN, TEKRAR BASINCA SÖNDÜREN
PROGRAM
Butonun mevcut durumu saklanarak her butona basıldığında ledin durumunu tersleyen
program.
Device=16F84
TRISA=%00000001 ‘PORTA’nın 1. ucunu giriş
TRISB=%00000000 ‘PORTB çıkış yap
Dim BUTON As PORTA.0 ‘PORTA’nın 0. ucunda buton,
Dim LEDLER As PORTB ‘PORTB de ledler
Dim DURUM As Bit ‘Ledlerin durumunu saklayan durum biti tanımlanır.
PORTA=0
PORTB=0
BASLA:
If BUTON=1 Then ‘BUTON’a basıldı mı?
BUTONDUR: ‘buton basılı kaldığı sürece döngü oluşturur.
If BUTON=1 Then GoTo BUTONDUR ‘Buton arkını önler.
DURUM=0 Then ‘DURUM bitine bak 0’sa
LEDLER=%11111111 ‘LEDLER’i yak
DURUM=1 ‘DURUM’u birle
Else ‘ DURUM=0 değilse
LEDLER=%00000000 ‘LEDLER’I söndür
DURUM=0 ‘DURUM’u sıfırla
EndIf
EndIf
GoTo BASLA
End
2
PROTEUS DEVRESİ:
3
3. KARAŞİMŞEK ( LEDLERİ SIRAYLA YAKAN PROGRAM)
Device=16F84
Dim LEDLER As PORTB ‘PORTB de ledler var
Dim SAY As Byte ‘SAY değişkenini byte olarak ata
Dim DUR As 200 ‘DUR’un içine 200 ms’lik gecikme koy
TRISB=0 ‘PORTB’nin uçlarını çıkış olarak ayarla
PORTB=0 ‘PORTB’yi sıfırla
BASLA:
LEDLER=SAY ‘LEDLER’i saya at
DelayMS DUR ‘200 ms gecik
ILERLE:
If SAY<=127 Then ‘SAY 127’den küçük olduğu sürece
SAY=1+SAY*2 ‘SAY’ı iki katını alıp 1 ekle
LEDLER=SAY ‘LEDLER’i SAYa at
DelayMS DUR ‘200 ms gecik
GoTo ILERLE ‘SAY’ın içi 127’den küçükse ILERLE’ya git
Else
AZALT:
If SAY>=1 Then ‘SAY 1’den büyük eşit olduğu sürece
SAY=((SAY-1)/2) ‘SAY’dan 1 çıkar 2ye böl
LEDLER=SAY ‘LEDLER’i saya at
DelayMS DUR
GoTo AZALT ‘SAY 1’den büyük olduğu sürece AZALT’a git
EndIf ‘değilse
GoTo BASLA ‘BASLA’ya git
EndIf
End
4
PROTEUS DEVRESİ:
5
4. 3 BUTON KULLANILACAK ; 1. BUTONA BASINCA TOGGLE , 2. BUTONA
BASINCA KARAŞİMŞEK , 3. BUTONA BASINCA DA ÖNCE İLK DÖRT BİTİ
YAKIP SONRA TERSLEYEN PROGRAM
Device=16F84
Dim LEDLER As PORTB ‘PORTB de ledler var
Dim SAY As Byte ‘SAY değişkenini byte olarak ata
Dim DURUM1 As Bit ‘durum bitleri tanımlanır
Dim DURUM2 As Bit
Dim BUTON1 As PORTA.0 ‘PORTA’nın 0. ucunda BUTON1
Dim BUTON2 As PORTA.1 ‘PORTA’nın 1. ucunda BUTON2
Dim BUTON3 As PORTA.2 ‘PORTA’nın 2. ucunda BUTON3
Dim BUTON4 As PORTA.3 ‘PORTA’nın 3. ucunda BUTON4
Dim DUR As 200 ‘200 ms gecikmeyi DUR’un içine at
TRISB=0 ‘PORTB’nin uçlarını çıkış olarak ayarla
PORTB=0 ‘PORTB’yi sıfırla
BASLA:
If BUTON1=1 Then GoSub PROG1 ‘BUTON1e basıldıysa PROG1’e dallan
If BUTON2=1 Then GoSub PROG2 ‘BUTON2ye basıldıysa PROG2’e dallan
If BUTON3=1 Then GoSub PROG3 ‘BUTON3e basıldıysa PROG3’e dallan
GoTo BASLA
PROG1:
BUTONDUR1:
If BUTON1=1 Then GoTo BUTONDUR1
If DURUM1=0 Then
LEDLER=%11111111
DURUM1=1
Else
LEDLER=%00000000
DURUM1=0
EndIf
Return ‘alt programdan çık
6
PROG2:
BUTONDUR2:
If BUTON2=1 Then GoTo BUTONDUR2
LEDLER=SAY
DelayMS DUR
ILERLE:
If SAY<=127 Then
SAY=1+SAY*2
LEDLER=SAY
DelayMS DUR
GoTo ILERLE
Else
AZALT:
If SAY>=1 Then
SAY=((SAY-1)/2)
LEDLER=SAY
DelayMS DUR
GoTo AZALT
EndIf
EndIf
Return
PROG3:
BUTONDUR3:
If BUTON3=1 Then GoTo BUTONDUR3
If DURUM2=0 Then
LEDLER=%00001111
DURUM2=1
Else
LEDLER=%11110000
DURUM2=0
EndIf
Return
End
7
Not: Programın çalışması ‘tek butonla ledi yak söndür’ ve ‘ karaşimşek’ programlarında
bulunmaktadır.
PROTEUS DEVRESİ:
8
5. 7 SEGMENT DİSPLAYDE BUTONA BASTIKÇA 0-F ARASI SAYDIRAN
PROGRAM
Device=16F628A
Dim BUTON As PORTA.0 ‘PORTA’nın 0. ucunda buton var.
Dim SAY As Byte ‘SAY byte olarak tanımlanan bir değişkendir
Dim SEG7 As PORTB ‘PORTB’de 7 SEGMENT DISPLAY bağlı
PORTB_PULLUPS=1 ‘PORTB’nin dahili pull-upları etkin
TRISA=%00000001 ‘PORTA’nın 1 nolu ucu giriş
TRISB=%00000000 ‘PORTB’nin uçları çıkış ucu olarak tanımlı
CMCON=$07 ‘PORTA’nın girişleri dijital giriş
SAY=0 ‘SAY değişkenini sıfırla
BASLA:
If BUTON=1 Then ‘BUTON’a basıldı mı?
BUTONTEST:
If BUTON=1 Then GoTo BUTONTEST ‘buton basılı kaldığı sürece döngü
oluşturur.
SAY=SAY+1 ‘butona basıldıysa SAY’I bir artır
EndIf
Select SAY ‘SAY’ın içi kaçsa o CASE’e gir
Case 1
SEG7=%11111001 ‘displayde 1 yazar
Case 2
SEG7=%10100100 ‘displayde 2 yazar
Case 3
SEG7=%10110000 ‘displayde 3 yazar
Case 4
SEG7=%10011001 ‘displayde 4 yazar
Case 5
SEG7=%10010010 ‘displayde 5 yazar
Case 6
SEG7=%10000010 ‘displayde 6 yazar
Case 7
9
SEG7=%11111000 ‘displayde 7 yazar
Case 8
SEG7=%10000000 ‘displayde 8 yazar
Case 9
SEG7=%10010000 ‘displayde 9 yazar
Case 10
SEG7=%10001000 ‘displayde A yazar
Case 11
SEG7=%10000011 ‘displayde b yazar
Case 12
SEG7=%11000110 ‘displayde C yazar
Case 13
SEG7=%10100001 ‘displayde d yazar
Case 14
SEG7=%10000110 ‘displayde E yazar
Case 15
SEG7=%10001110 ‘displayde F yazar
Case Else
SEG7=%11000000 ‘hiç biri değilse displayde 0 yazar
SAY=0 ‘SAY’I sıfırla
EndSelect
GoTo BASLA
End
NOT: 7 segment display’ı ortak anotlu kullandığımız için yanmasını istediğimiz ledlere 0 V
veririz. ( Normalde ledlerin ucunda +5V var). Ortak katot için bilgi terslenmelidir.(1 yerine0 )
10
PROTEUS DEVRESİ:
11
6. LCD UYGULAMASI
Device = 16F628A
CMCON=7 ‘PORTA’nın girişleri dijital giriş
Dim BUTON As PORTA.0 ‘PORTA’nın 0. ucunda buton var.
Dim SAY As Byte ‘SAY byte olarak tanımlanan bir değişkendir
SAY=0 ‘SAY değişkenini sıfırla
TRISA=%00000001 ‘PORTA’nın 1 nolu ucu giriş
TRISB=%00000000 ‘PORTB ÇIKIŞ
Declare LCD_DTPIN PORTB.4 ‘DATA girişi PORTB’nin 4. ucundan başlayacak
Declare LCD_ENPIN PORTB.0 ‘LCD’nin ENable ucu
Declare LCD_RSPIN PORTB.1 ‘LCD’nin Register Select ucu
Declare LCD_INTERFACE 4 ‘LCD veri yolu 4 bit olacak
Declare LCD_LINES 2 ‘LCD 2 satırdan oluşuyor
Cls ‘ekranı temizler ve 30 ms gecikme sağlar
Print At 1,1, "ROBOGAZI EKIBI" ‘ekranın 1. satır,1. sütununa yaz
BASLA:
If BUTON=1 Then
BUTONTEST:
If BUTON=1 Then GoTo BUTONTEST
SAY=SAY+1 ‘butona basıldıysa SAY’ı bir artır
EndIf
Select SAY ‘SAY’ın değerine gore CASE’e git
Case 1
Print At 2,1, " KENAN TURAN " ‘ekranda 2.satır,1. sütuna yaz
Case 2
Print At 2,1, " SADIK OZTURK "
Case 3
Print At 2,1, "FUNDA YORULMAZ "
Case 4
Print At 2,1, " HAKAN DOGAN "
12
Case 5
Print At 2,1, "SECIL KARABIYIK"
Case 6
Print At 2,1, " ADNAN KOMU "
Case 7
Print At 2,1, " NESRIN AYDIN "
Case 8
Print At 2,1, " MUSTAFA TEKE "
Case Else ‘ hiç biri değilse kolay gelsin
Print At 2,1, " KOLAY GELSIN " ‘yaz
SAY=0 ‘SAY’I sıfırla
EndSelect
GoTo BASLA
End
PROTEUS DEVRESİ:
13
7. WHİLE-WEND DÖNGÜSÜYLE KARAŞİMŞEK PROGRAMI
Butona basılırsa karaşimşek döngüsünden çıkar
Device=16F84
Dim LEDLER As PORTB ‘PORTB de ledler var
Dim SAY As Byte ‘SAY değişkenini byte olarak ata
Dim DUR As 100 ‘DUR’un içine 100 ms’lik gecikme koy
Dim KOD As Byte ‘KOD değişkenini byte olarak ata
Dim BUTON As PORTA.0 ‘RA0’da buton var
TRISB=0
TRISA=%00000001
BASLA:
While BUTON=0 ‘butona basılana kadar döngüye devam et
ILERLE:
While SAY<=127 ‘SAY 127’den küçük olduğu sürece
SAY=1+SAY*2 ‘SAY’ı iki katını alıp 1 ekle
LEDLER=SAY ‘LEDLER’i SAY’a at
DelayMS DUR ‘100 ms gecik
Wend ‘şart gerçekleşirse döngüyü bitir
AZALT:
While SAY>=1 ‘SAY 1’den büyük eşit olduğu sürece
SAY=((SAY-1)/2) ‘SAY’dan 1 çıkar 2ye böl
LEDLER=SAY ‘LEDLER’i saya at
DelayMS DUR
Wend
PORTB=0
Wend ‘butona basılma döngüsünü bitir
End
14
PROTEUS DEVRESİ:
15
8. TUŞTAKIMINDAN GİRİLEN SÜREYE GÖRE GERİ SAYAN PROGRAM FOR-
NEXT DÖNGÜSÜ
Device = 16F877
XTAL 4 ‘4 MHz lik kristal kullanılacak
Declare LCD_ENPIN PORTD.3 PIN
Declare LCD_RSPIN PORTD.2 PIN
Declare LCD_INTERFACE 4
Declare LCD_LINES 2
Declare LCD_DTPIN PORTD.4
Declare KEYPADPORT PORTB
Dim VAR1 As Byte
Dim SAYI[4] As Byte ‘ SAYI şeklinde tanımlanmış 4’lü dizi
Dim SAYAC As Byte
Dim SURE As Word
Dim SUTUN As Byte
PORTA=0 porta ve portb’yi sıfırla
PORTB=0
ALL_DIGITAL TRUE ‘bütün çıkışlar dijital
PORTB_PULLUPS TRUE ‘portb’nin pull-upları etkin
SURE = ERead 10 ‘EEPROM’un 10 nolu adrsindeki SURE değerini oku
BASLA:
SAYI[0]=0 ‘SAYI dizinin içini sıfırla
SAYI[1]=0
SAYI[2]=0
SAYI[3]=0
SUTUN=0 ‘SUTUN’u sıfırla
Cls
Print At 1,1, "SUREYI GIRINIZ"
DelayMS 500
GoSub TUSTAKIMI ‘tuş takımına dallan
GoSub SUREHESAP ‘sürehesap’a dallan
16
GoTo BASLA ‘baslaya git
TUSTAKIMI:
For SAYAC=3 To 0 Step -1 ‘SAYAC’ı 3’ten 0’a kadar birer azaltarak git
SAYI[SAYAC]=0 ‘SAYAC kaç ise SAYI’daki o dizini sıfırla
TUSBEKLE:
VAR1 = InKey ‘inkey ve lookup için
If VAR1=16 Then GoTo TUSBEKLE ‘ayrıntılı açıklama için 19.
DelayMS 50 ‘sayfaya bakınız
SAYI[SAYAC] = LookUpL VAR1, [1,2,3,255,4,5,6,255,7,8,9,255,"*",0,"#"]
If SAYI[SAYAC] = 42 Then ' *’ a basıldıysa for next dongusunden çık
SAYI[SAYAC] = 0
SAYAC=0 ‘SAYAC 0 ise döngüden çık
GoTo CIK
EndIf
If SAYI[SAYAC]>=10 Then GoTo TUSBEKLE ‘SAYI 10’dan büyükse
‘TUSBEKLEye git
SUTUN=SUTUN+1 ‘SUTUN’un içini bir artır
Print At 2,SUTUN,@SAYI[SAYAC] ‘ekrana SAYI’nın içindeki değeri
DelayMS 100 ‘SUTUN’un bulunduğu konuma yazar
CIK:
Next SAYAC ‘döngüden çık
Return
SUREHESAP:
Select SUTUN ‘SUTUN’un değerine göre CASE’e git
Case 4
SURE=SAYI[3]*1000+SAYI[2]*100+SAYI[1]*10+SAYI[0]
Case 3
SURE=SAYI[3]*100+SAYI[2]*10+SAYI[1]
Case 2
SURE=SAYI[3]*10+SAYI[2]
Case Else
SURE=SAYI[3]
End Select
17
Print At 2,1,"SURE=",@SURE ‘ekranda süreyi göster
EWrite 10,[SURE] ‘SURE’nin içini EEPROM’un 10 nolu
DelayMS 1000 ‘adresine yazar
Return
End
PROTEUS DEVRESİ:
18
9. KEYPAD’DEN GİRİLEN KODA GÖRE BAĞLI OLDUĞU LEDİ YAKAN
PROGRAM
Döngü if-else ile kurulmuştur. If- else döngüsü ile eğer KOD=5 ise KOD=1 mi diye bakar
değilse 2 mi diye bakar bulana kadar devam eder. Sonra döngüyü bitirir. Case –select’e gore
zaman kaybı yaratır.
Device=16F877
Dim KOD As Byte
Dim VAR1 As Byte
Dim DUR As 200
Declare LCD_DTPIN PORTC.4 ‘DATA girişi PORTC’nin 4. ucundan başlayacak
Declare LCD_ENPIN PORTC.3
Declare LCD_RSPIN PORTC.2
Declare LCD_INTERFACE 4
Declare LCD_LINES 4 ‘LCD 4 satırdan oluşuyor
Declare KEYPAD_PORT PORTB ‘KEYPAD’in bağlandığı port
PORTB_PULLUPS = 1 ‘PORTB’nin pull-upları aktif
REMINDERS = OFF
ALL_DIGITAL = True ‘bütün çıkışlar dijital
BASLA:
Print At 1,1, " KOD GIRINIZ: "
DelayMS 100
KODGIR:
PORTD=0 ‘portd’yi sıfırla
PORTE=0 ‘porte’yi sıfırla
KOD=0 ‘kod’u sıfırla
VAR1 = InKey ‘VAR1 değişkenini Inkey’e at
If VAR1=16 Then GoTo KODGIR ‘Keypad’de herhangi bir tuşa basılmadığı
zaman 0’a basılmış gibi algılıyor ve bu VAR1’de 16’ya karşılık geliyor.VAR1=16 olursa
işlem yapmadan KODGIR’e gönderilir.
KOD = LookUp VAR1,[1,2,3,255,4,5,6,255,7,8,9,255,10,0,11] ‘keypad’de basılan
numarayı kod değişkenine at
19
Print At 2,1,@ KOD ‘KOD’u decimal olarak ekranda göster
If KOD = 0 Or KOD > 9 Then GoTo KODGIR ‘eğer 0’a ya da 9’dan büyük bir
DelayMS 100 ‘sayıya basılmışsa(* ya da # gibi) KODGIR etiketine git
If KOD=1 Then ‘KOD=1 ise RD7’deki ledi yak
High PORTD.7
DelayMS DUR
ElseIf KOD=2 Then ‘KOD=2 ise RD6’daki ledi yak
High PORTD.6
DelayMS DUR
ElseIf KOD=3 Then
High PORTD.5
DelayMS DUR
ElseIf KOD=4 Then
High PORTD.4
DelayMS DUR
ElseIf KOD=5 Then
High PORTD.3
DelayMS DUR
ElseIf KOD=6 Then
High PORTD.2
DelayMS DUR
ElseIf KOD=7 Then
High PORTD.1
DelayMS DUR
ElseIf KOD=8 Then
High PORTD.0
DelayMS DUR
ElseIf KOD=9 Then
High PORTE.2
DelayMS DUR
EndIf
GoTo KODGIR
End
20
PROTEUS DEVRESİ:
21
10. KEYPAD’DEN GİRİLEN KODA GORE BAĞLI OLAN LEDİ YAKAN
PROGRAM (CASE-SELECT)
Döngü case-select ile kurulmuştur. Case- select ile KOD=1 ise sadece o şartı uygulayıp
döngüyü bitirir.
Device=16F877
Dim KOD As Byte
Dim VAR1 As Byte
Declare LCD_DTPIN PORTC.4 ‘DATA girişi PORTC’nin 4. ucundan başlayacak
Declare LCD_ENPIN PORTC.3
Declare LCD_RSPIN PORTC.2
Declare LCD_INTERFACE 4
Declare LCD_LINES 4 ‘LCD 4 satırdan oluşuyor
Declare KEYPAD_PORT PORTB ‘KEYPAD’in bağlandığı port
PORTB_PULLUPS = 1 ‘PORTB’nin pull-upları aktif
REMINDERS = OFF
ALL_DIGITAL = True ‘bütün çıkışlar dijital
BASLA:
Print At 1,1, " KOD GIRINIZ: "
DelayMS 100
KODGIR:
PORTD=0
PORTE=0
KOD=0
VAR1 = InKey
If VAR1=16 Then GoTo KODGIR
KOD = LookUp VAR1,[1,2,3,255,4,5,6,255,7,8,9,255,10,0,11]
Print At 2,1,@ KOD
If KOD = 0 Or KOD > 9 Then GoTo KODGIR
DelayMS 100
Select KOD ‘KOD’un içinde ne varsa o case’e gider
Case 1 ‘KOD=1 ise diğerlerine bakmadan RD7’ye bağlı ledi
22
High PORTD.7 ‘yakar ve döngüden çıkar.
Case 2
High PORTD.6
Case 3
High PORTD.5
Case 4
High PORTD.4
Case 5
High PORTD.3
Case 6
High PORTD.2
Case 7
High PORTD.1
Case 8
High PORTD.0
Case 9
High PORTE.2
Case Else ‘hiçbiri değilse bütün ledleri
PORTD=0 ‘söndür.
PORTE=0
EndSelect ‘seçim işlemini bitir.
GoTo BASLA
End
23
PROTEUS DEVRESİ:
24
11. LCD VE KEYPAD UYGULAMASI(BİSKÜVİ-MATİK)
Butonlar ile atılan paraya göre KEYPAD’den girilen koda bakarak para yetiyorsa ürünü veren
ve para üstünü gösteren, yetmiyorsa da eksik para uyarısı yaparak tekrar başa dönen program
Device=16F877
Dim YIRMIBES As PORTA.0 ‘PORTA’ya bağlanan para butonları
Dim ELLI As PORTA.1
Dim BIR As PORTA.2
Dim SON As PORTA.3 ‘paraya basma işlemini sonlandıran buton
TRISC=0 ‘portc çıkış (LCD)
TRISB=1 ‘portb giriş(KEYPAD)
TRISA=%00001111 ‘para butonları
Dim TOPLAM As Float ‘paraların toplamının atıldığı değişken
Dim ATILANPARA As Float ‘atılan paranın son hali
Dim VAR1 As Byte ‘keypad değişkeni
Dim KOD As Byte ‘keypad’den girilen kod
Dim PARAUSTU As Float ‘ürün alındıktan sonra kalan para
Declare LCD_DTPIN PORTC.4 ‘DATA girişi PORTC’nin 4. ucundan başlayacak
Declare LCD_ENPIN PORTC.3
Declare LCD_RSPIN PORTC.2
Declare LCD_INTERFACE 4
Declare LCD_LINES 2 ‘LCD 2 satırdan oluşuyor
Declare KEYPAD_PORT PORTB ‘KEYPAD’in bağlandığı port
PORTB_PULLUPS = 1 ‘PORTB’nin pull-upları aktif
REMINDERS = OFF
ALL_DIGITAL = True ‘bütün çıkışlar dijital
Dim FALIM As Float ‘ürünün tanımlanması(ondalık şeklinde)
Dim HALLEY As Float
Dim RODEO As Float
Dim CIZI As Float
Dim BROWNI As Float
25
Dim COCOSTAR As Float
Dim TUTKU As Float
Dim KOLA As Float
Dim SU As Float
FALIM=0.1 ‘ürünlerin fiyatları(YTL)
HALLEY=0.3
RODEO=0.5
CIZI=0.75
BROWNI=0.6
COCOSTAR=0.5
TUTKU=1.25
KOLA=1.5
SU=0.4
Cls ‘ekranı temizler ve 30 ms gecikme sağlar
BASLA:
KOD=0 ‘KEYPAD’in önceki kodunu sıfırlar
Print At 1,1, " MERHABA " ‘ekranın 1. satırına merhaba yaz
DelayMS 50 ‘50 ms gecik
Print At 2,1, "*HOS GELDINIZ*" ‘ekranın 2. satırına yaz
DelayMS 10
PARA:
TOPLAM=0 ‘toplamın içini sıfırlar
While SON=0 ‘Son butonuna basılmadıkça döngüye devam et
If YIRMIBES=1 Then ’25 butonuna basılırsa
BEKLE1: ‘BUTON’a bir kere basılmasını saglar
If YIRMIBES=1 Then GoTo BEKLE1
TOPLAM=TOPLAM+0.25 ‘toplam değişkenine 0.25 ekle
ElseIf ELLI=1 Then ‘50’ye basılırsa
BEKLE2:
If ELLI=1 Then GoTo BEKLE2
TOPLAM=TOPLAM+0.50 ‘toplam değişkenine 0.5 ekle
ElseIf BIR=1 Then ‘BIR’e basılırsa
26
BEKLE3:
If BIR=1 Then GoTo BEKLE3
TOPLAM=TOPLAM+1 ‘toplam değişkenine 1 ekle
EndIf
Wend ‘while döngüsünü bitir
ATILANPARA=TOPLAM ‘toplam değişkenini içini atılanparaya at
ATLNPR:
Print $FE , 1 ‘ekranı temizle
Print At 1,1, " ATILANPARA: " ‘ekranda atılan para yaz
Print At 2,1,@ ATILANPARA ‘decimal olarak atılan paranın içini
DelayMS 500 ‘ekrana yazdır
KODGIR:
Print $FE , 1
Print At 1,1, " KODUNU GIRINIZ: "
DelayMS 200
VAR1 = InKey ‘VAR1 değişkenini Inkey’e at
KOD = LookUp VAR1,[1,2,3,255,4,5,6,255,7,8,9,255,10,0,11] ‘keypad’de basılan
‘numarayı kod değişkenine at
Print At 2,1,@ KOD ‘KOD’u decimal olarak ekranda göster
If KOD = 0 Or KOD > 9 Then GoTo KODGIR ‘eğer 0’a ya da 9’dan büyük bir
DelayMS 1000 ‘sayıya basılmışsa(* ya da # gibi) KODGIR etiketine git
If KOD=1 Then GoSub FALIMSUB ‘eğer KOD=1 ise FALIMSUB etiketine dallan
If KOD=2 Then GoSub HALLEYSUB
If KOD=3 Then GoSub RODEOSUB
If KOD=4 Then GoSub CIZISUB
If KOD=5 Then GoSub BROWNISUB
If KOD=6 Then GoSub COCOSTARSUB
If KOD=7 Then GoSub TUTKUSUB
27
If KOD=8 Then GoSub KOLASUB
If KOD=9 Then GoSub SUSUB
GoTo BASLA ‘BASLA’ya dön
FALIMSUB: '1 - 0.1
Print At 1,1, " FALIM SECTINIZ! "
DelayMS 200
If TOPLAM<FALIM Then ‘TOPLAM para falım’dan azsa
Print At 2,1, "EKSIK PARA" ‘ekrana eksik para yazdır
DelayMS 500
Else ‘değilse
GoSub ONAY ‘ONAY etiketine dalan
PARAUSTU=TOPLAM-FALIM ‘TOPLAM’dan FALIM’ı çıkar PARAUSTU’ne
at
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU ‘ekranda paraustu’nun içini
DelayMS 500 ‘göster
EndIf
Return ‘ alt programdan geri dön
HALLEYSUB: '2-0.3
Print At 1,1, " HALLEY SECTINIZ! "
DelayMS 200
If TOPLAM<HALLEY Then
Print At 2,1, "EKSIK PARA"
DelayMS 500
Else
GoSub ONAY
PARAUSTU=TOPLAM-HALLEY
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU
DelayMS 500
EndIf
Return
RODEOSUB: '3 -0,5
Print At 1,1, " RODEO SECTINIZ! "
DelayMS 200
28
If TOPLAM<RODEO Then
Print At 2,1, "EKSIK PARA"
DelayMS 500
Else
GoSub ONAY
PARAUSTU=TOPLAM-RODEO
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU
DelayMS 500
EndIf
Return
CIZISUB: '4 -0,75
Print At 1,1, " CIZI SECTINIZ! "
DelayMS 200
If TOPLAM<CIZI Then
Print At 2,1, "EKSIK PARA"
DelayMS 500
Else
GoSub ONAY
PARAUSTU=TOPLAM-CIZI
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU
DelayMS 500
EndIf
Return
BROWNISUB: '5-0,6
Print At 1,1, " BROWNI SECTINIZ! "
DelayMS 200
If TOPLAM<BROWNI Then
Print At 2,1, "EKSIK PARA"
DelayMS 500
Else
GoSub ONAY
PARAUSTU=TOPLAM-BROWNI
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU
DelayMS 500
29
EndIf
Return
COCOSTARSUB: '6-0,5
Print At 1,1, " COCOSTAR SECTINIZ! "
DelayMS 200
If TOPLAM<COCOSTAR Then
Print At 2,1, "EKSIK PARA"
DelayMS 500
Else
GoSub ONAY
PARAUSTU=TOPLAM-COCOSTAR
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU
DelayMS 500
EndIf
Return
TUTKUSUB: '7-1,25
Print At 1,1, " TUTKU SECTINIZ! "
DelayMS 200
If TOPLAM<TUTKU Then
Print At 2,1, "EKSIK PARA"
DelayMS 500
Else
GoSub ONAY
PARAUSTU=TOPLAM-TUTKU
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU
DelayMS 500
EndIf
Return
KOLASUB: '8-1,5
Print At 1,1, " KOLA SECTINIZ! "
DelayMS 200
If TOPLAM<KOLA Then
Print At 2,1, "EKSIK PARA"
DelayMS 500
30
Else
GoSub ONAY
PARAUSTU=TOPLAM-KOLA
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU
DelayMS 500
EndIf
Return
SUSUB: '9 -0,4
Print At 1,1, " SU SECTINIZ! "
DelayMS 200
If TOPLAM<SU Then
Print At 2,1, "EKSIK PARA"
DelayMS 500
Else
GoSub ONAY
PARAUSTU=TOPLAM-SU
Print At 1,1,"PARAUSTUNUZ=", @ PARAUSTU
DelayMS 500
EndIf
Return
ONAY: ‘yazılan kod doğruysa onayla
Print At 2,1, "KOD DOGRUYSA:* " ‘onaylamak için *’a bas
DelayMS 200
Print $FE , 1
Print At 1,1, " ONAYLA: "
DelayMS 200
VAR1 = InKey
KOD = LookUp VAR1,[1,2,3,255,4,5,6,255,7,8,9,255,10,0,11]
If KOD=10 Then ‘KOD olarak 10’a yani *’a basıldıysa
Print At 2,1," * " ‘ekranda * göster
DelayMS 1000
Print $FE, 1
31
Print At 1,1, "AFIYET OLSUN"
DelayMS 200
Else ‘ *’a basana kadar ONAY’ a git
GoTo ONAY
EndIf
Return
GoTo BASLA
End
PROTEUS DEVRESİ:
32
12. RB0 İNTERRUPTININ KULLANIMI
RB0 portu harici kesme girişi olarak kullanılıyor. Böylece programın herhangi bir anında PIC
yapmakta olduğu işleri durdurup kesme rutinini işletir.
Device=16F628A
Dim BUTON As PORTB.0
Dim LED As PORTB.7
Symbol GIE = INTCON.7 ‘Tüm kesme işlemlerine izin verme biti INTCON
‘saklayıcısının 7. biti
Symbol INTE = INTCON.4 ‘RB0/INT ucundan gelen kesmeye izin verme biti
‘INTCON saklayıcısının 4. biti
Symbol INTF = INTCON.1 ‘RB0/INT harici kesme bayrağı INTCON
‘saklayıcısının 1. biti
CMCON=$07 ‘bütün portlar dijital
TRISB=%00000001
PORTB=0
On Interrupt GoTo INT ‘interrupt durumunda INT etiketine git
GIE=1 ‘Tüm kesme işlemlerine izin ver
INTE=1 ‘RB0/INT ucundan gelen kesmeye izin ver
High LED ‘LED’i yak
BASLA: DelayMS 50 ‘ana programda bekleme dışında hiçbir komut GoTo BASLA ‘yok işlem yapılmıyor
Disable ‘kesmelere izin verme
INT:
GIE=0 ‘diğer kesme işlemlerine izin verme
INTE=0 ‘RB0/INT ucundan gelen kesmeyi sıfırla
INTF=0 ‘RB0/INT harici kesme bayrağını sıfırla
Toggle LED ‘INTERRUPT GELDİĞİNDE LED’İ tersle
INTE=1 ‘RB0/INT ucundan gelen kesmeye izin ver
GIE=1 ‘diğer tüm kesme işlemlerine izin ver
Resume ‘ana programa dön
Enable ‘diğer interruptlara izin ver
End
33
PROTEUS DEVRESİ:
34
13. RB4-RB7 DEĞİŞİM INTERRUPTININ KULLANIMI
RB4 ile RB7 portu harici kesme girişi olarak kullanılıyor. Böylece 0 ile 15 arasında sayan ve
porta çıkışlarındaki ledleri yakan programın herhangi bir anında RB4-RB7 pinlerinde bir
değişim olursa PIC yapmakta olduğu işleri durdurup kesme rutinini işletir.
Device = 16F84A
TRISB = %11110000
TRISA = %00000000
Dim SAYI As Byte
Dim DURUM As Byte
PORTA=0
PORTB=0
On Interrupt GoTo INTGELDI ‘INT geldiğinde INTGELDI’ye git
INTCON =%10001000 ‘INTCON kaydedicisinde tüm kesmelere izin verme
ve PORTB’deki değişikliklerde kesme oluşturmaya
izin verme bitleri aktif
BASLA:
For SAYI=1 To 15 Step 1 ‘SAYI’yı 1’den 15’e kadar 1’er artırarak
PORTA= SAYI ‘SAYI’NIN içini PORTB’ye aktar
DelayMS 500
Next SAYI ‘döngüyü kapat
GoTo BASLA
Disable ‘INT’lara izin verme
INTGELDI:
INTCON.0=0 ’PORTB0 INTERRUPT (RBIF)bayrağını sıfırla
DURUM = PORTB & %11110000 ‘PORTB’yi F0’la çarp DURUM’a yaz
PORTB = DURUM >> 4 ‘DURUM’u 4 kez saga kaydır
DelayMS 1
Enable ‘diğer kesmeleri aktif et
Resume ‘ınt’dan dön
End
35
PROTEUS DEVRESİ:
36
14. TIMER1 INTERRUPTININ KULLANIMI
Belirli zaman aralıklarıyla işlem yaptırmak için kullanılır. Zaman geldiğinde işler durdurulup
belirlenen zamanlanmış görev çalıştırılır.
Device = 16F877A
TRISC = %00000000
TRISD = %00000000
Dim SAYI As Byte
Dim DURUM As Byte
PORTC=0
PORTD=0
DURUM=255 ‘DURUM’un içine 255 değerini at
On Interrupt GoTo INTEGIT ‘INT geldiğinde INTEGIT’e git
INTCON =%11000000 ‘diğer tüm kesmelere ve çevresel (PEIE)
‘birimlerden gelen kesmelere izin ver
PIE1 = %00000001 ‘TIMER1 kesmesini aktif et(TMR1IE)
T1CON = %00110001 ‘TIMER1 aktif ve prescaler oranı 8
TMR1H = $3F ' TMR1 $3FFF KADAR SAYIP INTERRUPT A GİRER
TMR1L = $FF ' TMR1 16383’e KADAR SAYIP INTERRUPT A GİRER
BASLA:
For SAYI=1 To 255 Step 1 ‘SAYI’yı 1’den 255’e kadar artır
PORTC= SAYI ‘SAYI’nın durumunu PORTC’de göster
DelayMS 500
Next SAYI ‘döngüyü bitir
GoTo BASLA
INTEGIT:
Disable ‘INT’lara izin verme
INTCON.7=0 ‘diğer tüm interruptlara izin verme
37
PIR1.0=0 ‘TIMER1 taşma bayrağını sıfırla
DURUM = DURUM-1 ‘DURUM’U bir azalt
PORTD = DURUM ‘DURUM’u PORTB’de göster
INTCON.7=1 ‘diğer kesmelere izin ver
Enable ‘INT’lara izin ver
Resume ‘INT’dan dön
End
PROTEUS DEVRESİ:
38
15. PWM’İN KULLANIMI
Device = 16F877
XTAL = 20 ’20 MHz’lik osc
CCP1_PIN = PORTC.1 ‘16F877’nin CCP pini PORTC’nin 2. ucunda
HPWM 1,127,1000 ‘1 KHz’lik PWM sinyalinin yarısı kadar(%50) duty cycle
‘gönderilir
BASLA:
DelayMS 500
GoTo BASLA
End
PROTEUS DEVRESİ:
39