ASM makro kullanımı ile ilgili bilgiler

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

alisumer

örnek program
    __CONFIG    0x0024
    LIST P = PIC16F690
    INCLUDE "p16f690.inc"
   list r=dec
    INCLUDE "KTPNE.INC"
    #define _C STATUS,0
    #define _Z STATUS,2
    #DEFINE OSC_8
  ; #DEFINE PWM 0X60
 ; #DEFINE KP
;udata
CBLOCK 0X20
SAYI :2
KERE :2
MAP_SNC:4
ENDC
R0 EQU 0X60
R1 EQU 0X62
R2 EQU 0X64
R3 EQU 0X66
R4 EQU 0X68
R5 EQU 0X6A
R6 EQU 0X6C
R7 EQU 0X6E
;BÖLME DEĞİŞLENKERLİ
CBLOCK 0X50
D0
D1
D2
D3
B0
B1
B2
B3
DR0
DR1
DR2
DR3 ;0X5B
DD
DD1 ;0X5D
ENDC
;ÇARPMA DEĞİŞKENLERİ
CBLOCK 0X70
X1 :2
X2 :2
XSL :2
XSH :2
XX
ENDC
    ORG    0X00
    GOTO    AYAR
    ORG        0X04
AYAR:
BANKSEL TRISA
    MOVLW    0x00
    MOVWF    TRISA
    MOVLW    0xFF
    MOVWF    TRISC
    MOVLW    0x00
    MOVWF    TRISB
    MOVLW    0x82
    MOVWF    OPTION_REG
    MOVLW    0x70
    MOVWF    OSCCON
    BCF    STATUS, RP0                        ;BANK0
    MOVLW    0x00
    MOVWF    ADCON0
    MOVLW    0x00
    MOVWF    PORTA
    MOVWF    PORTB
    MOVWF    PORTC
    BSF    STATUS,RP1                        ;BANK2
    MOVLW    0x00
    MOVWF    ANSEL
    MOVLW    0x00
    MOVWF    ANSELH
    BCF    CM1CON0,7
    BCF    CM2CON0,7
    CLRF WPUB
    BSF IOCB ,7
    BANKSEL PSTRCON
    CLRF PSTRCON
    BCF    STATUS,RP1
    BCF    STATUS,RP0                        ;BANK0
  MOVLW 0X00
  MOVWF INTCON
  CLRF PORTA
  CLRF PORTB
  CLRF PORTC
BASLA:
PAKET16 512,SAYI                   ; bu sayı denemelik örneğin analog okumayı simule ediyor
MAP SAYI,,0,1023,0,2000,R1     ;SAYI 2 byte olduğundan sayıdan sonraki iki virgül SAYI+1 yazmamak için
GOTO BASLA
END
Hep meraktan

alisumer

Bölme makrosu biraz daha hızlandı 32 bit için sürekli kaydır çıkar işlemi yapıyordu önceden şu an en değerli basamağı bulana kadar sadece kaydırıyor böylece gereksiz çıkarma işleminden kurtuluyor tabi sayının büyüklüğüne göre süre farkı değişmekle beraber küçük sayılarda neredeyse yarı yarıya hızlanma oluyor ancak bölünen sayı 32 bit değerinde olursa eski makro ile aynı hızda çalışır. ayrıca makroya BOL A,A+1... şeklinde yazma işi de kalktı gerekli reg alanını 4 byte ayarladığınız taktirde ilk register adresini verince 4 byte adresleniyor yani DIV32 A,B yapınca 32 bit /32 bitlik işlem yapabiliyor .
DIV32 MACRO ?,?0          ;? == A,A+1,A+2,A+3
                                      ;?0== B,B+1,B+2,B+3
divide:
clrf DD1 ;Reset sign flag
call absa ;Make dividend (REGA) positive
skpc
call absb ;Make divisor (REGB) positive
skpnc
return ;Overflow
movlw D'33' ;Loop counter
movwf DD
BASAMAK:
CALL TEST
SKPC
GOTO BASAMAK
CALL GERIAL
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 ?0+3,w ;Test if remainder (REGC) >= divisor (REGB)
subwf DR3,w
skpz
goto dtstgt
movf ?0+2,w
subwf DR2,w
skpz
goto dtstgt
movf ?0+1,w
subwf DR1,w
skpz
goto dtstgt
movf ?0,w
subwf DR0,w
dtstgt:
skpc ;Carry set if remainder >= divisor
goto dremlt
movf ?0,w ;Subtract divisor (REGB) from remainder (REGC)
subwf DR0,f
movf ?0+1,w
skpc
incfsz ?0+1,w
subwf DR1,f
movf ?0+2,w
skpc
incfsz ?0+2,w
subwf DR2,f
movf ?0+3,w
skpc
incfsz ?0+3,w
subwf DR3,f
clrc
bsf ? , 0 ;Set quotient bit
dremlt:
decfsz DD,f ;Next
goto dvloop
btfsc DD1,0 ;Check result sign
call negatea ;Negative
GOTO DIVCIK
;/////////////////////////////////////////////////////////////////
absa:
rlf ?+3,w
skpc
return ;Positive
negatea:
movf ?+3,w ;Save sign in w
andlw 0x80
comf ? ,f ;2's complement
comf ?+1 ,f
comf ?+2 ,f
comf ?+3,f
incfsz ? ,f
goto nega1
incfsz ?+1,f
goto nega1
incfsz ?+2,f
goto nega1
incf ?+3,f
nega1:
incf DD1,f ;flip sign flag
addwf ?+3 ,w ;Return carry set if -2147483648
return
;/////////////////////////////////////////////////////////////////
absb:
rlf ?0+3,w
skpc
return ;Positive
negateb:
movf ?0+3,w ;Save sign in w
andlw 0x80
comf ?0 ,f ;2's complement
comf ?0+1,f
comf ?0+2,f
comf ?0+3,f
incfsz ?0,f
goto negb1
incfsz ?0+1,f
goto negb1
incfsz ?0+2,f
goto negb1
incf ?0+3,f
negb1
incf DD1,f ;flip sign flag
addwf ?0+3,w ;Return carry set if -2147483648
return
;///////////////////////////////////////////////////////////
slac:
rlf ?,f
rlf ?+1,f
rlf ?+2,f
rlf ?+3,f
slc:
rlf DR0,f
rlf DR1,f
rlf DR2,f
rlf DR3,f
return
TEST:
DECF DD ,F
rlf ?,f
rlf ?+1,f
rlf ?+2,f
rlf ?+3,f
RETURN
GERIAL:
RRF ?+3,f
RRF ?+2,f
RRF ?+1,f
RRF ? ,f
RETURN
DIVCIK:
ENDM
kullanımı için sonuç A registerine kaydedilir.
CBLOCK 0X20
A :4
B :4
        endc
BASLA:
        DIV32 A,B
        GOTO BASLA
END
Hep meraktan

alisumer

FOR NEXT ve TOGGLE makrosu daha işlevsel hale getirildi.makro içerisinde goto lable komutu ana programda birden fazla  çalıştırıldığında çakışmaya neden olduğundan dallanmalar PCL üzerinden tekrar düzenlendi
TOGGLE MACRO PORT?,?0
MOVLW 0X01<<?0
XORWF PORT? ,F
           ENDM
;////////////////////////////////FOR-NEXTNGÜSÜ///////////////////////////////
;KULLANIMI "FOR 0,255" ; 255 TAKRAR YAPARAK FOR NEXT ARASINDAKİ KODU ÇALIŞTIRIR
; KODLAR
; ......
; NEXT
;*******************************************************************************
FOR MACRO R0,R2
MOVLW R2
MOVWF R4
MOVLW R0
SUBWF R4 ,F
MOVF PCL ,W
MOVWF R9
ENDM
NEXT MACRO
MOVF R9 ,W
DECFSZ R4 ,F
MOVWF PCL
ENDM
çalışma mantığı ile ilgili video ETE hocamın affına sığınarak
Hep meraktan

alisumer

#33
belki de makro kullanımımızı en çok gerektirecek konulara geldik sabit modul ayarları (ADC,UART,SPI vb) gibi ayarların ve okumaların yapıldığı makrolarda sıra. şu an için ADC ve UART makrolarını yaptım hayırlı olsun.
;///////////////////////////////////////////////////////ADC////////////////////////////////////
;kullanımı            ADC_SET  şeklinde olup herhangi bir değişken içermez standart ayarları ana programda define ile belirttiğimiz osc değerine göre otomatik yapar
; //////////////////10 bit sağa yaslı format kullanır .
ADC_SET  MACRO
    BANKSEL    ANSEL            ;BANK2
    CLRF    ANSEL
    CLRF    ANSELH
    ;BANKSEL    ADCON0
    BCF    STATUS    ,RP1
    MOVLW    0X80
    MOVWF    ADCON0   
    IFDEF    OSC_4
    ;BANKSEL    ADCON1
    BSF    STATUS    ,RP0
    MOVLW    B'00010000        ; BÖLME ORANI  OSC YE BAĞLI
    MOVWF    ADCON1
    ENDIF
    IFDEF    OSC_8
    ;BANKSEL    ADCON1
    BSF    STATUS    ,RP0
    MOVLW    B'01010000
    MOVWF    ADCON1
    ENDIF   
    IFDEF    OSC_20
    ;BANKSEL    ADCON1
    BSF    STATUS    ,RP0
    MOVLW    B'00100000
    MOVWF    ADCON1
    IFNDEF   
    BSF    STATUS    ,RP0
    MOVLW    B'01110000
    MOVWF    ADCON1   
    ENDIF
    BCF    STATUS    ,RP0
    ENDM
;*********************** ADC_READ ///////////////////////////////////////
;kullanımı  "ADC_READ pin,değişken" şeklindedir Örnek    "ADC_READ    0,SAYI    "
;analog olarak ayarlanacak bacakların makro dışında tek ayarı bacakların giriş olarak ayarlanmasıdır
ADC_READ MACRO    ?0,?1
    BSF        ADCON0    ,0
    MOVLW        ?0   
    ANDLW    0X0F
    MOVWF    R9
    MOVWF    0X70
    MOVLW    0X01
    BSF        STATUS    ,RP1
    BCF        STATUS    ,C
    MOVWF    ANSEL
    MOVF        0X70        ,W
    BTFSC        STATUS    ,Z
    GOTO        $+5
    RLF        ANSEL        ,F
    RLF        ANSELH    ,F
    DECFSZ    0X70    ,F
    GOTO $-3
    BCF        STATUS    ,RP1
    BCF        STATUS    ,C
    RLF        R9    ,F
    RLF        R9    ,W       
;    BANKSEL    ADCON0
    IORWF        ADCON0
;    BSF        ADCON0    ,0
    FOR    0,4
    NOP
    NOP
    NEXT
    ;PAUSE 1
    BSF        ADCON0    ,1
    BTFSC        ADCON0    ,1        ; bayrak biti okumanın bittiğini kontrol etmek için izlenir
    GOTO    $-1
;    PAUSE    1
    MOVFF    ADRESL,?1
    MOVFF    ADRESH,?1+1
    ENDM
;///////////////////////////////////////////////////////////////////////////////
;///////////////////////UART_SET/////////////////////////////////////////////;
;kullanımı            "UART_SET    230400,8,0"      UART_SET    baud,bit,ters/düz  şeklindedir
;tüm asenkron ayarları makro içerisinde yapar bacakların giriş çıkışları dahil
UART_SET MACRO    VAR,VAR1,VAR2
        BANKSEL TXSTA 
        BCF    TRISB        ,7 ;tx
        BSF    TRISB        ,5   
        MOVLW  0X24              ; TXEN,BRGH
        MOVWF  TXSTA 
        IF    VAR2>0
        BANKSEL    BAUDCTL
        MOVLW    0X18            ;İNVERTED
        MOVWF    BAUDCTL
        ELSE
        BANKSEL    BAUDCTL
        MOVLW    0X08
        MOVWF    BAUDCTL
      ;  CLRF    BAUDCTL            ;NONİNVERTED
        ENDIF        ;
        BANKSEL RCSTA          ;
        MOVLW 0X80            ;SPEN,CREN
        MOVWF RCSTA
        BANKSEL TRISA
        IFDEF    OSC_8
    IF VAR==9600
        MOVLW  .207              ;
        MOVWF  SPBRG
        ENDIF
        IF    VAR==10417
        MOVLW  .191          ;
        MOVWF  SPBRG
        ENDIF 
        IF    VAR==19200
        MOVLW  .103              ;
        MOVWF  SPBRG
        ENDIF 
        IF    VAR==57600
        MOVLW  .34            ;
        MOVWF  SPBRG
        ENDIF
        IF    VAR==115200
        MOVLW  .16          ;
        MOVWF  SPBRG               
    ENDIF
    IF    VAR==230400
        MOVLW  .8        ;
        MOVWF  SPBRG               
    ENDIF
    IF    VAR1==8
    BCF    RCSTA    ,RX9
    ENDIF
    IF    VAR1==9
    BSF    RCSTA    ,RX9
    ENDIF
    ENDIF
    ENDM
;//////////////////////////////PRİNTF///////////////////
;asenkron veri gönderme
PRINTF    MACRO    ?0
    MOVFF    ?0,TXREG
    BSF    STATUS    ,RP0
    BTFSS        TXSTA        ,TRMT        ; gönderimin bitmesi ile kalkan bayrak
    GOTO    $-1
    BCF    STATUS    ,RP0
   
    ENDM
uart kısmı şu an sadece 8 mhz için ayarlandı ifdef bloğu ile diğer frekanslara da uyarlanacak ayrı bir seri iletişim makro dosyasında hepsi toparlanacak şalışma mantığı açısından fikir verebilir.standart dışı olarak 230400 baud hızı eklendi hatasız çalıştı ,ayrıca alma için bir makro yapmadım o biraz daha karışık ama gelecek
Hep meraktan

alisumer

#34
ADXL345 için hazırlanmış 4 kablolu SPI haberleşmesini ayarlayan ve sensörü sürekli ölçüm modunda 10bit, 2g , 100hz de işarette büyüklük ile (eksi ve artı değerleri veren)ayarlayan ve 3  eksen data çıkışını veren iki adet makro
NOT: ana programda define ile CSN bacağı tanımlanmalı.örn= #DEFINE    CSN    PORTC,6
;//////////////////////ADXL345//////// STANDART AYARLAR///////////////////////////
;////////////////////////////////////////////////////////////////////////////////////////////
;
ADXL_BEGIN    MACRO          ;    CSN PORT VE BACAK SEÇİMİ
        BANKSEL    TRISA
    ;    MOVLW    0X10
    ;    IORWF        TRISB    ,F
        BSF        TRISB    ,4
        BCF        TRISB    ,6   
        BCF        TRISC    ,7
        BCF        TRISC    ,6
       
        MOVLW    0XC0
        MOVWF    SSPSTAT
        BANKSEL    SSPCON
        MOVLW    0X30
        MOVWF    SSPCON
       
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN   
        MOVLW    0XFF
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        CALL        ADXL_PAUS100
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN
        MOVLW    0X27
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVLW    0X00
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        BSF        CSN            ;100 HZ DATA ÇIKIŞ HIZI
        CALL        ADXL_PAUS1        ;DOKUNMA SENSÖRÜ İPTAL
        BCF        CSN
        MOVLW    0X2D
        MOVWF    SSPBUF            ;SÜREKLİ ÖLÇÜM MODU
        CALL        ADXL_SEND
        MOVLW    0X08
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN
        MOVLW    0X31                ;2G ÖLÇÜM. / SAĞA YASLI 10 BİT ÇÖZÜNÜRLÜK/4 KABLO SPİ MODU
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVLW    0X00
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        BSF        CSN
        CALL        ADXL_PAUS100
        GOTO        ADXL_EXT   
ADXL_PAUS100:       
              movlw          .186
                movwf          R0
                movlw          .4
                movwf          R1
                movlw          .2
                movwf          R2
                decfsz          R0,F
                goto            $-1
                decfsz          R1,F
                goto            $-3
                decfsz          R2,F
                goto            $-5
        RETURN
ADXL_PAUS1:   
                movlw      .6
                movwf      R0
                decfsz      R0,F
                goto        $-1
                nop
        RETURN
ADXL_SEND:
        BTFSS      PIR1 ,SSPIF
            GOTO        $-1 
            BCF            PIR1  ,SSPIF
            RETURN
ADXL_EXT:
        ENDM   
;******************************************************************************************
;//////////////////ADXL OKUMA///////////////////////////////////////////////////////
;/////////////////ADXL_READ        X,Y,Z   
ADXL_READ MACRO    ?0,?1,?2
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN
        MOVLW    0XB2
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVLW    0X88
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVF        SSPBUF    ,W
        MOVWF    ?0                    ;X
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN
        MOVLW    0XB3
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVLW    0X88
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVF        SSPBUF    ,W
        MOVWF    ?0+1                ;X+1
;YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY   
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN
        MOVLW    0XB4
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVLW    0X88                ;DUMMY       
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVF        SSPBUF    ,W
        MOVWF    ?1                    ;Y
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN
        MOVLW    0XB5
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVLW    0X88
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVF        SSPBUF    ,W
        MOVWF    ?1+1                ;Y+1
;ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ   
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN
        MOVLW    0XB6
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVLW    0X88
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVF        SSPBUF    ,W
        MOVWF    ?2                    ;Z
        BSF        CSN
        CALL        ADXL_PAUS1
        BCF        CSN
        MOVLW    0XB7
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVLW    0X88
        MOVWF    SSPBUF
        CALL        ADXL_SEND
        MOVF        SSPBUF    ,W
        MOVWF    ?2+1                ;Z+1
        BSF        CSN
        CALL        ADXL_PAUS100
        ENDM
kullanımı=
#include    SENSORS.INC
#DEFINE    CSN    PORTC,6
    ADXL_BEGIN
start:
   
    ADXL_READ X,Y,Z
goto start
Hep meraktan

alisumer

#35
S
Hep meraktan

alisumer

#36
Uart haberleşme ve ayar makrolarıdır şu an için sadece osc 8 mhz ayarları mevcut.Ascii gönderme için farklı bir makro da yazdım ascii ile standart gönderme arasındaki farkı da görebilirsiniz basitçe
;///////////////////////////////////////////////////////////////////////////////
;///////////////////////UART_SET/////////////////////////////////////////////
; UART_SET BAUD,9OR8,TERS-DÜZ
;    UART_SET 9600,8,0
UART_SET MACRO    VAR,VAR1,VAR2
        BANKSEL TXSTA 
        BCF    TRISB        ,7 ;tx
        BSF    TRISB        ,5   
        MOVLW  0X24               ; TXEN,BRGH
        MOVWF  TXSTA  
        IF    VAR2>0
        BANKSEL    BAUDCTL
        MOVLW    0X18            ;İNVERTED
        MOVWF    BAUDCTL
        ELSE
        BANKSEL    BAUDCTL
        MOVLW    0X08
        MOVWF    BAUDCTL
      ;  CLRF    BAUDCTL            ;NONİNVERTED
        ENDIF         ;
        BANKSEL RCSTA           ;
        MOVLW 0X80            ;SPEN,CREN
        MOVWF RCSTA
        BANKSEL TRISA
       
        IFDEF    OSC_8
        IF VAR==9600
        MOVLW  .207              ;
        MOVWF  SPBRG
        BANKSEL    PORTA
        ENDIF
        IF    VAR==10417
         MOVLW  .191           ;
        MOVWF  SPBRG
        BANKSEL    PORTA
        ENDIF  
        IF    VAR==19200
         MOVLW  .103              ;
        MOVWF  SPBRG
        BANKSEL    PORTA
        ENDIF 
        IF    VAR==57600
         MOVLW  .34            ;
        MOVWF  SPBRG
        BANKSEL    PORTA
        ENDIF
        IF    VAR==115200
         MOVLW  .16           ;
        MOVWF  SPBRG
        BANKSEL    PORTA                
        ENDIF
        IF    VAR==230400
         MOVLW  .8         ;
        MOVWF  SPBRG 
        BANKSEL    PORTA              
        ENDIF
        IF    VAR1==8
        BCF    RCSTA    ,RX9
        ENDIF
        IF    VAR1==9
        BSF    RCSTA    ,RX9
        ENDIF
        ENDIF
        ENDM
;//////////////////////////////PRİNTF///////////////////UART HABERLEŞME SERİ GÖNDERME
PRINTF    MACRO    ?0
        BANKSEL    PORTA
        BTFSC    INTCON    ,GIE
        GOTO    $+2
        GOTO    $+3
        BCF        INTCON    ,7
        BSF        R9        ,0
   
        MOVF    ?0,W
        MOVWF    TXREG
        BSF        STATUS    ,RP0
        BTFSS    TXSTA    ,TRMT
        GOTO    $-1
        BCF        STATUS    ,RP0
   
        MOVF    ?0+1,W
        MOVWF    TXREG
        BSF        STATUS    ,RP0
        BTFSS    TXSTA    ,TRMT
        GOTO    $-1
        BCF        STATUS    ,RP0
       
               
        MOVLW    .13
        MOVWF    TXREG
        BSF        STATUS    ,RP0
        BTFSS    TXSTA    ,TRMT
        GOTO    $-1
        BCF        STATUS    ,RP0
       
        BTFSC    R9    ,0
        BSF        INTCON    ,7
        ENDM
;////////////////////////////ASCİİ  GÖNDERME//////////////////////////////
PRINTA    MACRO    ?0
           
        BANKSEL    PORTA
        BTFSC    INTCON    ,GIE
        GOTO    $+2
        GOTO    $+3
        BCF        INTCON    ,7
        BSF        R9        ,0
   
   
        MOVLW    ?0
        MOVWF    TXREG
        BSF        STATUS    ,RP0
        BTFSS    TXSTA    ,TRMT
        GOTO    $-1
        BCF        STATUS    ,RP0           
        BTFSC    R9    ,0
        BSF        INTCON    ,7
ENDM   



Hep meraktan

alisumer

#37
Alıntı yapılan: alisumer - 13 Nisan 2023, 23:07:40FOR NEXT ve TOGGLE makrosu daha işlevsel hale getirildi.makro içerisinde goto lable komutu ana programda birden fazla  çalıştırıldığında çakışmaya neden olduğundan dallanmalar PCL üzerinden tekrar düzenlendi
TOGGLE    MACRO    PORT?,?0
        MOVLW    0X01<<?0
        XORWF    PORT?    ,F
           ENDM
;////////////////////////////////FOR-NEXTNGÜSÜ///////////////////////////////
;KULLANIMI    "FOR 0,255"        ; 255 TAKRAR YAPARAK FOR NEXT ARASINDAKİ KODU ÇALIŞTIRIR
;            KODLAR
;            ......
;            NEXT
;*******************************************************************************
FOR    MACRO    R0,R2
        MOVLW    R2    
        MOVWF    R4
        MOVLW    R0   
        SUBWF    R4        ,F
        MOVF        PCL    ,W
        MOVWF    R9
        ENDM       
NEXT    MACRO       
        MOVF        R9    ,W
        DECFSZ    R4    ,F
        MOVWF    PCL
        ENDM   
çalışma mantığı ile ilgili video ETE hocamın affına sığınarak
düzeltme goto lable komutu aslında olabiliyormuş yöntemi ise makro içerisinde lokal kalmasını yani genel programa etki etmesini istemediğimiz değişken veya lable leri "local lable,var..." şeklinde yazdığımızda makroda kullandığımız değişkenler ve lable adresleri ana programda değişikliğe neden olmaz makrodan çıkıldıktan sonra aynı makroyu tekrar çalıştırdığımızda farklı PC numarası alır yani çakışma olmaz biraz karışık anlattım sanırım örnek vereyim
;////////////////////////////////FOR-NEXTNGÜSÜ///////////////////////////////
;KULLANIMI    "FOR 0,255"        ; 255 TAKRAR YAPARAK FOR NEXT ARASINDAKİ KODU ÇALIŞTIRIR
;            KODLAR
;            ......
;            NEXT
;*******************************************************************************
FOR    MACRO    ?0,?1  ;R10,R11
    LOCAL for1
        MOVLW    ?1 ;R11    
        MOVWF    R12
        MOVLW    ?0 ;R10   
        SUBWF    R12 ,F
        ;MOVF    PCL    ,W
        ;MOVWF    R13
for1:
        ENDM       
NEXT    MACRO         
        MOVF    R13 ,W
        DECFSZ  R12   
        goto for1;MOVWF   PCL
 
        ENDM
makroda ilk hali ve ikinci hali aynı anda var yorum yaptım sadece kod birkaç komut kısaldı daha iyi oldu.makro içindeki değişkenleri de ? şeklinde yapıp gereksiz atama derdinden kurtulduk ordanda iki üç kazanç var
Hep meraktan

alisumer

şimdi ise daha önce yazdığım tüm matematik kütüphanelerini bir kenara brakıp yeni bir makro yazdım sebebi ise tüm işlemlerin farklı değişkenlerde tutulma zorunluluğuydu(beceremediğimden tabi:) ) çok yer tutuyor fakat çok hızlı işlem yapıyorlardı bunun yerine http://www.piclist.com/tecHREF/microchip/index.htm sitesinde yazılı hazır kütüphanelerin iş görürlerini makroma adapte ettim böylelikle tüm işlemler için farklı değişkenler tanımlamak zorunluluğum kalktı kodlar biraz yavaşladı ama sorunsuz çalıştılar ne de olsa yazanlar asm nin kralları sayılır.bu deneme programı
__CONFIG 0x30E4
radix dec
    LIST P = PIC16f690 
    INCLUDE "p16f690.inc"
;    INCLUDE "EPROM.INC"
    INCLUDE "MATH.INC"
;    INCLUDE "fload.inc"
    RADIX DEC
    extern  REGA0,REGB0,REGC0,subtract,add,multiply,divide,clrba,sqrt,DCOUNT,DCOUNT
;
; GLOBAL MAPS
; EXTERN FLO1624,INT2416,FPM24,FLO2424;R0,R1,R2,R3,R4,DIZ0,DIZ1,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,R16,R17,D0,D1,D2,D3,DS,DR,M0,M1,M2,MS,IF0,IF1,F0,F1,DIV32L
; ENDC
VAR UDATA 0X20
X   RES 4 
Y   RES 4
ZB  RES 4
DIG RES 10
_TMP0   EQU 0X70
_TMP1   EQU 0X71
_TMP2   EQU 0X72
ORG 0X00
GOTO AYAR
ORG 0X04
AYAR:
PAKET32 301 ,X
PAKET32 302  ,Y
BASLA:
;   TOPLA32   X,Y,ZB;
;   DIV32  X,Y,ZB
;   KAREKOK X,ZB
;   MULL32 X,Y,ZB
;   BCD  X,DIG
;   DIV32 ZB,Y,ZB
EGER    X,"Z",Y
    GOTO $+2
HESAP:
GOTO BASLA
    GOTO BASLA
        END
       

yorum larını kaldırırsanız tek tek deneme imkanınız olur
Hep meraktan

alisumer

bbu makro kodları (math.inc)
;//////////////// RAM ADRESİNDEN RAM ADRESİNE VERİ TRANSFERİ TAŞIMA ////////////////
;1 BYTE KULLANIMI= MOVFF A,B
;2 BYTE KULLANIMI= MIVFF16 A,B
;4 BYTE KULLANIMI= MIVFF32 A,B
;MOVFFL MAKROSU FARKLI BANKLARDA BULUNAN REGİSTERLER ARASINDA TAŞIMA YAPAR
MOVFF MACRO ?0,?1
MOVF ?0 ,W
MOVWF ?1
ENDM
MOVFF16 MACRO ?0,?1
MOVF ?0 ,W
MOVWF ?1
MOVF (?0+1) ,W
MOVWF ?1+1
ENDM
MOVFF32 MACRO ?0,?1
MOVF ?0 ,W
MOVWF ?1
MOVF ?0+1 ,W
MOVWF ?1+1
MOVF ?0+2 ,W
MOVWF ?1+2
MOVF ?0+3 ,W
MOVWF ?1+3
ENDM
MOVFFL MACRO ?0,?1
    BANKSEL ?0
    MOVF    ?0  ,W
    BANKSEL ?1
    MOVWF   ?1
    BANKSEL ?0
    ENDM
MOVFF16L MACRO ?0,?1
    BANKSEL ?0
    MOVF    ?0  ,W
    BANKSEL ?1
    MOVWF   ?1
    BANKSEL ?0
    MOVF    ?0+1 ,W
    BANKSEL ?1
    MOVWF   ?1+1
    BANKSEL ?0
    ENDM
MOVFF32L MACRO ?0,?1
    BANKSEL ?0
    MOVF    ?0  ,W
    BANKSEL ?1
    MOVWF   ?1
    BANKSEL ?0
    MOVF    ?0+1 ,W             ;26 KOMUT
    BANKSEL ?1
    MOVWF   ?1+1
    BANKSEL ?0
    MOVF    ?0+2    ,W
    BANKSEL ?1
    MOVWF   ?1+2
    BANKSEL ?0
    MOVF    ?0+3    ,W
    BANKSEL ?1
    MOVWF   ?1+3
    BANKSEL ?0
    ENDM
 ;///////////////////////////32 BİT İARETLİ SABİT YAZMA//////////////////
;ÖRNEK= PAKET32 12345678,Out0 ; PAKET32 -12345678,Out0 yazıldığında da negatif değeri yazabilir adreslere
;RADIX DEC YAPILMALI DESİMAL SAYILAR İÇİN
;///////////////////////////////////////////////////////////////////////////////////////////////
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 
;////////////////////16 BİT PAKET DEĞİŞKENLERE YAZILMASI///////////////////////////////////////////////
PAKET16 MACRO VAR,ADDRESS
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
ENDM
;/////////////////////////////////MATEMATİK İŞLEMLERİ (4 İŞLEM)///////////////////////////////////
;//////////////////////////////KULLANIMI İÇİN MATH.ASM TANITILMALI////////////////////////////////
;///////////////KULLANIMI TOPLA A,B,C ŞEKLİNDE A İLE B TOPLANIR C YE YAZILIR//////////////////////
;BÖLME İŞLEMİNDE KALAN HATILATICI OLARAK KULLANILAN REGC DE TUTULUT SONUÇ İSE GENE A/B=C ŞEKLİNDEDİR
;//////32BİT İŞARETLİ TOPLAMA////
TOPLA32 MACRO ?0,?1,?2
MOVFF32 ?0,REGA0
MOVFF32 ?1,REGB0
CALL    add
MOVFF32 REGA0,?2
;CALL    clrba
    ENDM
;//////32BİT ÇARPMA İŞARETLİ/////
MULL32 MACRO ?0,?1,?2
MOVFF32 ?0,REGA0
MOVFF32 ?1,REGB0
CALL   multiply
MOVFF32 REGA0,?2
ENDM
;///////32BİT İŞARETLİ BÖLME////
DIV32 MACRO ?0,?1,?2
MOVFF32 ?0,REGA0
MOVFF32 ?1,REGB0
    CALL    divide
MOVFF32 REGA0,?2
    ENDM
;///////KAREKÖK alma/////////
KAREKOK MACRO ?0,?2
MOVFF32 ?0,REGA0
    CALL    sqrt
MOVFF32 REGA0,?2
ENDM
;////////BCD ÇEVİRİCİ/////////////
BCD MACRO ?0,?1
MOVFF32 ?0,REGA0
CALL bin2dec
ENDM
;////////////////////////////////////////////////////////////////////////////
;//////////////////////////////////////////////////////////////////////////////
;///////////////////////////BİR BİTİ TERSLER/////////////////////////////
;ÖRNEK= TOGGLE PORTA,5
;/////////////////////////////////////////////////////////////////////
TOGGLE MACRO PORT? ,?0
MOVLW 0X01<<?0
XORWF PORT? ,F
           ENDM
;////////////////////////////////FOR-NEXT DÖNGÜSÜ///////////////////////////////
;KULLANIMI "FOR 0,255" ; 255 TAKRAR YAPARAK FOR NEXT ARASINDAKİ KODU ÇALIŞTIRIR
; KODLAR
; ......
; NEXT
;*******************************************************************************
FOR MACRO ?0,?1  ;R10,R11
    local for1
MOVLW ?1 ;R11
MOVWF R12
MOVLW ?0 ;R10
SUBWF R12 ,F
;MOVF PCL ,W
;MOVWF R13
for1:
ENDM
NEXT MACRO  
MOVF R13 ,W
DECFSZ  R12
    goto for1;MOVWF   PCL
 
ENDM
;//////////////////////////////IF-THEN KOŞULLARI////////////////////////////////////
;KULLANIMI (EGER A,"<",B) KOMUT KARŞILIĞINDA KOŞUL DOĞRU İSE İKİ ALT SATIRA YANLIŞSA BİR ALT SATIRA GİDER
;          (EGER A,"Z",B) A KÜÇÜK EŞİTSE ( Z İŞARETİ KÜÇÜK EŞİT İŞARETİNE EN ÇOK BENZEDİĞİ İÇİN SEÇİLDİ)
;          (EGER A,"=",B) A VE B EŞİTSE
;///////////////////DEĞER KIYASLAMASI//////////////////////////////////
;KULLANIMI= KARŞILAŞTIRILACAK HER BİR "WORD" DEĞERİ ARDIŞIK RAM BÖLGELERİNDE TUTULMALI
;R15 VE R16 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
;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 "R4" , 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
EGER MACRO ?0,?2,?1;,?2
BCF STATUS ,C
BCF STATUS ,Z
; MOVF ?0 ,W
; MOVWF R15         ;R0
; MOVF ?0+1 ,W
; MOVWF R15+1       ;R0+1
; MOVF ?1 ,W
; MOVWF R16         ;R3
; MOVF ?1+1 ,W
; MOVWF R16+1       ;R3+1
IF ?2=="<" ;????????
MOVF ?0+1   ,W  ;R0+1 ,W ;IF Y <= ART THEN GOTO KAPA
SUBWF ?1+1   ,W  ;R3+1 ,W ;
BTFSS STATUS ,C ;
GOTO $+6
BTFSS       STATUS  ,Z
GOTO        $+5
MOVF ?0     ,W  ;R0 ,W
SUBWF ?1     ,W  ;R3 ,W
BTFSS STATUS ,C
ELSE
; IF   R1 == "<" && R2 == .32
IF ?2=="Z"
MOVF ?0+1 ,W ;IF Y < ART THEN
SUBWF ?1+1 ,W ;
BTFSS STATUS ,C ;
GOTO $+8
BTFSS STATUS ,Z
GOTO $+7
MOVF ?0 ,W
SUBWF ?1 ,W
BTFSC STATUS ,Z
GOTO $+3
BTFSS STATUS ,C
ELSE
IF ?2=="="
; IF R1 == .61 && R2 == .32
MOVF ?0+1 ,W
XORWF ?1+1 ,W
BTFSS STATUS ,Z
GOTO $+5
MOVF ?0 ,W
XORWF ?1 ,W
BTFSC STATUS ,Z
GOTO $+2
ENDIF
ENDIF
ENDIF
ENDM
Hep meraktan

alisumer

#40
buda kütüphane dosyası (sub.asm) math.asm
       INCLUDE "p16f690.inc"
INCLUDE "MATH.INC"
UDATA 0X56
REGA0   RES 1                ;lsb
REGA1   RES 1
REGA2   RES 1
REGA3    RES 1            ;msb
REGB0    RES 1            ;lsb
REGB1   RES 1
REGB2   RES 1
REGB3    RES 1                ;msb
REGC0    RES 1            ;lsb
REGC1   RES 1
REGC2   RES 1
REGC3    RES 1            ;msb
DSIGN    RES 1            ;Digit Sign. 0=positive,1=negative
;DIGIT1    RES 1            ;MSD
;DIGIT2  RES 1
;DIGIT3  RES 1
;DIGIT4  RES 1
;DIGIT5    RES 1                ;Decimal (BCD) digits
;DIGIT6  RES 1
;DIGIT7  RES 1
;DIGIT8  RES 1
;DIGIT9  RES 1
;DIGIT10    RES 1            ;LSD
MTEMP   RES 1
MCOUNT  RES 1
DCOUNT  RES 1
;*** 32 BIT SIGNED SUTRACT ***
;REGA - REGB -> REGA
;Return carry set if overflow
    GLOBAL REGA0,REGB0,REGC0,subtract,add,multiply,divide,clrba,sqrt,DCOUNT,DCOUNT
CODE
subtract:
    call    negateb        ;Negate REGB
    skpnc
    return            ;Overflow
;*** 32 BIT SIGNED ADD ***
;REGA + REGB -> REGA
;Return carry set if overflow
add:
    movf    REGA3,w        ;Compare signs
    xorwf    REGB3,w
    movwf    MTEMP
    call    addba        ;Add REGB to REGA
    clrc            ;Check signs
    movf    REGB3,w        ;If signs are same
    xorwf    REGA3,w        ;so must result sign
    btfss    MTEMP,7        ;else overflow
    addlw    0x80
    return
;*** 32 BIT SIGNED MULTIPLY ***
;REGA * REGB -> REGA
;Return carry set if overflow
multiply:
    clrf    MTEMP        ;Reset sign flag
    call    absa        ;Make REGA positive
    skpc
    call    absb        ;Make REGB positive
    skpnc
    return                ;Overflow
    call    movac        ;Move REGA to REGC
    call    clra        ;Clear product
    movlw    D'31'        ;Loop counter
    movwf    MCOUNT
muloop:   
    call    slac        ;Shift left product and multiplicand
   
    rlf    REGC3,w            ;Test MSB of multiplicand
    skpnc                ;If multiplicand bit is a 1 then
    call    addba        ;add multiplier to product
    skpc                ;Check for overflow
    rlf    REGA3,w
    skpnc
    return
    decfsz    MCOUNT,f    ;Next
    goto    muloop
    btfsc    MTEMP,0        ;Check result sign
    call    negatea        ;Negative
    return
;*** 32 BIT SIGNED DIVIDE ***
;REGA / REGB -> REGA
;Remainder in REGC
;Return carry set if overflow or division by zero
divide:
    clrf    MTEMP        ;Reset sign flag
    movf    REGB0,w        ;Trap division by zero
    iorwf    REGB1,w
    iorwf    REGB2,w
    iorwf    REGB3,w
    sublw    0
    skpc
    call    absa        ;Make dividend (REGA) positive
    skpc
    call    absb        ;Make divisor (REGB) positive
    skpnc
    return                ;Overflow
    clrf    REGC0        ;Clear remainder
    clrf    REGC1
    clrf    REGC2
    clrf    REGC3
    call    slac        ;Purge sign bit
    movlw    D'31'        ;Loop counter
    movwf    MCOUNT
dvloop:
    call    slac        ;Shift dividend (REGA) msb into remainder (REGC)
    movf    REGB3,w        ;Test if remainder (REGC) >= divisor (REGB)
    subwf    REGC3,w
    skpz
    goto    dtstgt
    movf    REGB2,w
    subwf    REGC2,w
    skpz
    goto    dtstgt
    movf    REGB1,w
    subwf    REGC1,w
    skpz
    goto    dtstgt
    movf    REGB0,w
    subwf    REGC0,w
dtstgt:
    skpc                ;Carry set if remainder >= divisor
    goto    dremlt
    movf    REGB0,w        ;Subtract divisor (REGB) from remainder (REGC)
    subwf    REGC0,f
    movf    REGB1,w
    skpc
    incfsz    REGB1,w
    subwf    REGC1,f
    movf    REGB2,w
    skpc
    incfsz    REGB2,w
    subwf    REGC2,f
    movf    REGB3,w
    skpc
    incfsz    REGB3,w
    subwf    REGC3,f
    clrc
    bsf    REGA0,0        ;Set quotient bit
dremlt:
    decfsz    MCOUNT,f    ;Next
    goto    dvloop
    btfsc    MTEMP,0        ;Check result sign
    call    negatea        ;Negative
    return
;*** ROUND RESULT OF DIVISION TO NEAREST INTEGER ***
round:
    clrf    MTEMP        ;Reset sign flag
    call    absa        ;Make positive
    clrc
    call    slc        ;Multiply remainder by 2
    movf    REGB3,w        ;Test if remainder (REGC) >= divisor (REGB)
    subwf    REGC3,w
    skpz
    goto    rtstgt
    movf    REGB2,w
    subwf    REGC2,w
    skpz
    goto    dtstgt
    movf    REGB1,w
    subwf    REGC1,w
    skpz
    goto    rtstgt
    movf    REGB0,w
    subwf    REGC0,w
rtstgt:
    skpc            ;Carry set if remainder >= divisor
    goto    rremlt
    incfsz    REGA0,f        ;Add 1 to quotient
    goto    rremlt
    incfsz    REGA1,f
    goto    rremlt
    incfsz    REGA2,f
    goto    rremlt
    incf    REGA3,f
    skpnz
    return            ;Overflow,return carry set
rremlt:
    btfsc    MTEMP,0        ;Restore sign
    call    negatea
    return
;*** 32 BIT SQUARE ROOT ***
;sqrt(REGA) -> REGA
;Return carry set if negative
sqrt:
    rlf    REGA3,w        ;Trap negative values
    skpnc
    return
    call    movac        ;Move REGA to REGC
    call    clrba        ;Clear remainder (REGB) and root (REGA)
    movlw    D'16'        ;Loop counter
    movwf    MCOUNT
sqloop:
    rlf    REGC0,f        ;Shift two msb's
    rlf    REGC1,f        ;into remainder
    rlf    REGC2,f
    rlf    REGC3,f
    rlf    REGB0,f
    rlf    REGB1,f
    rlf    REGB2,f
    rlf    REGC0,f
    rlf    REGC1,f
    rlf    REGC2,f
    rlf    REGC3,f
    rlf    REGB0,f
    rlf    REGB1,f
    rlf    REGB2,f
    setc            ;Add 1 to root
    rlf    REGA0,f        ;Align root
    rlf    REGA1,f
    rlf    REGA2,f
    movf    REGA2,w        ;Test if remdr (REGB) >= root (REGA)
    subwf    REGB2,w
    skpz
    goto    ststgt
    movf    REGA1,w
    subwf    REGB1,w
    skpz
    goto    ststgt
    movf    REGA0,w
    subwf    REGB0,w
ststgt:
    skpc            ;Carry set if remdr >= root
    goto    sremlt
    movf    REGA0,w        ;Subtract root (REGA) from remdr (REGB)
    subwf    REGB0,f
    movf    REGA1,w
    skpc
    incfsz    REGA1,w
    subwf    REGB1,f
    movf    REGA2,w
    skpc
    incfsz    REGA2,w
    subwf    REGB2,f
    bsf    REGA0,1        ;Set current root bit
sremlt:
    bcf    REGA0,0        ;Clear test bit
    decfsz    MCOUNT,f    ;Next
    goto    sqloop
    clrc
    rrf    REGA2,f        ;Adjust root alignment
    rrf    REGA1,f
    rrf    REGA0,f
    return
;*** 32 BIT SIGNED BINARY TO DECIMAL ***
;REGA -> DIGITS 1 (MSD) TO 10 (LSD) & DSIGN
;DSIGN = 0 if REGA is positive, 1 if negative
;Return carry set if overflow
;Uses FSR register
;bin2dec:   
;    clrf    MTEMP        ;Reset sign flag
;    call    absa        ;Make REGA positive
;    skpnc
;    return                ;Overflow
;    call    clrdig        ;Clear all digits
;    movlw    D'32'        ;Loop counter
;    movwf    MCOUNT
;b2dloop:   
;    rlf    REGA0,f        ;Shift msb into carry
;    rlf    REGA1,f
;    rlf    REGA2,f
;    rlf    REGA3,f
;    movlw    DIGIT10
;    movwf    FSR        ;Pointer to digits
;    movlw    D'10'        ;10 digits to do
;    movwf    DCOUNT
;adjlp:
;    rlf    INDF,f        ;Shift digit and carry 1 bit left
;    movlw    D'10'
;    subwf    INDF,w        ;Check and adjust for decimal overflow
;    skpnc
;    movwf    INDF
;    decf    FSR,f        ;Next digit
;    decfsz    DCOUNT,f
;    goto    adjlp
;    decfsz    MCOUNT,f    ;Next bit
;    goto    b2dloop
;    btfsc    MTEMP,0        ;Check sign
;    bsf    DSIGN,0        ;Negative
;    clrc
;    return
;
;
;;*** 32 BIT SIGNED DECIMAL TO BINARY ***
;;Decimal DIGIT1 thro DIGIT(X) & DSIGN -> REGA
;;Set DSIGN = 0 for positive, DSIGN = 1 for negative values
;;Most significant digit in DIGIT1
;;Enter this routine with digit count in w register
;;Return carry set if overflow
;;Uses FSR register
;
;dec2bin:   
;    movwf    MTEMP        ;Save digit count
;    movlw    D'32'        ;Outer bit loop counter
;    movwf    MCOUNT
;
;d2blp1:   
;    movlw    DIGIT1-1    ;Set up pointer to MSD
;    movwf    FSR
;    movf    MTEMP,w        ;Inner digit loop counter
;    movwf    DCOUNT
;
;    movlw    D'10'
;    clrc            ;Bring in '0' bit into MSD
;
;d2blp2:   
;    incf    FSR,f
;    skpnc
;    addwf    INDF,f        ;Add 10 if '1' bit from prev digit
;    rrf    INDF,f        ;Shift out LSB of digit
;
;    decfsz    DCOUNT,f    ;Next L.S. Digit
;    goto    d2blp2
;
;    rrf    REGA3,f        ;Shift in carry from digits
;    rrf    REGA2,f
;    rrf    REGA1,f
;    rrf    REGA0,f
;
;    decfsz    MCOUNT,f    ;Next bit
;    goto    d2blp1
;
;    movf    INDF,w        ;Check for overflow
;    addlw    0xFF
;    skpc
;    rlf    REGA3,w
;    skpnc
;    return
;
;    btfsc    DSIGN,0        ;Check result sign
;    call    negatea        ;Negative
;    return
;
;
;UTILITY ROUTINES
;Add REGB to REGA (Unsigned)
;Used by add, multiply,
addba:   
    movf    REGB0,w        ;Add lo byte
    addwf    REGA0,f
    movf    REGB1,w        ;Add mid-lo byte
    skpnc            ;No carry_in, so just add
    incfsz    REGB1,w        ;Add carry_in to REGB
    addwf    REGA1,f        ;Add and propagate carry_out
    movf    REGB2,w        ;Add mid-hi byte
    skpnc
    incfsz    REGB2,w
    addwf    REGA2,f
    movf    REGB3,w        ;Add hi byte
    skpnc
    incfsz    REGB3,w
    addwf    REGA3,f
    return
;Move REGA to REGC
;Used by multiply, sqrt
movac:   
    movf    REGA0,w
    movwf    REGC0
    movf    REGA1,w
    movwf    REGC1
    movf    REGA2,w
    movwf    REGC2
    movf    REGA3,w
    movwf    REGC3
    return
;Clear REGB and REGA
;Used by sqrt
clrba:   
    clrf    REGB0
    clrf    REGB1
    clrf    REGB2
    clrf    REGB3
;Clear REGA
;Used by multiply, sqrt
clra:   
    clrf    REGA0
    clrf    REGA1
    clrf    REGA2
    clrf    REGA3
    return
;Check sign of REGA and convert negative to positive
;Used by multiply, divide, bin2dec, round
absa:   
    rlf    REGA3,w
    skpc
    return            ;Positive
;Negate REGA
;Used by absa, multiply, divide, bin2dec, dec2bin, round
negatea:   
    movf    REGA3,w        ;Save sign in w
    andlw    0x80
    comf    REGA0,f        ;2's complement
    comf    REGA1,f
    comf    REGA2,f
    comf    REGA3,f
    incfsz    REGA0,f
    goto    nega1
    incfsz    REGA1,f
    goto    nega1
    incfsz    REGA2,f
    goto    nega1
    incf    REGA3,f
nega1:
    incf    MTEMP,f        ;flip sign flag
    addwf    REGA3,w        ;Return carry set if -2147483648
    return
;Check sign of REGB and convert negative to positive
;Used by multiply, divide
absb:   
    rlf    REGB3,w
    skpc
    return            ;Positive
;Negate REGB
;Used by absb, subtract, multiply, divide
negateb:   
    movf    REGB3,w        ;Save sign in w
    andlw    0x80
    comf    REGB0,f        ;2's complement
    comf    REGB1,f
    comf    REGB2,f
    comf    REGB3,f
    incfsz    REGB0,f
    goto    negb1
    incfsz    REGB1,f
    goto    negb1
    incfsz    REGB2,f
    goto    negb1
    incf    REGB3,f
negb1:
    incf    MTEMP,f        ;flip sign flag
    addwf    REGB3,w        ;Return carry set if -2147483648
    return
;Shift left REGA and REGC
;Used by multiply, divide, round
slac:   
    rlf    REGA0,f
    rlf    REGA1,f
    rlf    REGA2,f
    rlf    REGA3,f
slc:       
    rlf    REGC0,f
    rlf    REGC1,f
    rlf    REGC2,f
    rlf    REGC3,f
    return
;Set all digits to 0
;Used by bin2dec
;
;clrdig:   
;    clrf    DSIGN
;    clrf    DIGIT1
;    clrf    DIGIT2
;    clrf    DIGIT3
;    clrf    DIGIT4
;    clrf    DIGIT5
;    clrf    DIGIT6
;    clrf    DIGIT7
;    clrf    DIGIT8
;    clrf    DIGIT9
;    clrf    DIGIT10
;    return
    END
kütüphanedeki BCD işlemi için girilen kodları yorum yaptım kullanmadığımdan lazım olan açıp kullanabilir 10 basamak binary decimal dönüşümünü yapıyor.bcd için kullanılan değişkenleri Global satırına eklemeniz gerekiyor ana programda da external satırına ekleyiniz
Hep meraktan

alisumer

#41
bir değişkenin ard arda değerlerinin bir başka byte uzunluğunu kendimizin belirlediği bir "dizi değişkene" kaydetmeye yarayan makrodur
kullanım amacı genellikle Adxl tarzı bir sensörden okunan ard arda verilerin sıralı adreslere sırası ile kaydedilmesine yarar .ortalama almak yada data loger yapmak için kullanılabilir.kullanımına Örnek:
CBLOCK;Yada UDATA
DIZI :10 ;10 Byte uzunluğunda değişken
endc
SAYAC EQU 0X73 ;Her banktan ulaşılabilir olması için sayaç değişkenleri 0x70 üstüne yazılıyor
......
clrf SAYAC
......
ADXL_OKU:
......
movwf A
DIZ A,DIZI,10
GOTO ADXL_OKU
GOTO OKUMA_TAMAM
makro kodu ise:
DIZ MACRO  ?0,?1,?2          ;?2 = kayıt sayısı
                            ;?1 = kayıt yapılan dizi değişkeni ilk adresi yada adı
        MOVLW  ?1          ;?0 = kaydedeceğimiz değişken
        ADDWF  SAYAC ,W
        MOVWF  FSR
        MOVFF  ?0,INDF
        INCF    SAYAC ,F
        MOVF    SAYAC ,W
        XORLW  ?2 
        BTFSS  STATUS ,Z
        GOTO    $+3
        CLRF    SAYAC
        GOTO    $+2
       
        ENDM
       
belirttiğimiz sayı adedince kayıt yapılınca verdiğimiz komutun iki altına  eğer verdiğimiz sayı kadar kayıt yapılmamışsa bir alt satıra gider Aynı BTFSS gibi
Hep meraktan

alisumer

Aynı makronun değişkenimizin 16 bit olması halinde çalışan iki bytelik versiyonu
DIZ16 MACRO ?0,?1,?2
        MOVLW   ?1
        ADDWF   SAYAC   ,W
        MOVWF   FSR
        MOVFF   ?0,INDF
        INCF    FSR ,F
        MOVFF   ?0+1,INDF
        INCF    SAYAC
        INCF    SAYAC
        MOVF    SAYAC   ,W
        XORLW   ?2
        BTFSS   STATUS ,Z
        GOTO    $+3
        CLRF    SAYAC
        GOTO    $+2       
        ENDM
kaç değer kaydedeceğimizi girdiğimiz değer doğal olarak yarı boyutta kayıt yapacaktır yani 10 tane 1 Byte değer yazarken artık 5 tane 2 byte değer sığdırabiliriz aynı adreslere doğal olarak önemli olan kayıt adedi ise DIZ16 komutunda sayı değerimiz de iki kat artmalı
Hep meraktan

alisumer

yeni makro dizi değişkendeki belli sayıda değerin en küçüğünü dizinin en başına taşır yer değiştirir. art arda çalıştırıldığında MEDIAN filtre( bir dizi değerin orta noktasını bulma) uygulamalarında iş görür.Örnek kodu:
    __CONFIG    0x30E4
    radix    dec
      LIST P = PIC16f690 
      INCLUDE "p16f690.inc"
;      INCLUDE "EPROM.INC"   
      INCLUDE "MATH.INC"
;    INCLUDE "fload.inc"
 
      RADIX    DEC
    extern  REGA0,REGB0,REGC0,subtract,add,multiply,divide,clrba,sqrt,DCOUNT,DCOUNT,subtract
;
    ;    GLOBAL    SAYAC
;    EXTERN FLO1624,INT2416,FPM24,FLO2424;R0,R1,R2,R3,R4,DIZ0,DIZ1,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,R16,R17,D0,D1,D2,D3,DS,DR,M0,M1,M2,MS,IF0,IF1,F0,F1,DIV32L
 
;        ENDC
VAR UDATA 0X20
X  RES 4 
Y  RES 4
ZB  RES 4
DIG RES 20
_TMP0  EQU 0X70
_TMP1  EQU 0X71
_TMP2  EQU 0X72
SAYAC  EQU 0X73
RAM0    EQU 0X74
RAM1    EQU 0X75
RAM2    EQU 0X76
RAM3    EQU 0X77
RAM4    EQU 0X78
RAM5    EQU 0X79
RAM6    EQU 0X7A
RAM7    EQU 0X7B
        ORG    0X00
        GOTO    AYAR
        ORG    0X04
AYAR:
PAKET32 200 ,X
PAKET32 302  ,Y
SELF:
DECF    X  ,F
BASLA:
;  TOPLA32  X,Y,ZB;
;  DIV32  X,Y,ZB
;  KAREKOK X,ZB
;  MULL32 X,Y,ZB
;  BCD  X,DIG
;  DIV32 ZB,Y,ZB
;  EGER    X,"Z",Y
;  CIKAR32 X,Y,X
DIZ X,DIG,5    ;x in değerini her seferinde bir azaltarak sıra ile DIG in ilk 5 adresine yazar
 
 
    GOTO SELF
    SIRALA DIG,5        ; ilk değeri diğer tüm değerler arasından en küçüğü ile değişir
    SIRALA DIG+1,4      ; ikinci değeri kalan değerler arasından en küçüğü ile değişir
    SIRALA DIG+2,3      ; öylece devam eder
    SIRALA DIG+3,2
 
HESAP:
   
 
        GOTO $
    GOTO BASLA
 
 
 
 
        END
Hep meraktan

alisumer

makro kodları:
SIRALA MACRO   ?0,?1       ; ?0 DİZİ DEĞİŞKENİ BAŞLANGIÇ ADRESİ
         LOCAL KAR,TARA,AYRIL,BITIR,SONRAKI
         MOVLW  1
         MOVWF  RAM4
         MOVLW ?0                   ; SIRALANACAK BYTE SAYISI 
         MOVWF  FSR
         MOVLW   ?1-1 
         MOVWF  RAM3  
 TARA:  
         FORR 0,RAM3
         MOVFF  INDF,RAM0
         MOVFW  RAM4
         ADDWF  FSR ,F
         MOVFF  INDF,RAM1
         EGER RAM0,"<",RAM1
         CALL   KAR
         CALL   SONRAKI     
         NEXT
         GOTO   BITIR  
 KAR:  
        MOVFF RAM0,INDF
        MOVFW   RAM4
        SUBWF   FSR ,F 
        MOVFF RAM1,INDF
        RETURN
 SONRAKI:
        INCF    RAM4,F
        DECFSZ  RAM3,F
        RETURN  
  BITIR:      
        ENDM   
Hep meraktan

Powered by EzPortal