pic ile toplama işlemi yapılması...

Başlatan memo84, 14 Şubat 2009, 11:35:52

memo84

slm arkadaşlar.
öncelikle forumda böyle bir soruya raslamadım eğer varsa sizlerden özür dilerim.
pic ile 10 tane sayıyı toplamam gerek.bu 10 sayı ad den belli aralıklarla okunan değerlerdir.amacım  bunları tolayıp ortalamasını almam.bunu en hızlı şekilde nasıl yapabiliriz.bi önerisi olan varmı.asm ile yapmam gerek.
ilgilenen arkadaşlara teşekkür ederim

MURSEL

dijital elektronik calış  birazcık asm  ile yazabilmen icin

memo84

dostum cvp için sagol ama ben hızlı bi method istemiştim.yani ben işlemi yaptım.ama cok uzun surdu.örneğin dizi olustururen  fsr yi kullanıyorsun.ve istediğin diziye sayıyı atıyorsun.benim istediğim toplama içinde fsr gibi bi komut varmı?

Tagli

Söz konusu sayılar tamsayı mı? Açıkçası ASM'de tam olmayan sayılarla hiç uğraşmadım. Tamsayıları toplamak kolay. Bu sayılar 1 byte'lık ise 2 byte'lık bir alan sonucu saklamak için yeterli olacaktır. Yeni sayıyı küçük byte'a eklemeli ve işlem sonunda C'yi (Carry Bit) kontrol etmelisin. Taşma varsa büyük byte'ı 1 arttırmalısın.

Bölme işi daha karışık. İnternette hazır algoritmalar bulabilirsin, hatta Microchip'in bu konu hakkında kendi hazırladığı belgeleri var. Eğer 10 değil de 8 veya 16 gibi 2'nin kuvveti bir sayıya bölme yapacaksan kaydırma yöntemini kullanarak çok hızlı ve kolay bir şekilde sonuca ulaşabilirsin. Ama tamsayı kullandığın zaman elbette ki bölme sonucundaki küsuratlı kısmı kaybedeceksin.
Gökçe Tağlıoğlu

agora_meyhanesi42

Hızlı bir metod istiyorsan ve asm de bilmiyorsan En hızlısı pic basicte yazmak bence :)
Yüksel Türk ! Senin için yükselmenin hududu yoktur...

bigbey

sayıları 10 kez toplama yerine 8 kez veya 16 kez toplamak uygun olurmu.
buna göre kolay bir bölme işlemi yapabilirsiniz. 2 nin katları olarak çalışırsanız. işlem hızınız en iyi durumda olur.
Toplama yaptığınız sayıların sonucunu aldığınız registeri, 3 kez sağa kaydırdığınızda mevcut sayınız 8'e bölünmüş olur. 4 kez sağa kaydırırsanız 16 ya bölünmüş olur.(carry bitini sıfırlamayı unutmayınız)
TA6R

XX_CİHAN_XX

Öncelikle FSR bir komut değil, picin içinde bulunan bir registerdir.
FSR(File Select Register) adındanda anlaşılacağı üzere picin ram belleğindeki tüm yazmaçlara doğrudan ulaşabilmeni sağlayan bir registerdir. Örneğin; 0x20 adresinden itibaren sıra ile 10 adet register tanımladın ve bu registerleri toplayıp sonucunuda 11 ve 12 sıradaki yani 0x2A ve 0x2B deki iki byte lık register alanına yazmak istiyorsun. (Sonuç 16 bit olacağı için 2 byte lık yer kaplamaktadır.)
FSR ile 0x20 den 0x29 a kadar olan 10 adet registere direkt olarak yada sıralı bir şekilde ulaşabilirsin. Bu olay C dilindeki Dizi mantığı ile aynı sayılabilir.
Örneğin;
  MOVLW   0x20
   MOVWF   FSR
   CLRF    INDF           ;FSR nin gösterdiği adresteki register clear oldu
   INCF    FSR,F          ;FSR bir sonraki registeri işaret ediyor
   MOVLW   0x2A        
   SUBWF   FSR,W
   BTFSS   STATUS,Z  ;FSR tüm regsiterleri işaret etti mi
   GOTO     $-5          ; Hayır ise hepsini temizlemeye devam :)

Yukarıdaki kod parçası şöle çalışmaktadır önce FSR ye bir adres değeri yüklenir ardındanda  o adresteki register e yüklemek istediğimiz değer INDF registerine yüklenir. Bu şekilde bir döngü sayesinde 0x20 den 0x29 a kadar olan 10 ader registeri Clear etmiş olduk. Bu register sayısı 10 değilde 60 ta olabilirdi. Bu sayede 60 tane alt alta CLRF register şeklinde komut yazmaktansa yukarıdaki gibi 8 satırlık bir döngü ile bu işi rahatlıkla yapmış olurduk. FSR olayına açıklık getirdiğimize göre gelelim 16 bitlik toplama işlemine oda aşağıdaki 8 satırlık kodla bitiverir :)
  MOVF   TOPL1L,W
   ADDWF   TOPL2L,W
   MOVWF   SONUCL
   MOVF   TOPL1H,W
   BTFSC   STATUS,C
   ADDLW   .1
   ADDWF   TOPL2H,W
   MOVWF   SONUCH

Gelelim ortalama alma işine. Onda sana çok pratik bir yöntem önericem.
Anladığım kadarıyla adc çevrim sonuçlarından 10 örnek alıp ortalamasını yazmaya çalışıyorsun burada örnekleme alacağın sayıyı 2 nin üssü ile tam çakışabilen bir sayı seçersen dediğim pratik yöntem ile işini görebilirsin.
Örneğin; 10 kez değilde 8 (2 üzeri 3) kez yada 16 (2 üzeri 4) kez örnekleme alırsan müthiş hızlı bir şekilde ortalama alabilirsin. Nasıl mı?
İşte şöyle, 8 sayının ortalamasını almak için sayıları toplayıp 8 e bölmek gerekir. Yukarıda toplamayı öğrendin şimdi gelelim 8 e nasıl böleceğimize.
Bir sayıyı sağa kaydırmak demek o sayıyı 2 ye bölmek demektir ;)
(aynı şekilde sola kaydırmakta 2 ile çarpmak demektir.)
Yani bir sayıyı n kez sağa kaydırırsam o sayıyı 2 üzeri n değerine bölmüş olurum. Öyleyse 8 sayının ortalamasını almak için toplam değeri 3 kez sağa kaydırmamız yeterli olacaktır. Gördüğün gibi süper hızlı ve pratik bir yöntem. Yani 16 bitlik toplam sonuç değerini 3 kez sağa kaydıracaksın. Aynen şöyle;
;BU BİRİNCİ KAYDIRMA
   BCF     STATUS,C
   RRF     SONUCH,F
   RRF     SONUCL,F

;BU İKİNCİ KAYDIRMA
   BCF     STATUS,C
   RRF     SONUCH,F
   RRF     SONUCL,F

;BUDA ÜÇÜNCÜ KAYDIRMA
   BCF     STATUS,C
   RRF     SONUCH,F
   RRF     SONUCL,F

8 sayının ortalamasını almış bulunuyoruz hayılı uğurlu olsun.
16 sayı olsaydı 4 kez kaydıracaktık  ;)

Edit : Bigbey hocamla aynı anda mesaj göndermişiz. Oda aynı konuya değinmiş  :P
Kolay gelsin...
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

Erhan YILMAZ

Arkadaşlarında dediği gibi endirek adresleme ile dizi oluşturarak toplama işlemini yapabilirsin fikir vermesi açısından yazdığım kodları ekliyorum aşağıdaki program 10 tane değişkeni toplayıp sonucl ve sonuch isimli toplmada 16 btilik değişkene aktarıyor

       
MOVLW	0X0A
MOVWF	SAYAC
MOVLW   0x20
MOVWF   FSR
MOVF	INDF
ADDWF	SONUCL,F
BTFSC	STATUS,C
INCF	SONUCH,F
INCF	FSR,F
DECFSZ	SAYAC,F
GOTO	$-5 
RETURN


Ortalaması almak için sayıyı 10 bölme işlemi yapman gerekir bunu asm de yapabilmen için sayıdan sürekli 10 çıkarman gerekir işlem 16bitlik sayıyı 8bitlik sayıya bölme işlemidir.

MOVLW	0X0A
SUBWF	SONUCL,F
BTFSC	STATUS,C
DECF	SONUCH,F
BTFSC	STATUS,C
RETURN
INCF	ORTALAMA,F
GOTO	$-7


yukarıdaki kod parçası ise 16bitlik sonuc saklayıcısından sürekli 10 çıkarıyor. ve her çıkartmada ortalamayı bir arttırıyor. sayı enson 10 dan küçük hale gelincede return ile geri dönüyor ortalama değeride ortalama değişkeninde kalıyor. Bu şekilde istediğin işlemi yapabilirsin kodlarda hata olabilir biraz aceleye geldi.

memo84

Sayın arkadaslar.Vermiş olduğunuz cevaplar için hepinize  ayrı ayrı teşekkur ederim...
bu arada,Bu pic ile uğraşmak niye bukadar zevkli yaa :D:D