Transcript 4. Hafta

PROGRAMLAMA
VE ASSEMBLY
DİLİ
4.Hafta
Mikrodenetleyiciler
1
Sembol Tanımlamaları :
f - Register File Adress: kayıtçı adı veya adresi (0x00 ile 0x7F)
w - Akümülatör, çalışma kayıtçısı
b - Bit tanımlayıcısı; 8 bitlik kayıtçının 0~7 arasındaki bir biti veya etiket. (EQU komutu ile adresi tanımlanmış olması gerekir)
d - Destination : Gönderilecek yer; komutun çalıştırılmasından sonra sonucun nereye yazılacağını belirler.
d = 0 - W kayıtçısına, d = 1 - dosya kayıtçısına
k - Sabit bir sayı (0x0C veya 0CH, 00001100B, 10D) veya adres etiketi
x - “0” yada “1” önemli değil
TO - Zaman aşımı biti (Time-out bit)
PD - Güç kesimi biti (Power-down)
Mikrodenetleyiciler
2
Sembol Tanımlamaları :
f - Register File Adress: kayıtçı adı veya adresi (0x00 ile 0x7F)
w - Akümülatör, çalışma kayıtçısı
b - Bit tanımlayıcısı; 8 bitlik kayıtçının 0~7 arasındaki bir biti veya etiket. (EQU komutu ile adresi tanımlanmış olması gerekir)
d - Destination : Gönderilecek yer; komutun çalıştırılmasından sonra sonucun nereye yazılacağını belirler.
d = 0 - W kayıtçısına, d = 1 - dosya kayıtçısına
k - Sabit bir sayı (0x0C veya 0CH, 00001100B, 10D) veya adres etiketi
x - “0” yada “1” önemli değil
TO - Zaman aşımı biti (Time-out bit)
PD - Güç kesimi biti (Power-down)
Mikrodenetleyiciler
3
Örnek: 20h tan başlayan 0x25h ta biten bir tablodaki sıfırları sayan program.
list
p=pic16f877a
#include<p16f877a.inc>
tbasi
equ
0x20
tsonu
equ
0x25
sayac equ
0x30
org
0x000
goto
basla
basla:
clrf
sayac
movlw tbasi
movwf FSR
geri:
movf
INDF,w
btfsc
STATUS,Z
incf
sayac,f
incf
FSR,f
movlw tsonu
subwf FSR,w
btfss
STATUS,Z
goto
geri
end
Mikrodenetleyiciler
4
Örnek: 20h tan başlayan 0x25h ta biten bir tablodaki sıfırları sayan program. (Tablo
verileri program ile yüklenir)
list
p=pic16f877a
#include<p16f877a.inc>
tbasi
equ
0x20
tsonu
equ
0x25
sayac equ
0x30
org
0x000
goto
basla
basla:
clrf
sayac
call
tdoldur
movlw tbasi
movwf FSR
geri:
movf
INDF,w
btfsc
STATUS,Z
incf
sayac,f
incf
FSR,f
movlw tsonu
subwf FSR,w
btfss
STATUS,Z
goto
geri
Mikrodenetleyiciler
goto
son
tdoldur:
movlw
movwf
movlw
movwf
movlw
movwf
movlw
movwf
movlw
movwf
movlw
movwf
0x3f
tbasi
0x00
tbasi+1
0x5b
tbasi+2
0x00
tbasi+3
0x66
tbasi+4
0x00
tbasi+5
return
son:
end
5
ÖDEV1: 0x20h tan başlayan 0x25h ta biten bir tablodaki
sayıları toplayıp sonucu 0x2A ya program
(Tablo verileri sırasıyla; 0x02, 0x0A, 0x05, 0x0C, 0x08,
0x0E )
ÖDEV2: 16 bitlik A sayısının düşük anlamlı 8 biti 0x20h
adresinde, yüksek anlamlı bitleri 0x21h adresindedir.
Aynı şekilde B sayısı için düşük bitler 0x22h ve yüksek
bitler 0x23h ta bulunmaktadır. İki 16 bitlik sayıyı toplayan
sonucun düşük bitlerini 0x25h yüksek bitlerini 0x26h a
yazan program.(Test değerleri: A=0x650F, B=0x30B2,
A=0x25C8, B=0xA0DE)
(Olası elde durumlarını göz önünde bulundurunuz. )
Mikrodenetleyiciler
6
ÖDEV1: 0x20h tan başlayan 0x25h ta biten bir tablodaki sayıları toplayıp sonucu 0x2A ya program
list
p=pic16f877a
#include<p16f877a.inc>
tbasi
equ
0x20
tsonu
equ
0x26
toplam
equ
0x2A
org
0x000
goto
basla
basla:
clrf
toplam
; toplam=0
call
tdoldur
movlw
tbasi
movwf
FSR
geri:
movf
toplam,w
;w <- toplam
addwf INDF,w
;toplam (w) <- toplam (w) + indf
movwf
toplam
; w tasi toplam
incf
FSR,f
; FSR i 1 arttir
movlw
tsonu
; tablo sonunu yukle
subwf
FSR,w
; o anki FSR dan cikar
btfss
STATUS,Z ; tablo sonuna gelindiyse w
sifir olur 1 komut atlanir
goto
geri
goto
son
Mikrodenetleyiciler
tdoldur:
movlw
movwf
movlw
movwf
movlw
movwf
movlw
movwf
movlw
movwf
movlw
movwf
0x02
tbasi
0x0A
tbasi+1
0x05
tbasi+2
0x0C
tbasi+3
0x08
tbasi+4
0x0E
tbasi+5
return
son:
end
7
ÖDEV2: 16 bitlik A sayısının düşük anlamlı 8 biti 0x20h adresinde, yüksek anlamlı
bitleri 0x21h adresindedir. Aynı şekilde B sayısı için düşük bitler 0x22h ve yüksek bitler
0x23h ta bulunmaktadır. İki 16 bitlik sayıyı toplayan sonucun düşük bitlerini 0x25h
yüksek bitlerini 0x26h a yazan program.(Test değerleri: A=0x650F, B=0x30B2,
A=0x25C8, B=0xA0DE)
(Olası elde durumlarını göz önünde bulundurunuz. )
list p=pic16f877a
#include<p16f877a.inc>
elde equ 0x28
org
0x000
goto basla
basla:
clrf
elde
movf 0x20,w
addwf 0x22,w
btfsc STATUS,C
incf
elde,f
movwf 0x25
movf 0x21,w
addwf 0x23,w
addwf elde,w
movwf 0x26
end
Mikrodenetleyiciler
; elde yi sifirla
; A nin dusuk anlamli bitleri
; w <- w + B nin dusuk anlamli bitleri
; Elde olusmadiysa 1 komut atla
; Elde varsa eldeyi artir
; Sonuc un dusuk anlamli bitleri
; A nin yuksek anlamli bitleri
; w <- w + B nin yuksek anlamli bitleri
; w <- w + Elde
; Sonuc un yuksek anlamli bitleri
8
Döngü Oluşturma
Program yazarken bazı işlemlerin belirli sayıda tekrarlanması gerekebilir.
Bu durumda kayıtçılardan biri sayaç olarak kullanılır. Daha sonra her
işlem tekrarlandığında sayaç değeri bir azaltılır. Azaltma işlemini DECFSZ
komutu ile yapılır.
Bazı işlerin belirli sayılarda tekrarlanması istenebilir. Bu durumda da bir
kayıtçı sayaç olarak kullanılır ve sayacın değeri her defasında 1 arttırılır.
Arttırma işlemi INCF komutu ile yapılır. Sayaç belirlene değer ulaştığı
zaman program akışı başka komuta geçer.
Zaman Gecikmesi ve Alt Programlar
Bazı işlemlerin yapılması sırasında belirli bir zaman hiçbir şey yapmadan
beklenmesi gerekir. Zaman geciktirme işlemlerini yazılım döngülerini kullanarak
yapabildiğimiz gibi, donanımın bize sunduğu özel geciktirmeler yapabiliriz. Biz zaman
geciktirme döngüsünde, gecikme zamanını tespit etmek için komutların çevrim süreleri
dikkate alınır. RC osilatör kullanılan PIC devrelerinde bir komutun çevrim süresini hassas
olarak hesaplamak kolay değildir. Ancak kristal veya seramik osilatör kullanılan
devrelerde hassas gecikme döngüleri yapabiliriz.
PIC‟in geciktirilmesi için ilk başta kullanıcılar NOP komutlarını kullanmayı tercih
edebilirler. Örneğin:
NOP komutu ile 0,1 milisaniyelik bir gecikme yaratmak için ne kadar NOP komutu
gerekir. Kristal Osilatör=20 Mhz)
PIC16F877 için Bir komutun çevrim süresi = 4×0.05µsn = 0.2 µsn (1/20.000.000)
Aynı gecikme için NOP komut sayısı ise (0.1×103)/(0.2) = 500 adettir.
Bu sayıda NOP komutunun ardarda yazılması belleğin gereksiz biçimde dolmasına yol
açar. Bu yöntem iyi bir programlama tekniği olarak da önerilmez. Bunun yerine daha
az sayıda komut kullanarak, istenilen gecikmeyi sağlayabiliriz.
Gecikme programında iç içe iki döngü kullanılmıştır. Her iki döngü kullanıldığında oluşan
toplam komut çevrim sürelerini hesaplarsak;
KOMUTLAR
KOMUT ÇEVRİM SÜRESİ
Gecikme:
movlw
0xFF
1
movwf SAYAC1 ;d‟255‟=M
1
Dongu11:
movlw
0xFF
1xM
movwf SAYAC2 ; d‟255‟=N
1xM
Dongu12:
decfsz
SAYAC2,F
1xMxN
goto
Dongu12
2xMxN
decfsz
SAYAC1,F
1xM
goto
Dongu11
2xM
return
2
M ve N yerine 255 yerleştirilirse;
Toplam 196.608 çevrim süresi (3xMxN+5xM+4)
196.608 x (0.05 x 4)µsn = 39.321 µsn ≡39 msn
Gecikme sürelerini sayaçlara yüklediğimiz M ve N sabitlerini değiştirerek ayarlamak
mümkündür. Örneğin gecikme süresinin 10 ms olması için dış ve iç döngü
sayaçlarının değerlerinin ne olması gerektiğini bulalım:
10.000/(0.05 x 4) = 3xNxN
N=129
bu değer h‟81‟ değerine karşılık gelir. Böylece 10 ms gecikme elde edilir.
Giriş-Çıkış Portları Kullanımı
TRISX : 0 Çıkış ; 1 Giriş
Örn: TRISB=b’11110000 = 0xF0 (Üst 4 bit giriş, Alt 4 bit çıkış)
PORTX= data; Veri gönderme
data= PORTX; Veri alma
16F877 Minimum Konfigurasyon
Mikrodenetleyiciler
14
Örnek: PortB de butonlar bağlıdır, PortC de LED ler. PortB deki bilgiyi PortC ye
gönderen programı yazınız. (RBPU aktif edilmeli)
list
p=pic16f877a
#include<p16f877a.inc>
org
0x000
goto
basla
basla:
;port B ve C için yönlendiricileri ayarla
bsf
STATUS,RP0 ; Bank 1
clrf
TRISC ; PortC çıkış
bcf
OPTION_REG,RBPU ;Pull-up aktif
movlw 0xFF
movwf TRISB ; PortB giriş
bcf
STATUS,RP0 ; Tekrar bank 0
geri:
movf
PORTB,w
; PortB oku
nop
nop
movwf PORTC
;PORTC ye yaz
nop
goto
geri
end
Mikrodenetleyiciler
15
Örnek: PortB de düşük 4 bitine butonlar bağlıdır, yüksek anlamlı bitlerine de
LED ler. PortB ilk 4 bitindeki bilgiyi, yüksek bitlerine gönderen programı yazınız.
list
p=pic16f877a
#include<p16f877a.inc>
org
0x000
goto
basla
temp
equ
0x20
basla:
;port B için yönlendiricileri ayarla
bsf
STATUS,RP0 ; Bank 1
movlw 0x0F
; ust 4 cikis, alt 4 giris
movwf TRISB ; PortB ayarla
bcf
STATUS,RP0 ; Tekrar bank 0
geri:
swapf PORTB,w
andlw 0xF0;
movwf temp
movf
PORTB,w
andlw 0x0F;
addwf temp,w
movwf PORTB
goto
geri
end
Mikrodenetleyiciler
16
Örnek: PortB.0 da buton bağlıdır, PortC.0 da LED. Butona basıldığında LED in
durumunu tersleyen programı yazın. (Buton basıldıktan sonra gecikme programı ile
yeniden basılması geciktirilecek)
list
p=pic16f877a
#include<p16f877a.inc>
sayac1 equ 0x20
sayac2 equ 0x21
org
0x000
goto
basla
basla:
;port B ve C için yönlendiricileri ayarla
bsf
STATUS,RP0 ; Bank 1
clrf
TRISC ; PortC çıkış
bcf
OPTION_REG,RBPU ;Pull-up aktif
movlw 0xFF
movwf TRISB ; PortB giriş
bcf
STATUS,RP0 ; Tekrar bank 0
clrf PORTC
geri:
btfsc
PORTB,0
; PortB.0 basili degil ise 1 dir alt komut calisir
goto
geri
; basili degilse git geri
call
led_tersle
;Led konum degistirir
call
gecikme
;yeni tus basimi icin beklenir
goto
geri
Mikrodenetleyiciler
17
gecikme:
movlw
movwf
dongu11:
movlw
movwf
dongu12:
decfsz
goto
decfsz
goto
return
led_tersle:
comf
return
end
0xFF
sayac1 ;d’255’=M
0xFF
sayac2 ; d’255’=N
sayac2,f
dongu12
sayac1,f
dongu11
PORTC,f
Mikrodenetleyiciler
;portc durumunu tersle f e tasi
18
Örnek: PortC ye bağlı LED ler baştan sona kadar teker teker yanıp sönen sonra geriye doğru
devam eden devre tasarlanacaktır. LED geçişlerinin görülebilmesi için gecikme yazılımı
yapılmalıdır. (Karaşimşek devresi)
;====karaşimşek.asm======
list
p=pic16f877a
#include<p16f877a.inc>
sayac1 equ 0x20
sayac2 equ 0x21
org
0x000
goto
basla
basla:
clrf
PORTB
bsf
STATUS,RP0
clrf
TRISC
bcf
STATUS,RP0
bcf
STATUS,C
movlw
0x01
movwf
PORTC
sol:
call
gecikme
rlf
PORTC,f
btfss
PORTC,7
goto
sol
sag:
call
gecikme
bekle.
rrf
PORTC,f
btfss
PORTC,0
goto
sag
goto
sol
Mikrodenetleyiciler
;bank1
;PORTC cikis
;bank0
;Elde biti sıfırlandı.
;ilk değeri yükle ve
;C portuna gonder
gecikme:
movlw
movwf
dongu11:
movlw
movwf
dongu12:
decfsz
goto
decfsz
goto
return
end
0xFF
sayac1 ;d'255'=M
0xFF
sayac2 ; d'255'=N
sayac2,f
dongu12
sayac1,f
dongu11
;Yeni değer için bekle.
;sola kaydır
;PORTC<7>=1 mi?
;hayır.SOL’a dallan.
;evet. Yeni değer için
; sağa kaydır.
; PORTC<0>=1 mi?
;hayır.SAG’a dallan.
;evet.SOL’a dallan,
19
Örnek: B portundaki değerin 0x4C olup olmadığını test etmek için gereken
program parçasını yazınız.
…….
…….
movlw
test_portb:
xorwf
btfss
goto
0x4C
;W= 0x4C
PORTB,f
STATUS,Z
test_portb
;PORTB=(PORTB XOR W)
; STATUS<2>=1 mi? (Z=1 mi?)
; hayır.Tekrar test et.
; evet. Sonraki komutlar…
…….
…….
…….
XORLW ve XORWF komutlarıyla sadece verilerin eşit olup olmadığı testini
yapabiliriz.
Bu işlem için istenirse SUBLW ve SUBWF komutları da kullanılabilir. Ayrıca bu iki
komutla , büyük / küçük mü? Testleri de yapılabilir.
Mikrodenetleyiciler
20
Çalışma Soruları
Soru1: 4 bitlik iki sayıyı çarpan sonucu belirleyeceğiniz bir RAM
bölgesine yazan programı yazınız.
Soru2: 16 bitlik A sayısınından düşük anlamlı 8 biti AL 0x20h
adresinde, yüksek anlamlı bitleri AH 0x21h adresindedir. Aynı şekilde
B sayısı için düşük bitler BL, 0x22h ve yüksek bitler BH, 0x23h ta
bulunmaktadır. İki 16 bitlik sayıyı çıkaran sonucun düşük bitlerini CL,
0x25h yüksek bitlerini CH, 0x26h a, işaret bitini SIGN, 0x27 e yazan
program.
(A-B=C)(Test değerleri: A=0x650F, B=0x30B2, A=0x25C8,
B=0xA0DE)
Soru3: PortC nin ilk 4 bitinde LED bağlıdır. 0’dan F’e kadar
hexadecimal sayan çıkıştaki LED leri buna göre yakan programı
yazınız.
Mikrodenetleyiciler
21