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-NEXT DÖNGÜ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-NEXT DÖNGÜ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-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
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