-

PIC 16F877A DA YANAN LEDİN SAĞA SOLA HARAKET ETMESİ-RLF RRF KULLANIMI

Pic 16f877a da ledin yanması demek  kullanılan  potrun ilgili  bitinin “1″ olması demektir.Yanan bir  ledin sağa sola hareket etmesini sağlayan özel komutlar  vardır:

rlf :   Açılımı “rotate left file”,içeriği sola kaydırmaya yarar.Örneğin portun içinde b’01000000′  ise  rlf komutu bir kere uygulandığında b’10000000′   şeklinde olur.

rrf:   Açılımı “rotate right  file”,içeriği sağa kaydırmaya yarar.Örneğin portun içinde b’01000000′  ise  rrf komutu bir kere uygulandığında b’00100000′   şeklinde olur. 


           portun içeriğini sağa  sonra sola kaydıran örnek kodu inceleyelim:
Bu kodda    PORTB nin içine en başta b’00000001′  sayısı  yerleştiriliyor,içerik 7. bit 1 olana kadar her defasında  bir bit sola kaydırılıyor, çünkü 7. bit  1 olduğunda sola kayacak yer klamıyor,bu kontrolden sonra  sağa kaymalar başlayacaktır.Bu aşamada da içerik0. bit 1 olana kadar  her defasında bir bit olmak üzere sağa kaydırılıyor ,0. bit  1 olduğunda yine sola kayma olacaktır.
SAYAC1 EQU h’0C’   ;gecikme sayacları için adresler belirtiliyor

SAYAC2 EQU h’0D’

CLRF PORTB      ;potrbnin içi en başta temizleniyor
BSF STATUS,5             ;bank1 tris registerlarının ayarlanması için seçildi

CLRF TRISB             ;portb çıkış portu yapıldı

BCF STATUS,5                  ;port içeriği ile ilgili işlem yapılması için tekrar bank0 a geçildi
MOVLW h’01’
MOVWF PORTB            ;portb nin içine b’00000001′  sayısı atıldı
SOL:

CALL GECIKME;en başta bi bekleme anı oluyor

RLF PORTB,F               ;içerik 1 birim sola kaydı

BTFSS PORTB,7            ;portbnnin 7. biti kontrol ediliyor,
1 ise sağa kaydırma başlayacak 1 değilse tekrar  sola kayma olacaktır

GOTO SOL

SAG:

CALL GECIKME                    ;bekleme yapılıyor

RRF PORTB,F                     ;içerik 1 birim sağa kaydırılıyor

BTFSS PORTB,0                  ;portbnin 0. biti kontrol ediliyor 1 ise sola kaymaya geçilecek,0 ise sağa ;kaymaya devam

GOTO SAG

GOTO SOL

GECIKME:

MOVLW h’FF’

MOVWF SAYAC1           ;gecikme için sayac1 in içine h’FF’  sayısı atılıyor

DONGU1:

MOVLW h’FF’

MOVWF SAYAC2                 ;gecikme için sayac1 in içine h’FF’  sayısı atılıyor

DONGU2:

DECFSZ SAYAC2,F

GOTO DONGU2           ;sayac2 nin içindeki sayı 0 olana  kadar her defasında 1 azalt,0 olunca saya1 i      ;                                       ;azaltmaya git

DECFSZ SAYAC1,F        ;sayac1in içi 0 olana kadar her defasında 1 azalt,0 olduğunda return yap

GOTO DONGU1

RETURN            ;en son callın yapıldığı adrese  gider

END        ;programo bitir

   

DERYA GÜNDÜZ

PIC 16F877A DA YANAN LEDİN SAĞA SOLA HARAKET ETMESİ-RLF RRF KULLANIMI

Pic 16f877a da ledin yanması demek  kullanılan  potrun ilgili  bitinin “1″ olması demektir.Yanan bir  ledin sağa sola hareket etmesini sağlayan özel komutlar  vardır:

rlf :   Açılımı “rotate left file”,içeriği sola kaydırmaya yarar.Örneğin portun içinde b’01000000′  ise  rlf komutu bir kere uygulandığında b’10000000′   şeklinde olur.

rrf:   Açılımı “rotate right  file”,içeriği sağa kaydırmaya yarar.Örneğin portun içinde b’01000000′  ise  rrf komutu bir kere uygulandığında b’00100000′   şeklinde olur. 


           portun içeriğini sağa  sonra sola kaydıran örnek kodu inceleyelim:
Bu kodda    PORTB nin içine en başta b’00000001′  sayısı  yerleştiriliyor,içerik 7. bit 1 olana kadar her defasında  bir bit sola kaydırılıyor, çünkü 7. bit  1 olduğunda sola kayacak yer klamıyor,bu kontrolden sonra  sağa kaymalar başlayacaktır.Bu aşamada da içerik0. bit 1 olana kadar  her defasında bir bit olmak üzere sağa kaydırılıyor ,0. bit  1 olduğunda yine sola kayma olacaktır.
SAYAC1 EQU h’0C’
SAYAC2 EQU h’0D’

CLRF PORTB      ;potrbnin içi en başta temizleniyor
BSF STATUS,5             ;bank1 tris registerlarının ayarlanması için seçildi

CLRF TRISB             ;portb çıkış portu yapıldı

BCF STATUS,5                  ;port içeriği ile ilgili işlem yapılması için tekrar bank0 a geçildi
MOVLW h’01’
MOVWF PORTB            ;portb nin içine b’00000001′  sayısı atıldı
SOL:

CALL GECIKME;en başta bi bekleme anı oluyor
RLF PORTB,F               ;içerik 1 birim sola kaydı
BTFSS PORTB,7            ;portbnnin 7. biti kontrol ediliyor,1 ise sağa kaydırma başlayacak 1 değilse tekrar                                                                                                          ;sola kayma

GOTO SOL

SAG:

CALL GECIKME                    ;bekleme yapılıyor
RRF PORTB,F                     ;içerik 1 birim sağa kaydırılıyor
BTFSS PORTB,0                  ;portbnin 0. biti kontrol ediliyor 1 ise sola kaymaya geçilecek,0 ise sağa ;kaymaya devam

GOTO SAG
GOTO SOL

GECIKME:

MOVLW h’FF’
MOVWF SAYAC1           ;gecikme için sayac1 in içine h’FF’  sayısı atılıyor

DONGU1:

MOVLW h’FF’
MOVWF SAYAC2                 ;gecikme için sayac1 in içine h’FF’  sayısı atılıyor

DONGU2:

DECFSZ SAYAC2,F
GOTO DONGU2           ;sayac2 nin içindeki sayı 0 olana  kadar her defasında 1 azalt,0 olunca saya1 i      ;                                       ;azaltmaya git

DECFSZ SAYAC1,F        ;sayac1in içi 0 olana kadar her defasında 1 azalt,0 olduğunda return yap
GOTO DONGU1

RETURN            ;en son callın yapıldığı adrese  gider

END        ;programo bitir

   

DERYA GÜNDÜZ

pic 16f877a portlar ve port seçimleri

portlar nedir ne işe yarar?

portlar,microcontroller ile bileşenleri arasındaki bağlantının kurulmasını sağlar.

pic 16f877a da  5 tane  port vardır:

  • PORT A
  • PORT B
  • PORT C
  • PORT D
  • PORT E
 portların giriş çıkış  portları olması
portlar  kullanılacakları konuma  göre bazen çıkış portu bazen de giriş portu olmalıdır.portun  giriş ya da  çıkış portu olmasını yada  bazı bitlerinin  giriş bazı  bitlerinin çıkış olmasını  TRIS adındaki  özel bir register sağlar.
hangi port için çalışacaksak trisx  deyip bitlerini  değiştiririz.
0——>çıkış
1——>giriş
    clrf    TRISB            ;b  portunun bütün bitlerini çıkış yapar
   movlw  h’ff’
   movwf  TRISA         ;a  portunun  bütün bitlerini  giriş yapar
ya da  bazı bitleri girş  bazılarını çıkış da  yapabiliriz:
     movllw  b’00001111′
    movwf     TRISD        ;d  portunun ilk 4  bitini giriş,son 4 bitini çıkış yaptık
porta yazma porttan okuma:
clrf          TRISB           ;önce  b  portunun bütün bitlerini çıkış olarak ayarlıyoruz
movlw     0×55
movwf      PORTB         ;portb nin içine  55 hex  yazdık
  movlw  h’ff”
movwf    TRISA       ;a  portunu okuma yapmak için giriş portu yaptık
movf  PORTA,w
movwf   myreg          ;porta nın içeriğini  myreg adında  bir registera attık

assembly 80-80 Branch ve jump kullanımı

branch‘in kelime anlamı dallanmak demektir,branchde  bir durumun kontrolü yapılır,ona  dallanma olur.
assemby 80-80de 2 tane  branch komutu vardır:

BRN:branch on negative (negatife dallan) demektir,sayının negatif  olup olmadığını kontrol eder,sayı negatif ise sonraki satırı atlayıp onun altındaki satırdan devam eder,negatif değilse de normal sırada devam eder.

BRZ:branch on zero (sıfıra dallan) demektir,sayının 0 olup olmadığını kontrol eder,0 ise alttaki satırı atlar,devam eder;0  değilse de normal sırayı takip eder.

jump‘ın  kelime  anlamı atla,zıpla demektir,jump komutu  geldiği zaman  kod akışı  jump edilen adresten devam eder.

örnek bir  kodu inceleyelim:
bir sayının mutlak değerini bulan assembly kodu yazınız,sayı  20 hex adresindedir,mutlak değeri de  20 hex değerine yazınız,r2 ile  point ediliyor.

1         LDI       r5,7            ;jump yapabileceği adresin değerini  r5 registerında tutuyorum
2         LD        r1,r2            ;mutlak değeri alınacak sayıyı r2den r1  registeriına  atıyorum
3        BRN       r1                ;sayının  negatif olup olmadığına  bakıyorum
4          JMP  r5                 ;negatif değilse  birşey yapmaya gerek yok,7. satırdaki komutu işle,yani çıkış
5         NOT  r1,r1           ;negatifse  tersini  al,pozitif yap
6         ST    r2,r1             ;tersini aldığın sayıyı  yerine  yükle
7         Halt                      ;bitir

DERYA GÜNDÜZ

assembly 80-80

digital system dersinin sonlarına  doğru simple  computer dahilinde assembly 80-80  gördük,daha  önce  öğrenmiş olduğum pic  16f877a  den bayağı  bir farklı geldi.
Assembly 80-80 assembly diline  griş  şeklinde,eksikleri  fazla olan ve günümüzde  yetersiz kalan bir dil,16f877a  ile komutları ve adreslerin hafızalanması  da  farklı.
assembly  80-80de verilerle ilgili işelmler nasıl yapılır?
adressleri  bir  pointer işret  ediyor  ve  adresler üzerinde  işlem yapılamıyor,işlem yapılmak istendiğinde  onu  registerlara taşıyıp  o şekilde işlem yapmak gerekiyor,hangi adresteki bilgiyi taşıyıp onun üzerinde  işlem yapmak istiyorsak  pointerı da  oraya getirip onun yardımıyla taşıma  yapabiliyoruz.

şimdi basit  bir  toplama-çıkarma  işlemini inceleyelim:
memoryde 248hex adresinde “2″ verisi,249hex  adreside “153″  verisi  yazılıyor olsun,bizden istenen işelem:
 153+2-5  ve sonucu  250 hex memory alnına yazmamızı istiyor.248 hex adresini de r3   point ediyor(r3=248)
LD     r1,r3                      ;r3 ün içindeki 2 yi r1  registerına  taşıyorum
 LDI      r2,5                      ;r2  registerının  içine  5 i  atıyorum
 SUB    r1 ,r1,r2                  ;2-5  işlemini gerçekleştiriyorum
INC     r3,r3                       ;r3 pointerını 249 adresine  getiriyorum
LD      r4,r3                       ;r3ün içindeki  153 verisini alıp r4 reg  atıyorum
ADD    r1,r1,r4                      ;-3+153      işlemini gerçekleştiriyorum
INC      r3,r3                         ;sonucu yazmak için  pointerı 250ye getirdim
ST     r3,r1                            ;sonucu registerdan adrese atıyorum,store  komutu ile
DERYA GÜNDÜZ

assembly(pic 16f877a) programlama’da ardışık adreslere veri yazma

şöyle bir problemimiz var:20h  adresinden başlayarak 24h’e kadar   sırasıyla 11h,22h,33h,44h,55h adreslerini yazma,indirect adressing kullanacaz:
11h,22h,33h,44h,55h verilerini sırasıyla 20hdan başlayarak 24he kadar olan adreslere yaz

list p=16F877A                                   ;her  programın başında  yazılmalı

include “p16F877A.inc”                             ;her programın başında yazılmalı

movlw 0×20

movwf FSR              ;fsrnin içine  20hex i attım

movlw 0×11

movwf INDF               ;  11h’i 20 hex adresine yazdım

incf FSR                 ;fsrnin içini  1 arttır  yani 21hex adresine gel

movlw 0×22

movwf INDF          ;22 h’i 21 hex adresine yazdım

incf FSR                ;fsrnin içini 1 arttır yani 22hex adresine gel

movlw 0×33

movwf INDF            ;33 hexi 22 hex adresine yazdım

incf FSR                    ;fsrnin içini 1 arttır yani 23hex adresine gel

movlw 0×44

movwf INDF           ;44 hex verisini  23 hexdresine yazdım

incf FSR                    ;fsrnin içini 1 arttır yani 24hex adresine gel

movlw 0×55

movwf INDF         ;55  hex verisini  24 hex adresine yaz

end                         ;programı sonlandır

DERYA GÜNDÜZ

assembly(pic 16f877a) programlama’da adresleme çeşitleri

assembly programlama’da  3 çeşit adresleme vardır

  • immidiate adressing
  • direct adressing
  • indirect adressing

immidiate adressing:bu adresleme  türünde working egisterın içine doğrudan değişken atanabilir veya içeriğinde değişiklik yapılabilir,bu adresleme sadece  working reg ile ilgili adres atamalarında kullanılır, çünkü  başka  bir  adrese veri atacaksak mutlaka onu önce  working registera  ordan başka bir yere aktarmamız  gerekir.
movlw 0×20;working registerın içine 20hex verisini atmış olduk
sublw 0×10;istersek bu atılan veride  değişiklik de yapabiliriz

direct adressing:bu adresleme program yazarken en sık kullanılan adresleme  türüdür,bu adresleme  türünde bir veriyi  bir adrese yazmak isterken onu önce  working reg’e  taşırız,ondan da  istediğimiz yere.
movf    0×50,w             ;50 hex verisini  working  reg’e atıyorum
movwf     0×20;              ;working reg’in içindekini, yani 50hex verisini  20hex adresine atıyorum
böylece  veriyi istediğim bir adrese atmış oluyorum.

indirect adressing:dolaylı adresleme  diğer adresleme  türlerine  göre biraz daha karışk ve hata oranı daha fazladır.bu adresleme  türünde veri yazmak istediğimiz adresi  başka bir registerın içine yazıyoruz,bu exra  registera yazdığımız adrese de  başka bir  register yardımıyla veri  yazarız.

bu adresleme türünde yardımcı olarak kullandığımız iki extra  register vardır:fsr ve indf registerları.
fsr  register:veri aktarmak istediğimiz  adresin taşındığı registerdır.
indf  register:fsrnin  adreslediği yere karşılık geliyor,ram bellekte adresi buluna  fiziksel bir register değildir.
indf registerını kullanan bir komut  geldiğinde fsr’nin  gösterdiği registerın içindeki veriye ulaşmak için kullanılır.
şimdi indirect  adresleme  yolu ile   0×20 verisini  0×50 adresine atalım:

movlw  0×50         ;w rege  50 adresini attım
movwf  fsr            ;w regindeki 50 hex adresini fsrnin içine   attım
movlw  0×20         ;w regine  20 hex verisini attım
movwf   indf          ;workingdeki  20 hex verisini  indf’nin  içine attım,yani  fsr’nin  tuttuğu 50 hex adresine  20
;hex verisini yazmış oldum

neden indirect adresleme kullanma  gereği  duyarız???
indirect  adresleme  türünü daha  çok ardıiık adreslerde işlem yapmak için  kullanırız,
incf  fsr     diyerk  bir sonraki adrese  kolaylıkla  geçmiş olruz.

DERYA GÜNDÜZ

assembly programlama/iki adresteki verinin yer değiştirmesi

iki tane  registerımız olsun;
reg1
reg2
reg1 ve reg2nin içindeki verileri değiştirmek istiyorum.
assembly  programlamada essas olarak bir veriyi bir adrese taşıma istiyorsam o veriyi önce  working registera orda istenilen adrese taşımalıyım,iki registerın içini yer değiştirmek istiyorsam da hem working reg hem arada geçici kullanacağım bi reg kullanmalıyım,bu reg temp olsun.
değiştirme kodlar;:

movf reg1,w           ;reg1in içini w rege  at
movwf temp             ;wnin içeriğini  tempe at
movf reg2,w       ;reg2yi w ye at
movwf reg1         ;wnin içinde  reg2 vardı bunu  reg1e atıyorum
movf temp,w     ;tempin içini wye atıyorum,içinde reg1(içeriği) vardı
movwf reg2       ;wnin içini  yani tempten gelen reg1i de  reg2 ye attım

böylece temp geçici registrı ve  working registerı sayesinde reg1 ve reg2nin içini değştirmiş olduk
DERYA GÜNDÜZ