TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: NANO1985 en 23 de Mayo de 2008, 09:47:52

Título: Division en Assembler...
Publicado por: NANO1985 en 23 de Mayo de 2008, 09:47:52
Hola muchachos, haciendo unas pruebas, sabemos que la multiplicacion o producto son sumas sucesivas y la division o cociente son restas sucesivas, ahora me surgió una duda,...
¿que pasa con el resto?  :? si yo divido d30 en d4 (efectuando las restas correnpondientes), como resultado obtengo un d7 y como resto un d0, en realidad tendríamos que obtener 0.5 de resto, pero como ésto es practicamente imposible, los 0.5  se pierden... és posible solucionar ésto??
¿cómo podemos obtener operaciones más precisas mediante assembler?  :?
Disculpen mi inquietud, pero ésto era una duda que me picaba en la cabeza....
saludos  8)
Título: Re: Division en Assembler...
Publicado por: Leon Pic en 23 de Mayo de 2008, 10:49:11
En la divición hay un tema muy importante, que tu CI trabaje con punto flotante. Si no, lo que sigue después de la coma, lo perdés.
Título: Re: Division en Assembler...
Publicado por: NANO1985 en 23 de Mayo de 2008, 11:54:39
En la divición hay un tema muy importante, que tu CI trabaje con punto flotante. Si no, lo que sigue después de la coma, lo perdés.
antes que nada muchas gracias por tu pronta respuesta,...
si se utilizan los convencionales pics16Fxxx directamente estoy perdido....
hay pics que soporten operaciones con punto flotante?? :?
Título: Re: Division en Assembler...
Publicado por: Leon Pic en 23 de Mayo de 2008, 11:57:26
Si, la línea 18F trabajan con punto flotante, aunque no se si todos.
Título: Re: Division en Assembler...
Publicado por: NANO1985 en 23 de Mayo de 2008, 12:00:57
Si, la línea 18F trabajan con punto flotante, aunque no se si todos.
muchas gracias leon pic... ya les voy a aplicar un vistazo...
Saludos...  8)
Título: Re: Division en Assembler...
Publicado por: Javicho en 23 de Mayo de 2008, 12:23:35
Hola NANO1985:

Aquí te paso una subrutina de división:
Para usar la subrutina en (ACCbHI)(ACCbLO) cargas el Numerador luego en (ACCaHI)(ACCaLO) cargas el denominador y llamas a la surutina (es decir haces ... call   D_divF) luego en (ACCbHI)(ACCbLO) tienes el cociente y en (ACCcHI) el residuo. Lo puedes usar con cualquier PIC de cualquier serie
;************************************************************************************************
;               SUBRUTINAS DE DIVISION A 16 BITS
;************************************************************************************************
; definir en la RAM: TEMP, sign, ACCaHI, ACCaLO, ACCbHI, ACCbLO, ACCcHI, ACCcLO, ACCdHI, ACCdLO
;(ACCbHI)(ACCbLO) / (ACCaHI)(ACCaLO) = (Q)->(ACCbHI)(ACCbLO) + (R)->(ACCcHI)(ACCcLO)   |
;Q: Cociente
;R: Residuo
;----------------------------------------------------------------------------------------
TRUE    equ     1
FALSE   equ     0
;+++++++++++++++++++++++++
SIGNED  equ     FALSE

divMac  MACRO
   LOCAL   NOCHK
   LOCAL   NOGO

   bcf     STATUS,C
   rlf     ACCdLO, F
   rlf     ACCdHI, F
   rlf     ACCcLO, F
   rlf     ACCcHI, F
   movf    ACCaHI,W
   subwf   ACCcHI,W          ;check if a>c
   btfss   STATUS,Z
   goto    NOCHK
   movf    ACCaLO,W
   subwf   ACCcLO,W        ;if msb equal then check lsb
NOCHK   btfss   STATUS,C        ;carry set if c>a
   goto    NOGO
   movf    ACCaLO,W        ;c-a into c
   subwf   ACCcLO, F
   btfss   STATUS,C
   decf    ACCcHI, F
   movf    ACCaHI,W
   subwf   ACCcHI, F
   bsf     STATUS,C        ;shift a 1 into b (result)
NOGO    rlf     ACCbLO, F
   rlf     ACCbHI, F
   ENDM
;*******************************************************************
setup   movlw   .16             ; for 16 shifts
   movwf   TEMP
   movf    ACCbHI,W          ;move ACCb to ACCd
   movwf   ACCdHI
   movf    ACCbLO,W
   movwf   ACCdLO
   clrf    ACCbHI
   clrf    ACCbLO
   retlw   0
;*******************************************************************
D_divF
     IF   SIGNED
     CALL    S_SIGN
     ENDIF

   call    setup
   clrf    ACCcHI
   clrf    ACCcLO
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
   divMac
    IF    SIGNED
   btfss   sign,MSB        ; check sign if negative
   retlw   0
   goto    neg_B          ; negate ACCa ( -ACCa -> ACCa )
    ELSE
   retlw   0
    ENDIF
;*******************************************************************
; Assemble this section only if Signed Arithmetic Needed
     IF    SIGNED
S_SIGN  movf    ACCaHI,W
   xorwf   ACCbHI,W
   movwf   sign
   btfss   ACCbHI,MSB        ; if MSB set go & negate ACCb
   goto    chek_A
   comf    ACCbLO          ; negate ACCb
   incf    ACCbLO
   btfsc   STATUS,Z
   decf    ACCbHI
   comf    ACCbHI
chek_A  btfss   ACCaHI,MSB        ; if MSB set go & negate ACCa
   retlw   0
   goto    neg_A
     ENDIF
;************************************************************************************************

Javicho.