ASM makro kullanımı ile ilgili bilgiler

Başlatan alisumer, 11 Aralık 2022, 01:56:13

alisumer

  program başında "radix dec" veya    "list r=dec " ifadesi ile program içerisinde vereceğimiz desimal 8 bitlik değerleri aşmadan şu tarz oynamalar yapabiliriz.böylelikle negatif sayıları dönüştürme işi ile uğraşmadan da işlemler yapabiliriz.NOT: radix belirtmeden varsayılan olarak aynı işlemleri HEX sayı sisteminde de yapabilirsiniz ama kontrolu güç olur böyle iyi   
include   "..........."
 list r=dec
.........
BASLA:
    CLRF        STATUS
    MOVLW    -8*11               ; 0xA8 (-88) sayısını değişkenimize yazar yazar
    MOVWF    SAYI
    MOVLW    (28<<2)-42          ;0x46 (70) sayısını değişkene yazar
    MOVWF    KERE
    ADDWF    SAYI    ,W  ;TOPLAMA SONUCUNU 0XEE(-18) ŞEKLİNDE BULUR
bu yazım şeklini meblab ide kabul ediyor tüm denemelerim doğru sonuç verdi işlem eper 8 biti aşarsa alt byte gene doğru değeri verir ama üst byte kaybolur.bu hali ile bile birçok problemimi çözüyor.
Hep meraktan

alisumer

#16
32 Bit işaretli sayıları paket halinde değişkenlere yazmak için bir makro
#include p16F690.inc
RADIX    DEC                  :desimal sayılar ile işlem yapabilmek için gerekli
CBLOCK 0x20
Out0 :5 ;res 1 ;
ENDC
PAKET32 MACRO Var, Address ;Address meblab ide için Cblock yada udata kullanıldığında ram başlangıç adresidir(otm)
BANKSEL Address
movlw Address
movwf FSR                  ;fsr ye adresi yükler
movlw Var & H'FF'          ;en değersiz byte filtrelenip yazılır
movwf INDF                ;fsr nin işaretlediği adrese değeri yazar
movlw Var >>8 & H'FF'      ; Var 8 bit kaydırılır filtrelenip fsr 1 arttırılır(bir sonraki ram bölgesi yazılır)
incf FSR,F
movwf INDF
movlw Var >>16 & H'FF'
incf FSR,F
movwf INDF
movlw Var >>24 & H'FF'
incf FSR,F
movwf INDF
ENDM
ORG 0
START
PAKET32 12345678,Out0 ; PAKET32 -12345678,Out0 yazıldığında da negatif değeri yazabilir adreslere
goto START
END
yazılan değer en fazla 2.147.483.647 ile -2.147.483.648 arası olabilir
Hep meraktan

alisumer

TOGGLE MACRO PORT?,R0
MOVLW 0X01<<R0
XORWF PORT? ,F
           ENDM
bir pinin durumunu terslemek için makro .program içerisinde örneğin "TOGGLE PORTA,5"  yazıldığında porta 5 pini durum değiştirir NOT: makro içerisindeki soru işaretine dokunmayın MEPLAB soru işaretini ana programda yazdığımızla değiştirir.
Hep meraktan

alisumer

#18
;/////////////////////////////////////////////////////////////////
;EEPROM YAZMA
;/////////////////////////////////////////////////////////////////
WRITE MACRO R3,R1
BCF INTCON ,GIE ;KESMELERİ KAPAR (ÖNEMKİ KESME OLMAMALI YAZMA ESNASINDA)
BCF PIR2 ,EEIF ;PAYRAĞI İNDİR
MOVF R3 ,W ;
BANKSEL EEADR
MOVWF EEADR ;BELİRTTİĞİMİZ ADRESİ EEADR E YAZ(YAZILACAK ADRESİ SEÇ)
BANKSEL R1
MOVF R1 ,W ;
BANKSEL EEDAT
MOVWF EEDAT ;VERİYİ ADRESE YAZ
BANKSEL EECON1
BCF EECON1 ,EEPGD ;eeprom veya program hafızası seçilebilir.burada eeprom seçili
BSF EECON1 ,WREN ;yazmayı aç
MOVLW 0X55
MOVWF EECON2 ;yazma için rutin olan h55 ve hAA komutları eecon2 ye sırası ile yazılmalı
MOVLW 0XAA
MOVWF EECON2 ;eecon2 ye sırası ile yazılmalı
BSF EECON1 ,WR ;yazmaya başla
BTFSC EECON1 ,WR
GOTO $-1 ;bitene kadar takıl
BANKSEL PIR2
BTFSS PIR2 ,EEIF ;TAMAMLANINCA BAYRAK KALKAR DEVAM
GOTO $-1
BANKSEL EECON1
BCF EECON1 ,WREN ;yazmayı kapat
BCF STATUS ,RP1
BCF STATUS ,RP0 ;Bank 0
BCF PIR2 ,EEIF ;BAYRAĞI İNDİR
ENDM
;////////////////////////////////////////////////////////////////
;EEPROM OKUMA
;////////////////////////////////////////////////////////////////
READ MACRO R3
MOVF R3, W;
BANKSEL EEADR
MOVWF EEADR ;Data Memory ;Address to read
BANKSEL EECON1
BCF EECON1, EEPGD ;Point to DATA memory
BSF EECON1, RD ;EE Read
BTFSC EECON1, RD
GOTO $-1
BANKSEL EEDAT
MOVF EEDAT, W ;W = EEDAT
BANKSEL PORTA
ENDM
program içerisinde kullanılacak örnek kodlar YAZMA İÇİN " WRITE 3,VAR" okuma için "READ 3" komutları ile eepromun 3.adresine VAR değişkeni yazılır.okuma komutu ile de 3. adresten kaydedilmiş veri "W" ye yazılır.bu hali ile basic komutuna benzedi biraz.
Hep meraktan

alisumer

ETE hocam bir sorum olacaktı iki butonum var ve birine bastığımda bir word değişkeni ardışık iki adrese ve diğerine bastığımda da ilk ikisinin ardından ilk adresten itibaren diğer bir word değişkeni yazdım örnek (0,1,2,3 adresleri gibi) bu adres başlangıcı olan sayıyı yani "0"ı da 255. adreste tuttum ve her yeni eprom kaydı sonrası bu adresi bir artırıp tekrar kaydettim program başında da adresi okuyarak hangi adresten kayda başlayacağımı bildim sonra de eeprom ömrünü uzatmak için saatlerce uğraşıp çok saçma bir yere vardığımı farkettim çünkü bu sefer de adresi tuttuğum 255.adresi hunharca kullanmış oldum :o.daha önce böyle bir paylaşım yapılmıştı ama bulamadım.çözüm hakkında yardımcı olurmusunuz.
Hep meraktan

ete

Sorunu anladım. Benzer işlerle daha öncede uğraşmıştım. Burada temel amaç eprom hafızalarına dengeli biçimde gerektiği kadar yazma yapılmasıdır. Sıfır adresi dışında kalanları dengeli kullanıyorsun ama sıfırı da bu arada aşırı şekilde kullanmış oluyorsun.
Ben son olarak şöyle bir mantık kullanmıştım. Senin örneğine benzeterek açıklayayım.

Sıfır nolu adresten kayıta başladık ve ilk 4 adrese değişkenlerini kayıt ettik.
Elimizde 1 sayac daha olacak. Bu sayac ilgili adreslere kac defa kayıt ettiğimizi tutacak. Tabiiki bu değerleride kayıt etmek zorunda kalacaksın. Bu durumda kayıt adedin 5 olacak. Böylece ilk 5 adrese kayıt yaptın ve sondaki adres(baştakide olabilir) kayıt adedin olacak. Bu adreslere en azından 100 kayıt yada toplamda 255 kayıt yapacağını düşünebilirsin.
Şimdi diyelimki adres kayıt limitini doldurdun. Yapılacak iş 0+5=5 nolu adresten itibaren yenilerini kayıt etmek ve 0-4 arasına 255 değerini yeniden yazmak olacak.
Böylece okuma yaparken 255 lerin bittiği yeri bulup onu kayıt altında tutman bir dahaki kayıtı oraya yapman yeterli olacaktır. 255 den küçük bir değer bulunmaz ise işin başında olduğunu anlayabilir ve sıfır nolu adresten işe başlarsın. Böylece adresleri dengeli şekilde tutabilirsin. Önceleri adres göstergesinide kayıt ediyordum ama sonradan fazla işe yaramadığına karar verip yanlızca kayıt adedini tutuyordum.
Bu iş akıl işidir. Bir başkası daha akıllıca bir yöntem bulabilir. Kafa yormak gerek. Amacımız eprom adreslerini dengeli şekilde kullanmak hep aynı adrese kayıt yapmamak. Düşünün bakalım.

Ete

alisumer

Anladım sanırım tek eksi yanı sisteme ilk enerji verildiğinde epromda ff harici ilk değeri bulana kadar okuma yapıp ilk baştaki 0-254 arası sınırladığım kayıt adedini bulana kadar bir gecikme olacak.teşekkürler hocam.
Hep meraktan

ete

Eprom okumasında bekleme yapılmıyor biliyorsun. Toplam 256 adres okunacak ki bu çok kısa sürede halledilir. Üstelik her açılışta belirli bir gecikme uygulandığınıda unutma. Onu minimumda (150ms dir) tutarsın gerisi 100 ms bile tutmaz diye düşünüyorum. Kısaca sorun olmaz. Ama emniyetli bir sistem bana kalırsa.

Ete

alisumer

Karşılaştırma fonksiyonları için makrolar.
;///////////////////DEĞER KIYASLAMASI//////////////////////////////////
;KULLANIMI= KARŞILAŞTIRILACAK HER BİR "WORD" DEĞERİ ARDIŞIK RAM BÖLGELERİNDE TUTULMALI
;R4 VE R5 DEĞERLERİNİ ASCII DEĞERLER OLARAK İLGİLİ İŞARETLER OLARAK SEÇTİM
;MAKRODA "=" SENBOLÜ KABUL EDİLMEDİĞİ İÇİN DEC KARŞILIĞI YAZILDI
;AMA ANA PROGRAMDA KULLANILABİLİR OLDU
;ÖRNEK KODLAR= KIYAS A,"<","=",B
; KIYAS A,"<"," ",B
; KIYAS A,"="," ",B
; BTFSS R6 ,0
; GOTO ****
; GOTO ****
;BOŞ BIRAKILAN SEMBOL YERİNE ASCII BOŞLUK BIRAKILMALI
;R6 ADRESİNİN İLK BİTİ TRUE/FALSE DÖNDÜRÜR
;MAKRO ÇIKIŞI R6 , 0 BİTİ KONTROL EDİLEREK İŞLEM YAPILIR
;" > " YADA ">=" İŞARETİ İÇİN AYRI BİR İŞLEME GEREK YOK MEVCUT İŞLEMLERİN TERSİ OLDUĞUNDAN SADECE DEĞİŞKEN YERİ DEĞİŞECEK
KIYAS MACRO R0,R4,R5,R2
IF   R4 == "<" && R5 == 61
MOVF R0+1 ,W ;IF Y <= ART THEN GOTO KAPA
SUBWF R2+1 ,W ;
BTFSS STATUS ,C ;
GOTO YANLIS ;GOTO SAG_KAPA
BTFSS STATUS ,Z
GOTO DOGRU ;GOTO SAG_AC
MOVF R0 ,W
SUBWF R2 ,W
BTFSS STATUS ,C
GOTO YANLIS
GOTO DOGRU
ENDIF
IF   R4 == "<" && R5 == 32
MOVF R0+1 ,W ;IF Y < ART THEN
SUBWF R2+1 ,W ;
BTFSS STATUS ,C ;
GOTO YANLIS ;GOTO SAG_KAPA
BTFSS STATUS ,Z
GOTO DOGRU ;GOTO SAG_AC
MOVF R0 ,W
SUBWF R2 ,W
BTFSC STATUS ,Z
GOTO YANLIS
BTFSS STATUS ,C
GOTO YANLIS
GOTO DOGRU
ENDIF
IF R4 == 61 && R5 == 32 ;IF A=B
MOVF R0+1 ,W
XORWF R2+1 ,W
BTFSS STATUS ,Z
GOTO YANLIS
MOVF R0 ,W
XORWF R2 ,W
BTFSS STATUS ,Z
GOTO YANLIS
GOTO DOGRU
ELSE
GOTO EXT
ENDIF
YANLIS:
BCF R6 ,0
GOTO EXT
DOGRU: ;GOTO SAG_KAPA
BSF R6 ,0
GOTO EXT
EXT:
ENDM   
 
işaretleri ascii olarak kullanmak zorunda kalmam dışında iş görür tabi bide adı kıyas  ::) .ayrıca diğer dillerin karşılaştırma sonucu çıkardığı koddan çok daha kısa kod üretiyor.kullanımını kodun üzerinde başlık kısmında yapmaya çalıştım soru yada kodda bir sorun olursa bildirin lütfen.denemelerini yaptım hata bulamadım ama insanlık hali.
Hep meraktan

alisumer

#24
programı işlemciye yazdığımız esnada eeprom'a veri yazmak içindir,program çalışması esnasında herhangi bir yazma yapmaz.program içerisinde rutin eprom yazma kodları ile tekraren değiştirilebilir tabiki.
       
        org      0x00
        basla:
        çalışan programlarımız
        ......
        .......
        goto basla
        ORG    0X2100         ; eepromun çoğu 16 f serisinde başlangıç adresi
        DE  0, 0, 0, 0, 0, 0    ;ilk adresten başlayarak 5. adrese kadar 0 yazar
        END
   
Hep meraktan

alisumer

#25
aynı formatı gene ilgili adreslerinde örneğin org 0x800  kullanılarak bu sefer program hafızasına "data,da veya dw"komutları kullanılarak yazılabilir
Hep meraktan

alisumer

Klasik for-next döngüsü için bir makro "FOR 10,200" şeklinde kullanımı pic basic pro ya oldukça benzer oldu,işlevi ise  for dan sonraki kodu next makrosunu görene kadar çalıştırır next makrosunda fordaki verilen koşula bakar ona göre kodu yeniden tekrarlar yada bir altından devam eder.şu an için sadece 255 e kadar tekrar yapabiliyor,for ve next iki ayrı makro olarak çalışır
FOR MACRO R0,R2
MOVLW R2
MOVWF R4
MOVLW R0
SUBWF R4 ,F
FOR1:
ENDM
NEXT MACRO
DECFSZ R4 ,F
GOTO FOR1
ENDM
kullanımı ise
FOR 10,220
BSF PORTA ,0
NOP
BCF PORTA ,0
.........
........
NEXT
Bu kodda for next arasına yazdığımız kodun 210 kere tekrar etmesi sağlanır
Hep meraktan

alisumer

#27
Map fonksiyonu için makro bildiğimiz arduino map fonksiyonu ile aynı çalışıyor hayırlı olsun :)
bir hata yapmışım düzeltip paylaşacağım
Hep meraktan

alisumer

Bölme fonksiyonu hata veriyordu düzelttim
MAP    MACRO    R0,R0+1,VAR,VAR1,VAR2,VAR3,ADDRESS ;address =VAR
 ;{
;return ((value - fS) * (tE - tS)) / ((fE - fS) + tS);
;map(value,fS, fE, tS,tE)
;map(512, 0, 1023,0, 2000)            ((512-0)*(2000-0)/(1023-0)+0)
    BANKSEL ADDRESS
    movlw    ADDRESS ;
    movwf    FSR                    ;fsr ye adresi yükler
    movlw    VAR & H'FF'            ;;en değersiz byte filtrelenip yazılır
    movwf    INDF                ;fsr nin işaretlediği adrese değeri yazar
    movlw    VAR >>8 & H'FF'        ;; Var 8 bit kaydırılır filtrelenip fsr 1 arttırılır(bir sonraki ram bölgesi yazılır)
    incf    FSR        ,F
    movwf    INDF
    MOVLW    VAR1 &0XFF
    INCF        FSR        ,F
    MOVWF    INDF
    MOVLW    VAR1>>8 & 0XFF
    INCF        FSR        ,F
    MOVWF    INDF
   
    MOVLW    VAR2 & 0XFF
    INCF        FSR        ,F
    MOVWF    INDF
    MOVLW    VAR2 >> 8 &0XFF
    INCF        FSR        ,F
    MOVWF    INDF
    MOVLW    VAR3 & 0XFF
    INCF        FSR        ,F
    MOVWF    INDF
    MOVLW    VAR3 >> 8 &0XFF
    INCF        FSR        ,F
    MOVWF    INDF
;*******************************************************************FONKSİYONLAR**************************   
    MOVF        R1        ,W
    SUBWF    R0        ,F
    BTFSS    STATUS    ,C
    INCF        R1+1        ,F    ;VALUE-FS
    MOVF        R1+1        ,W    ;SONUC    R0
    SUBWF    R0+1        ,F
;///////////////////////////////
    MOVF        R3        ,W
    SUBWF    R4        ,W
    MOVWF    R5
    BTFSS    STATUS    ,C
    INCF        R3+1        ,F    ;TE-TS
    MOVF        R3+1        ,W    ;SONUC    R5
    SUBWF    R4+1        ,W
    MOVWF    R5+1
;********************************
    MULL32    R5,R5+1,R0,R0+1            ;((value - fS) * (tE - tS))  ;SONUC= XSL-XSH    32BİT
   
    MOVF        R1        ,W                ;    60  62 64  66  68            ADRESLER
    SUBWF    R2        ,W
    MOVWF    R5                        ;        R0  R1 R2  R3  R4            DEĞİŞKENLER
    BTFSS    STATUS    ,C                ;    MAP    SAYI,0,1023,800,2200,R1        HARİTA
    INCF        R1+1        ,F                ;    (1023-0)+800                    İŞLEM
    MOVF        R1+1        ,W                ;    map(value,fS, fE, tS,tE)
    SUBWF    R2+1        ,W
    MOVWF    R5+1                        ;  R2 - R1 + R3
                                    ;((fE - fS) + tS);
    CLRF        R6                                ;SONUÇ = R2
    CLRF        R6+1
    BOL    XSL,XSL+1,XSH,XSH+1,R5,R5+1,R6,R6+1
    MOVF        R3        ,W
    ADDWF    XSL        ,F
    MOVF        R3+1        ,W
    BTFSC    STATUS    ,C
    INCF        XSL+1        ,F
    ADDWF    XSL+1        ,F
    BTFSC    STATUS    ,C
    INCFSZ    XSH
    GOTO    $+2
    INCF        XSH+1
    MOVF        XSL        ,W
    MOVWF    MAP_SNC
    MOVF        XSL+1    ,W
    MOVWF    MAP_SNC+1   
    MOVF        XSH    ,W
    MOVWF    MAP_SNC+2   
    MOVF        XSH    ,W
    MOVWF    MAP_SNC+3       
   
    ENDM   
Hep meraktan

alisumer

#29
yeni bölme fonksiyonu bi kısmı araklama tabi :P işaretli 32 bit sayılarla işlem yapabiliyor 32/32=32 sonucu da 32 bit içinde saklıyor biraz zaman alıyor ama kısaltmanın yolunu buldum gibi deniyorum paylaşırım başarınca.MAP ile ilgili tüm makrolar 32 bit çarpma ve 32 bit bölme makrosundan ibaret.ikisi de aşağıda
;****************************************************************
;* MUL        : 16 x 16 = 32 multiply                           *
;*                                                              *
;* Input      : R3 * R1                                         *
;* Output     : R2, W = low word                                *
;*            : R0, R2 + 1 = mid word                           *
;*            : R0 = high word                                  *
;*                                                              *
;* Notes      :                                                 *
;****************************************************************
MULL32  MACRO   X1,X1+1,X2,X2+1
 
MUL3:       
MOVLW    .16              ; For 16 shifts
        MOVWF    XX
        CLRF    XSH + 1
        CLRF    XSH
mulloop:
BCF STATUS, C
RRF      X1 + 1, F
        RRF      X1, F
        BTFSS    STATUS, C ;
        GOTO    mull1            ; Skip add
        MOVF    X2, W           ; 16-bit add with carry out
        ADDWF    XSH, F
        MOVF    X2 + 1, W
        BTFSC    STATUS, C
        INCFSZ  X2 + 1, W
        ADDWF    XSH + 1, F
mull1:
RRF    XSH + 1, F
        RRF      XSH ,F
        RRF      XSL + 1,F
        RRF      XSL ,F 
        DECFSZ  XX ,F
        GOTO    mulloop
DONE:   
  CLRF X1
  CLRF X1+1
  CLRF X2
  CLRF X2+1
 
          ENDM
               
;****************************************************************
;* DIV        : 16 x 16 (31 x 15) divide                        *
;*                                                              *
;* Input      : R0 / R1                                         *
;* Output     : R0, R0+1  =     bolüm                           *
;*            : R2 = remainder            kalan                     *
;*                                                              *
;* Notes      : R2 = R0 MOD R1                                  *
;****************************************************************
; ----BÖLÜNEN--- ----BÖLEN----
;*** 32 BIT SIGNED DIVIDE ***
;REGA / REGB -> REGA
;Remainder in REGC
;Return carry set if overflow or division by zero
;*** 32 BIT SIGNED DIVIDE ***
;REGA / REGB -> REGA
;Remainder in REGC
;Return carry set if overflow or division by zero
BOL MACRO D0,D1,D2,D3,B0,B1,B2,B3
divide:
clrf DD1 ;Reset sign flag
call absa ;Make dividend (REGA) positive
skpc
call absb ;Make divisor (REGB) positive
skpnc
return ;Overflow
clrf DR0 ;Clear remainder
clrf DR1
clrf DR2
clrf DR3
movlw D'32' ;Loop counter
movwf DD
;call slac ;Purge sign bit
dvloop:
call slac ;Shift dividend (REGA) msb into remainder (REGC)
movf B3,w ;Test if remainder (REGC) >= divisor (REGB)
subwf DR3,w
skpz
goto dtstgt
movf B2,w
subwf DR2,w
skpz
goto dtstgt
movf B1,w
subwf DR1,w
skpz
goto dtstgt
movf B0,w
subwf DR0,w
dtstgt:
skpc ;Carry set if remainder >= divisor
goto dremlt
movf B0,w ;Subtract divisor (REGB) from remainder (REGC)
subwf DR0,f
movf B1,w
skpc
incfsz B1,w
subwf DR1,f
movf B2,w
skpc
incfsz B2,w
subwf DR2,f
movf B3,w
skpc
incfsz B3,w
subwf DR3,f
clrc
bsf D0,0 ;Set quotient bit
dremlt:
decfsz DD,f ;Next
goto dvloop
btfsc DD1,0 ;Check result sign
call negatea ;Negative
GOTO DIVCIK
;/////////////////////////////////////////////////////////////////
absa:
rlf D3,w
skpc
return ;Positive
negatea:
movf D3,w ;Save sign in w
andlw 0x80
comf D0,f ;2's complement
comf D1,f
comf D2,f
comf D3,f
incfsz D0,f
goto nega1
incfsz D1,f
goto nega1
incfsz D2,f
goto nega1
incf D3,f
nega1:
incf DD1,f ;flip sign flag
addwf D3,w ;Return carry set if -2147483648
return
;/////////////////////////////////////////////////////////////////
absb:
rlf B3,w
skpc
return ;Positive
negateb:
movf B3,w ;Save sign in w
andlw 0x80
comf B0,f ;2's complement
comf B1,f
comf B2,f
comf B3,f
incfsz B0,f
goto negb1
incfsz B1,f
goto negb1
incfsz B2,f
goto negb1
incf B3,f
negb1
incf DD1,f ;flip sign flag
addwf B3,w ;Return carry set if -2147483648
return
;///////////////////////////////////////////////////////////
slac:
rlf D0,f
rlf D1,f
rlf D2,f
rlf D3,f
slc:
rlf DR0,f
rlf DR1,f
rlf DR2,f
rlf DR3,f
return
DIVCIK:
ENDM
Hep meraktan

Powered by EzPortal