4 bitlik iki sayının çarpımını nasıl yaparız

Başlatan Proteus, 21 Ekim 2014, 23:24:01

Proteus

16F877 ile B  ve C portlarından uygulanan 4 bitlik iki sayının çarpımını yapıp D portunda göstermek istiyorum nasıl yapabiliriz
şöyle bi kod buldum uyarlamaya çalıştım olmadı
; 4x4 bit multiply
; by Ray Gardiner
       ;  X*Y ; result left in W
       ;  X and Y are 4 bits
       ;
       ;
       CLRW            ; Clear Result
       CLRC            ; Clear Carry for RLF later                     ;
       BTFSC   Y,0     ; ?*1
       ADDWF   X,W     ; W = ?X
       RLF     X,F     ; X = 2X
                       ;
       BTFSC   Y,1     ; ?*2
       ADDWF   X,W     ; W = ?X + ?2X
       RLF     X,F     ; W = 4X

       BTFSC   Y,2     ; ?*4
       ADDWF   X,W     ; W = ?X + ?2X + ?4X
       RLF     X,F     ; W = 8X

       BTFSC   Y,3     ; ?*8
       ADDWF   X,W     ; ?X + ?2X + ?4X + ?8X

kantirici

#1
Çarpmayı toplama ile bölmeyi de çıkarma işlemi ile yapabilirsin. Tabi taşma olup olmadığınıda kontrol etmek gerek. Gerçi 4 bitlik iki sayının çarpımı bir byte ı geçmez.

Örneğin 3x5 veya 5x3 çarpmada değişim özelliği oldugundan bu işlem farketmez. Dolayısı ile ya 3 kere 5 i yada 5 kere 3 ü toplayarak çarpma işlemi yapılır.

Eğer çarpma da  2^x çarpanı varsa sola kaydırarakta yapılabilir. Örneğin 4*3; 4= 2^2 oldugundan 4<<2 işlemi bize 1100 verir ve çarpma yapılır.

Kabil ATICI

bu kodun çalışması gerekir.4 bitlik çarpma işte. x ve y olarak iki bellek hücresini kullan, sonuç zaten W registerinde. Bunu D portuna gönder.
Yaptığını söylediğin kod nerede?
ambar7

Proteus

  LIST P=16F877
  INCLUDE "P16F877.INC"
   X EQU 0X20
   Y EQU 0X21

      
 SETUP
      BSF STATUS,5        
      CLRF TRISD
      MOVLW 0XFF
      MOVWF TRISC
      MOVWF TRISB
      BCF STATUS,5
      CLRF PORTB
      CLRF PORTC
      CLRF PORTD
MOVF PORTB,X
MOVF PORTC,Y
      
      CLRW            ; Clear Result
      CLRC           ; Clear Carry for RLF later                     ;
       BTFSC   Y,0     ; ?*1
       ADDWF   X,W     ; W = ?X
       RLF     X,F     ; X = 2X
                       ;
       BTFSC   Y,1     ; ?*2
       ADDWF   X,W     ; W = ?X + ?2X
       RLF     X,F     ; W = 4X

       BTFSC   Y,2     ; ?*4
       ADDWF   X,W     ; W = ?X + ?2X + ?4X
       RLF     X,F     ; W = 8X

       BTFSC   Y,3     ; ?*8
       ADDWF   X,W     ; ?X + ?2X + ?4X + ?8X
MOVWF PORTD
END
     

hasankara

---  C:/Program Files (x86)/Microchip/xc8/v1.30/sources/common/bmul.c  ----------------------------------
1:             unsigned char
2:             __bmul(unsigned char multiplier, unsigned char multiplicand)
0225  00F3     MOVWF multiplier
3:             {
4:             	unsigned char	product = 0;
0226  01F2     CLRF k
5:             
6:             	do {
7:             		if(multiplier & 1)
0227  1C73     BTFSS multiplier, 0x0
0228  2A2C     GOTO 0x22C
8:             			product += multiplicand;
0229  0870     MOVF __pcstackCOMMON, W
022A  00F1     MOVWF byte
022B  07F2     ADDWF k, F
9:             		multiplicand <<= 1;
022C  1003     BCF STATUS, 0x0
022D  0DF0     RLF __pcstackCOMMON, F
10:            		multiplier >>= 1;
022E  1003     BCF STATUS, 0x0
022F  0CF3     RRF multiplier, F
11:            	} while(multiplier != 0);
0230  08F3     MOVF multiplier, F
0231  1D03     BTFSS STATUS, 0x2
0232  2A27     GOTO 0x227
12:            	return product;
0233  0872     MOVF k, W
0234  0008     RETURN
13:            }
0235  3067     MOVLW 0x67
14:      


27:                TRISB=0XFF;
02DB  30FF     MOVLW 0xFF
02DC  1683     BSF STATUS, 0x5
02DD  1303     BCF STATUS, 0x6
02DE  0086     MOVWF PORTB
28:                TRISC=0XFF;
02DF  0087     MOVWF PORTC
29:                TRISD=0;
02E0  0188     CLRF PORTD
30:                PORTD=PORTB*PORTC;
02E1  1283     BCF STATUS, 0x5
02E2  1303     BCF STATUS, 0x6
02E3  0807     MOVF PORTC, W
02E4  00FA     MOVWF 0x7A
02E5  00F0     MOVWF __pcstackCOMMON
02E6  0806     MOVF PORTB, W
02E7  120A     BCF PCLATH, 0x4
02E8  118A     BCF PCLATH, 0x3
02E9  2225     CALL 0x225
02EA  120A     BCF PCLATH, 0x4
02EB  118A     BCF PCLATH, 0x3
02EC  1283     BCF STATUS, 0x5
02ED  1303     BCF STATUS, 0x6
02EE  0088     MOVWF PORTD

Proteus

hasankara çok sağol ama kendi kodum üstünden gitmek istiyorum nedir burdaki eksiklik ? b*c=d olucak b ve c giriş portları  d ise çıkış

hasankara

#6
MOVF PORTB,X
MOVF PORTC,Y

burada kullanım hatası var. asm i geride bırakalı çok oldu ama büyük ihtimalle burada hatan var. movf komutu f kopyalıyor sonucu aynı f e mi yoksa w a mı kaydetsin diye ikinci parametre alıyor. yani "movf PORTB,w" mantıklı kullanım olur. bunun anlamı ise portb yi w a geçirir.

burada yapmak istediğini sanırım anladım.

MOVF PORTB,w
MOVWF X,f
MOVF PORTC,w
MOVWF Y,f

önce akümülatöre alıp sonra hedefe yüklüyorsun. ilk gözüme çarpan burasıydı bakayım bakalım başka ne yapmışsın.

mesaj birleştirme:: 22 Ekim 2014, 00:41:08

bir de clrc diye bir komutunun olduğunu hatırlamıyorum 16f877 için. onun yerine bcf STATUS,c diyebilirsin.

RaMu

16F877 de
MOVF PORTB,X
MOVF PORTC,Y

diye bir komut yoktur,
MOVF PORTB,W

veya
MOVFW PORTB

diyerek portb de ne varsa W registerına alırsın, sonra
MOVWF  X

diyerek W registerındaki değeri X file registerına (değişkenine) aktarırsın.

Birde sayılar B ve C portunun alt 4 bitine uygulanıyor diye düşünelim,
(alt mı üst mü 4 bite uygulanıyor belirtmemişsin sanırım)
yukarıda söylediğim şekilde değeri okuduyup X e aktardıktan sonra,
MOVLW  h0F
ANDWF  X,F

diyerek X registerının üst 4 bitini temizlemekte fayda var.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Kabil ATICI

LIST P=16F877
#INCLUDE <P16F877.INC>
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _LVP_ON & _CPD_OFF

 INT_VAR     UDATA_SHR
w_temp      RES     1       ; variable used for context saving
status_temp RES     1       ; variable used for context saving
pclath_temp RES       1       ; variable used for context saving

CBLOCK 0x20
   X 
   Y 
 ENDC ;

ORG 0x000 ;
 GOTO Init ;
INT_VECTOR      CODE    0x0004 ; interrupt vector location
GOTO INT_GIT
ORG 0X005

Init
; movlw 0x07 ; Turn comparators off and
; movwf CMCON ; enable pins for I/O functions
BANKSEL TRISD
      CLRF TRISD
      MOVLW 0XFF
      MOVWF TRISC
      MOVWF TRISB
BANKSEL PORTB
      CLRF PORTB
      CLRF PORTC
      CLRF PORTD
MOVF PORTB, W
MOVWF X
MOVF PORTC, W
MOVWF Y
;MOVF PORTB,X
;MOVF PORTC,Y

      CLRW            ; Clear Result
         BCF STATUS,C           ; Clear Carry for RLF later                     ;
       BTFSC   Y,0     ; ?*1
       ADDWF   X,W     ; W = ?X
       RLF     X,F     ; X = 2X
                       ;
       BTFSC   Y,1     ; ?*2
       ADDWF   X,W     ; W = ?X + ?2X
       RLF     X,F     ; W = 4X

       BTFSC   Y,2     ; ?*4
       ADDWF   X,W     ; W = ?X + ?2X + ?4X
       RLF     X,F     ; W = 8X

       BTFSC   Y,3     ; ?*8
       ADDWF   X,W     ; ?X + ?2X + ?4X + ?8X
MOVWF PORTD

dongu
GOTO dongu

INT_GIT
    movf    pclath_temp,w   ; retrieve copy of PCLATH register
    movwf   PCLATH          ; restore pre-isr PCLATH register contents
    movf    status_temp,w   ; retrieve copy of STATUS register
    movwf   STATUS          ; restore pre-isr STATUS register contents
    swapf   w_temp,f
    swapf   w_temp,w        ; restore pre-isr W register contents
    retfie                  ; return from interrupt
 end

ortalığı biraz karıştırdığımın farkındayım...Bu şekilde mplabx üzerinde derlenmekte ve isis üzerinde çalışmakta.
ambar7

Proteus

#9
ambar kodları derledim hata veriyor kullandıgım surum mplab7.10



sanırım kullandıgım compılerdan kaynaklanıyor kodların hexını gonderebılırsen ya da compilerin linkini atsan

Kabil ATICI

#10
http://www.microchip.com/pagehandler/en-us/family/mplabx/
derleyicinin linki,


:020000040000FA
:020000000528D1
:040002000034003492
:020008002328AB
:06000A00831603138801B8
:10001000FF30870086008312031386018701880161
:100020000608A0000708A1000301031021182007FB
:10003000A00DA1182007A00D21192007A00DA119BE
:1000400020078800222872088A0071088300F00EB9
:04005000700E090025
:02400E00F13F80
:00000001FF

buda hex dosyası
ambar7

Proteus

verdiğin kodla devre eksik calısıyor ambar kullandığın şemayı ekleyebilirmisin




2*1=4 buluyor sen nasıl calıstırdınn ?

Kabil ATICI

giriş ve çıkışları ters bağlamışsın.1 yazdığı zaman bit0 kırmızı olması gerekir. LSB ve MSB olarak ters bağlı.

girişte ne yazıyor üstteki 100 (ikilik sayı sisteminde) alttaki 1000 (ikilik sayı sisteminde)

sonuçta ne yazıyor 100000 (ikilik sayı sisteminde) sonuç doğru... İstersen bilgisayarın hesap makinesinde deneebilirsin.

Benim şemamda yayınlanacak bir şey yok doğrudan ikilik sayı sisteminde baktım çünkü...
girişler basit  LOGICTOGGLE bağlı bunlarla girilen değeri çıkış bacaklarının sonucuna baktım.
ambar7

RaMu

Hem displayi hem sayı girişlerini yanlış bağlamışsın,
yaptığın işlem (sw1 4, sw2 8 )
4x8
sonuç ise
32
pice bağlı olan sayı girişlerinin y ekseninde simetriği olacak şekilde bağlamalısın.
Display içinde bulduğun sonucu displayde gösterilebilir hale getirmen lazım,
senin bulduğun 32 sonucu aslında 0x20, veya 0b 0010 0000 şeklindedir.
Picde işlemler hexadecimal (16lık taban) olarak yapılır,
sen sonucu decimal (onluk taban) olarak görmek istiyorsun.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Proteus

tamamdır sorunu çözdüm yardımlarınız için çok teşekkürler...