Gracias,
alexhumbertoa.
Le he hecho un par de cambios a la rutina que posteé ayer para hacerla
más rápida, ahora nos ahorramos hasta 25 ciclos de instrucción.
Según las pruebas que he hecho, se ejecuta en
315-331 ciclos.
Esta función también la podéis usar para
dividir dos números de 8 bits y que os entregue el resultado
con decimales.
¿Cómo? Muy sencillo: sólo tenéis que poner los 8 bits del dividendo en DIVIDENDOH (en la parte alta de DIVIDENDO), dejando los 8 bits más bajos a cero. El divisor lo dejáis igual que antes(poniendo los 8 bits del divisor en la parte baja y dejando DIVISORH a cero).
De esta manera obtendréis: en
COCIENTEH la parte entera del resultado y en
COCIENTE la parte decimal.
Como sólo usamos 8 bits para la parte decimal, os serán validas las
2 primeras cifras decimales del resultado.
Aquí tenéis un par de
resultados reales que me ha dado el PIC16F1509:
55/7 = 7'8554 (en realidad es 7'8571)
255/7 = 36'4257 (en realidad es 36'4285)
Espero que os sea de utilidad,un saludo.
PICdevJerez
;;DIVISION ENTERA DE NÚMEROS NATURALES 16bits:16bits
;;
;;Emplea la instrucción "subwfb", que se encuentra en
;;los Mid-Range 8 bits PICs (49 instrucciones o más)
;;
;;Realiza la división de dos números de 16bits
;;en aprox. 320 ciclos de instrucción
;;usando desplazamientos en lugar de restas sucesivas
;;
;;Necesita 2 variables de 8 bits:TEMPORAL y W_L
;;Para que funcione, las variables de 16bits han de estar
;;en el orden HIGH:LOW (como se puede ver en las equ)
;;es decir, en la posición más baja de la RAM el byte bajo
;;y en la siguiente posición más alta el byte alto
;;
;;Entrada: DIVIDENDO (16b) y DIVISOR(16b)
;;Salida: COCIENTE(16b) y RESTO(16b)
;;Borra DIVIDENDO, no altera DIVISOR
;;
;;Está implementada como una subrutina: DIVIDE
;; PICdevJerez - Jerez de la Frontera - España
#ifndef Carry
#define Carry STATUS,C
#endif
#ifndef lsl16
lsl16 MACRO File
lslf File,F
rlf (File+.1),F
endM
#endif
;;****************Estas líneas son un ejemplo ********************
;;**suprimir los punto y coma para su funcionamiento stand-alone**
;Temporal equ .127
;CocienteH equ .126
;Cociente equ .125
;RestoH equ .124
;Resto equ .123
;DividendoH equ .122
;Dividendo equ .121
;DivisorH equ .120
;Divisor equ .119
;W_L equ .118
;
;DIVIDENDO equ .6000 ;Constantes usadas como ejemplo
;DIVISOR equ .14 ;
;
; movlw HIGH DIVIDENDO
; movwf DividendoH
; movlw LOW DIVIDENDO
; movwf Dividendo
; movlw HIGH DIVISOR
; movwf DivisorH
; movlw LOW DIVISOR
; movwf Divisor
;;*****************************************************************
DIVIDE:
clrf Temporal
clrf CocienteH
clrf Cociente
clrf RestoH
clrf Resto
st:
btfsc Temporal,4
return
incf Temporal
lsl16 Cociente
lsl16 Dividendo
rlf Resto
rlf (Resto+.1)
movf Divisor,W
subwf Resto,W
movwf W_L
movf DivisorH,W
subwfb RestoH,W
btfss Carry
goto st
bsf Cociente,0
movwf RestoH
movf W_L,W
movwf Resto
goto st
;end