Online Pic Compiler
- ÜCRETSİZ - ONLINE PIC ASSEMBLY COMPILER
- KULLANIMI KOLAY ARAÇLAR
- ÖĞRETİCİ YARDIM DOSYALARI
- HATA AYIKLAYICI VE SİMÜLATÖR ÖZELLİĞİ

Bu yazıya direk olarak, bir örnekle başlayalım. Butona bastığımızda bir DC motoru saat yönünde, butondan elimizi çektiğimizde ise bu motoru saat yönünün tersine döndüren basit bir sistem düşünelim.

Mikrodenetleyici uygulamalarında bir sonuca erişebilmek için birden fazla çözüm yöntemi bulunabilir. Benzer şekilde buton algılamanın da bir çok yolu bulunmaktadır. Burada basit bir çözüm üzerinde duracağız. Butondan gelen sinyali sürekli olarak kontrol edecek ve programı eğer basıldığını tespit edersek, motorun saat yönünde dönmesini sağlayan, diğer durumda ise saat yönünün tersinde dönmesini sağlayan kodlara yönlendireceğiz.
Bu örnek için iki farklı durum
- butonuna basılıyor olması
- butona basılmıyor olması
ve iki farklı tepki
- motoru saat yönünde dönmesini sağlayan sinyallerin gönderilmesi ve
- butonun saat yönünün tersinde dönmesini sağlayan sinyallerin gönderilmesi
bulunmaktadır. Bu tepkiler kodlama seviyesinde gerçekleştirildiğinden, programda her bir tepki için ayrı bir kod sekmesi bulunmalıdır. Bu kod sekmelerine geçiş ise, butona basılıp basılmadığını kontrol eden bir şartlı ifade ile gerçekleşmektedir.
Program içerisinde bir bitlik verinin, o an için, 0 mı yoksa 1 mi olduğunu kontrol etmek için oluşturulan kod parçası, bit kontrol eden şartlı bir ifadedir.
Bir butona basılıp basılmadığını anlamak için aşağıdaki gibi bir devre kurup, butonun bağlı olduğu pinin mantık-1 mi yoksa mantık-0 mı olduğunu test etmemiz gerekir.

Yukarıdaki devreyi takip edecek olursak, butona basıldığı zaman, bağlı bulunduğu porta gelen voltajın 5V (mantık seviyesinin 1) olduğunu ve basılmadığı zaman ise voltaj değerinin 0V (mantık seviyesinin 0) olduğunu görebiliriz. Bu nedenle, butonun o an için basılı olup olmadığını, bağlı olduğu port olan RA0'ın mantık seviyesine bakarak test edebiliriz. İki farklı durum için de, farklı bir sinyal göndereceğimizden, farklı bir kod sekmesine geçiş yapmamız gerekecektir. Bu geçişleri GOTO komutuyla gerçekleştirebiliriz. Karşılaştırma kısmı için ise, BTFSS veya BTFSC komutlarını kullanabiliriz.
Diyelim ki, motorun saat yönünde çalışmasını sağlayan kod parçası için SAAT, diğer yönün kod parçası için de TERSSAAT etiketi kullanılmış olsun. Bu durumda
Örnek :
- BTFSC PORTA, 0
- GOTO SAAT
- GOTO TERSSAAT
komutları, RA0'ın karşılaştırmasını gerçekleştirecektir.
BTFSC komutu iki parametre alır. Bunlardan ilki, komutun hemen yanında belirtilen bellek alanı ismidir. İkincisi ise, virgülden sonra yazılan bit numarasıdır. BTFSC bellek alanının belirtilen bit numarasındaki mantık seviyesini kontrol eder. Eğer, bu mantık seviyesi 0 ise, bir sonra yazılan satırı (GOTO SAAT) atlar ve kendisinden sonraki ikinci satıra (GOTO TERSSAAT) geçer. Eğer mantık seviyesi 1 ise, atlama işlemini gerçekleştirmez ve kendisinden bir sonraki satıra (GOTO SAAT) gider. Böylece, eğer butona basılmışsa SAAT, basılmamışsa TERSSAAT ile etiketlenmiş kod parçasına geçilir. Buradaki koşullu ifade BTFSC komutuyla gerçekleştirilmektedir.
Örnek :
- BTFSC PORTA, 0
- GOTO TERSSAAT
- GOTO SAAT
komutları, RA0'ın karşılaştırmasını gerçekleştirecektir.
Bit kontrolü sadece Giriş-çıkış PORT'ları için değil, hafızadaki herhangi bir bellek alanının (register) istenilen bir biti için de yapılabilir. örneğin, yazdığımız programda yaptığımız aritmetik işlemin sonucunu SONUC isimli bir bellek alanı içerisine kaydetmiş olalım. Sonucumuz tek sayı ise RB0'a bağlı LED'i, çift sayı ise RB1'e bağlı LED'i yakmamız gerektiğini düşünelim.

Bu durumda kontrol etmemiz gereken şey, SONUC isimli bellek alanının son bitidir. çift sayılar için son bit her zaman 0, tek sayılar için ise her zaman 1 olur (örneğin, 7'nin ikilik düzende gösterimi 0000 0111, 6'nınki ise 0000 0110'dir). Son bite göre işlem yapmamız için, bir önceki örnekteki gibi, BTFSC veya BTFSS komutlarından birini kullanabiliriz. SONUC çift olduğunda RB0’daki LED’i yakmak için yazdığımız program CIFT, diğer durumdaysa TEK etiketi altında olsun. Bu durumda,
Örnek :
- BTFSC SONUC, 0
- GOTO TEK
- GOTO CIFT
satırları beklediğimiz dallanmayı program içerisinde yapacaktır. Son bitimiz (0 lokasyonundaki) 1 ise (yani SONUC tek bir sayı ise) bir sonraki satır olan GOTO TEK işlenecektir. SONUC, çift sayı olduğunda ise BTFSC’den sonraki satır atlanarak GOTO CIFT satırına geçilecektir.
Assembly programlamada, bellek alanlarında tutulan sayıların sabit sayılarla veya birbirleriyle karşılaştırılması gereken durumlarla sıklıkla karşılaşılır.
Program akışına göre, bu karşılaştırmalar büyüklük, küçüklük veya eşitlik ölçütlerine göre yapılabilir.
Eşitlik Durumu
7 segmentte dijital bir saat uygulaması yaptığımızı düşünelim. Bu uygulamadaki saniye, dakika ve saat sayılarını RAM'deki bellek alanları içerisinde tutmalıyız. Saniye değerini, SANIYE adında bir bellek alanında tutuyor olalım.

Her bir saniye geçtikten sonra, SANIYE’de tutulan sayı bir artırılmalıdır. Fakat, SANIYE 60'a eriştiğinde, değeri 7 segmente göndermeden önce sıfırlamalı ve dakikayı temsil eden sayıyı bir artırmalıyız. Bu nedenle, program içerisinde SANIYE’yi 60 sayısı ile karşılaştıran bir şartlı ifadeye ihtiyaç duymaktayız.
Assembly dilinde, iki sayının eşit olup olmadığını anlamanın bir kaç yolu bulunmaktadır. Bu yolların tümünde eşit olma ve olmama durumları için sıfır bayrağının (zero flag) farklı değerler alıyor olması kullanılmaktadır.
Örneğin, SANIYE’den 60 çıkardığımızda, SANIYE 60'a eşit olduğu durumda sonuç sıfır olacaktır. Başka bir ifadeyle, sıfır bayrağı (zero flag) yalnızca SANIYE=60 durumunda 1 olacaktır. Toparlayacak olursak, SANIYE’den 60 çıkarıp, sıfır bayrağını BTFSC veya BTFSS komutlarından biriyle kontrol ederek bu registerın 60'a ulaşıp ulaşmadığını kontrol edebiliriz. Diğer bir çözüm yolu da, SANIYE’yi 60 ile XOR işleminden geçirmektir. İki registerın XOR değeri yalnızca bu iki sayı birbirine eşit olduğunda sıfırdır.
SANIYE’nin 60’a eşit olmadığı durumda değerini bir artıran kod sekmesine ARTIR, değerini sıfırlayıp dakikayı bir artıran kısma ise SIFIRLA etiketini verelim.
Örnek :
- MOVF SANIYE, W
- SUBLW D'60'
- BTFSC STATUS, Z
- GOTO SIFIRLA
- GOTO ARTIR
ve
Örnek :
- MOVF SANIYE, W
- XORLW D'60'
- BTFSC STATUS, Z
- GOTO SIFIRLA
- GOTO ARTIR
kod dizilerinin her ikisi de beklenen karşılaştırmayı yapmakta ve eğer SANIYE=60 ise SIFIRLA etiketine, diğer durumda ise ARTIR etiketi ile belirtilmiş kod sekmesine geçiş yapmaktadır.
Yukarıdaki kod dizilerinde ilk satır, SANIYE değerinin W'ya kopyalanmasını sağlamaktadır. İkinci satırda yapılan çıkarma veya XOR işlemlerinin sonucu STATUS içerisindeki sıfır bayrağınının durumunu değiştirmektedir. Sayılar eşitse (sonuç sıfırsa) sıfır bayrağı 1, diğer durumda ise 0 olmaktadır. BTFSC komutu ise bu bitin değerine göre atlama yaptığından program eşitliğin olup olmamasına göre farklı sekmelere geçiş yapmaktadır.
Büyük veya Küçük olma durumları
Şimdi şöyle bir senaryo düşünelim: Bir analog sicaklık sensöründen (LM35 gibi) gelen verilerin belli periyotlarla mikrodenetleyicinin ADC ünitesine alınıp sonuçların SENSOR isimli bir bellek alanına kaydedildiğini düşünelim. Gelen sensör değeri 120'den büyükse, fanı çalıştırmak için, FAN isminde bir kod sekmesi çağrılacak olsun. Yukarıdaki örnekte olduğu gibi, her defasında, SENSOR bellek alanının içerisindeki değerin 120'den büyük olup olmadığına bakılacak ve karşılaştırma sonucuna göre FAN etiketine atlanacak veya SENSOR kontrol edilmeye devam edilecek olsun.
Böyle bir karşılaştırmayı yapabilmek için, SENSOR içeriğinden 120 değerini çıkarıp, Carry Flag değerinin ne olacağına bakabiliriz.
Örnek :
- KONTROL
- MOVLW D'120'
- SUBWF SENSOR, W
- BTFSS STATUS, C
- GOTO KONTROL
- GOTO FAN
Yukarıdaki kodlamada ilk satır, sadece kod sekmemizi etiketlemek için kullanılmaktadır. İkinci satırda (MOVLW D'120') ise W'ya 120 değerini kopyalıyoruz. üçüncü satırda (SUBWF SENSOR, W) ise SENSOR’den W’yu, yani 120 sayısını, çıkarıp tekrar W içerisine yazıyoruz. Kodlama terimleriyle yaptığımız işlem W=SENSOR-W olur. SENSOR eğer 120'den büyükse veya bu değere eşitse çıkarma işleminin sonucu negatif olmayacağından Carry Flag=1 olur. Tersi durumda ise Carry Flag=0 olacaktır. Dördüncü ve ilerleyen satırlarda, daha önce yaptığımız karşılaştırmalara benzer bir yöntem izlemekteyiz.