Autor Tema: ¿Como puedo dividir 16bit/16bit con punto decimal que no sea en C?  (Leído 3534 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado PICado

  • PIC10
  • *
  • Mensajes: 11
Hola compañeros necesito una rutina en asm donde pueda dividir 16bit/16bit o 8bit/8bit con punto decimal.....
Muchas gracias por su colaboracion...

Desconectado Artifox

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 455
    • Quadbot
RE: ¿Como puedo dividir 16bit/16bit con punto decimal que no sea en C?
« Respuesta #1 en: 13 de Julio de 2005, 22:11:00 »
Hola, si quieres hacerlo en asembler, te recomiendo que hagas tu propio algoritmo, yo hace mucho tiempo hice una para 16 bits, era en base a restas y comparaciones, recuerdo que demoraba un poco, pero lograba obtener el cociente y el residuo de la division, luego para hacer el punto decimal tenia que multiplicar por 10 y volver a dividir... era bastante pesado. No se si alguien habra hecho alguna mejor, pero esa es la idea.

Mi codigo ya no lo tengo a la mano, sino te lo pasaria, ten paciencia y podras sacar tu propio algoritmo...
Video Quadbot
Saludos desde mi querido Perú.
Si realmente queremos que el mundo cambie debemos empezar por nosotros mismos... ;)

Desconectado RaDoN

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1498
RE: ¿Como puedo dividir 16bit/16bit con punto decimal que no sea en C?
« Respuesta #2 en: 13 de Septiembre de 2005, 14:02:00 »
Esta fue una de las razones por que pase de ASM a C ....

a = b/c; // Así de sencillo Demonio

Ademas que cuendo comence en C, en pocos días hice mas cosas que en meses con ASM. Yo lo recomiendo 100% Divertido
Si juegas contra el mejor, pierdes como los demás.

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
RE: ¿Como puedo dividir 16bit/16bit con punto decimal que no sea en C?
« Respuesta #3 en: 30 de Septiembre de 2005, 03:08:00 »
Supongo que habrás encontrado ya la rutina de división pero... por si acaso te paso esta. A mi me funciona perfectamente.


###################################################
; DIVIDE
; Divide one 16-bit number into another, returning the 16-bit result and
; the remainder. Upon entry, the top of the division fraction (the dividend)
; must be in topH and topL, and the bottom (divisor) in btmH and btmL.
; If division by zero is attempted, the routine will return immediately with
; the error code of 0FFh in w. Otherwise, it will perform the division, leaving
; the remainder in topH and topL and the result (quotient) in qH and qL.
; Upon return from a successful division, w contains 0.


Divide       MOVF btmH,w                ; Check for division by 0.
             IORWF btmL,w              
             BTFSC STATUS,Z            
             RETLW d"255"               ; Error code= 255: return.
             MOVLW d"1"                 ; Otherwise, initialize variables
             MOVWF count
             CLRF index                 ; for the division.
             CLRF qH                    
             CLRF qL                    

Divide_sh_loop  BTFSC btmH,d"7"         ; Shift divisor left
             GOTO Divide_d1
             BCF STATUS,C               ; until msb is in
             RLF btmL                   ; btmH.7.
             RLF btmH                   ; count = no. of shifts+1.
             INCF count                
             GOTO Divide_sh_loop        
Divide_d1    BCF STATUS,C              
             RLF qL                     ; Shift quotient left.
             RLF qH                    
             MOVF btmL,w                ; top = top - btm.
             SUBWF topL
             BTFSC STATUS,C             ; If top - btm < 0 then
             GOTO Divide_d2
             MOVLW d"1"                 ; top = top + btm
             SUBWF topH
             BTFSC STATUS,C             ; The idea is to do the
             GOTO Divide_d2
             INCF topH                  ; the subtraction and comparison
             MOVF btmL,w                ; (top > btm?) in one step.
             ADDWF topL
             goto Divide_reentr         ; Then, if btm > top, undo <Microchip instruction>
Divide_d2    MOVF btmH,w                ; the subtraction by adding
             SUBWF topH
             BTFSS STATUS,C             ; top and btm back together
             goto Divide_less           ; <Microchip instruction>
             BSF qL,d"0"                
Divide_reentr
             BCF STATUS,C              
             RRF btmH                  
             RRF btmL                  
             DECFSZ count              
             GOTO Divide_d1

             RETLW 0h                   ; Return w/ remainder in top
                                        ; and result in q.&nsp;
Divide_less  MOVF btmL,w                ; btm > top, so
             ADDWF topL
             BTFSC STATUS,C             ; undo the subtraction by
             INCF topH                  ; adding them back together.
             MOVF btmH,w                
             ADDWF topH
             goto    Divide_reentr      ; <Microchip instruction>

###################################################


; MULTIPLY multiplier, multiplicand
; Multiply two 16-bit numbers into a 16-bit product, permitting overflow.


Multiply
             CLRF prodH                 ; Clear product to make
             CLRF prodL                 ; way for new calculation.
             MOVLW d"16"                ; Number of bits to calc.
             MOVWF index
Multiply_loop
             BCF STATUS,C              
             RLF prodL                  ; Shift product left.
             RLF prodH                  
             BCF STATUS,C              
             RLF mulcL                  ; Shift multiplicand left.
             RLF mulcH                  
             BTFSS STATUS,C             ; If carry, add multiplier
             GOTO Multiply_skip
             MOVF mulpL,w               ; to the product. Else skip.
             ADDWF prodL
             BTFSC STATUS,C             ; 16-bit addition: prod+mulp
             INCF prodH                
             MOVF mulpH,w              
             ADDWF prodH
Multiply_skip
             DECFSZ index              
             GOTO Multiply_loop
            
             RETLW 0h

###################################################

suma_16_bits

movf   Dato_A_L,W      ;Carga menos peso del dato A
addwf   Dato_B_L,W      ;Suma menos peso del dato B
movwf   Resultado_L      ;Almacena el resultado
movf   Dato_A_H,W      ;Carga más peso del dato A
btfsc   STATUS,C      ;Hubo acarreo anterior ??
addlw   1            ;Si, suma 1 al acumulador
addwf   Dato_B_H,W      ;Suma más peso del dato B
movwf   Resultado_H      ;Guarda el resultado

return

###################################################

resta_16_bits

movf   Dato_B_L,W   ;Carga menos peso del dato B (sustraendo)
subwf   Dato_A_L,W   ;Resta menos peso del dato A (minuendo)
movwf   Resultado_L   ;Almacena el resultado
movf   Dato_B_H,W   ;Carga más peso del dato B (sustraendo)
btfss   STATUS,C                   ;Hubo acarreo (CARRY = 0) anterior ??
addlw   1      ;Si, añade 1 al acumulador (sustraendo)
subwf   Dato_A_H,W   ;Resta más peso del dato A (minuendo)
movwf   Resultado_H   ;Guarda el resultado

return

###################################################

movlw   .156
movwf   Dato_A_H
movf   .167
movwf   Dato_A_L

movlw   .15
movwf   Dato_B_H
movlw   .120
movwf   Dato_B_L

call   suma_16_bits

EL RESULTADO DE LA SUMA SE ENCUENTRA EN "Resultado_H" y "Resultado_L"

call   resta_16_bits

EL RESULTADO DE LA RESTA SE ENCUENTRA EN "Resultado_H" y "Resultado_L"

###################################################

movlw   b"00001010"
movwf   topH
movlw   b"00111100"
movwf   topL

movlw   b"00000000"
movwf   btmH
movlw   b"00001010"
movwf   btmL

call   Divide

movf   qH,W   ; RESULTADO
movf   qL,W

EL RESULTADO DE LA DIVISION SE ENCUENTRA EN "qH" y "qL"

###################################################

movlw   .13
movwf   mulcH
movlw   .123
movwf   mulcL

movlw   .65
movwf   mulpH
movlw   .117
movwf   mulpL

call   Multiply

movf   prodH,W               ; RESULTADO
movf   prodL,W

EL RESULTADO DE LA MULTIPLICACION SE ENCUENTRA EN "prodH" y "prodL"

Desconectado peterpan1000

  • PIC10
  • *
  • Mensajes: 7
RE: ¿Como puedo dividir 16bit/16bit con punto decimal que no sea en C?
« Respuesta #4 en: 30 de Septiembre de 2005, 10:26:00 »
Busca en la pagina de microchip tiene codigo fuente para realizar multitud de tareas y en concreto funcionas matematicas hay muchas