TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: elpeco en 20 de Julio de 2005, 01:38:00
-
Saludos amigos del foro,
para pedirles un super favor....
en los pic 16f87x, cuando hago la conversion analogo-digital, el resultado queda en adresH y adresL en 10 bits, pero lo que no sé, es qué hago despues de eso, he escuchado que hay que hacer una regla de tres, pero necesito las rutinas de Multiplicacion 16x16=32 bits y la Division 32/16=16 bits, y luego despues de la regla de tres, convertirlos a BCD.
Por favor me colaboran con estas rutinas?, son para un proyecto mio....
GRACIAS POR LA RESPUESTA
-
Saludos..
Se me olvidaba, yo programo con MPLAB IDE 6.5-
GRACIAS-espero me respondan por favor
-
No se si saldra doble la respuesta porque me dio un error.si es así lo siento.
Yo usé las que hay en las App Notes que tiene el fabricante, en las de Math,las de punto fijo y van bien
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1469&filter1=function
Espero que sirva de algo
-
Gracias por responder rápido.
Saludos !
parece que he encontrado la subrutina de multiplicacion 16*16=32, pero la de division 32/16=16, no la he encontrado, he visto en el enlace que me dejaste varias subrutinas de multiplicacion y division, pero la mayoria estan implementadas para otros pic y ademas en lenguaje C, y yo no manejo este lenguaje todavia, entonces por favor me podrias ayudar a encontrar la de division 32/16=16, y/o me podrias decir por favor el procedimiento para la conversion A/D luego de obtener el valor en ADRESSH y ADRESSL (10bits), creo que el procedimiento que yo creo es así:
1. hacer regla de tres,es decir, multiplicar el resultado de ADRESSH y ADRESSL por otros dos registros de 16 bits, en estos registros va el valor en que lo necesitamos. y como resultado 4registros (32bits)
en este caso implementaria la Multiplicacion 16*16=32
2.como resultado tengo 4 registros, estos los divido por otros 2 registros (16bits), que tienen como valor la proximacion de escala que queremos, y como resultado tendria 2 registros (16bits).
en este caso utilizaria la Division 32/16=16
3.estos 2 registros de resultado de la Division, los convertiria a BCD, y este seria el resultado.
estos son los pasos a seguir que yo me sé, a no ser que alguien ha de saber otro procedimiento, por favor si me lo hacen saber...
-Entonces que consejos me das?, que hago?, como lo haces vos?, Como implementaste las de app notas?, puedo hacer implementar dos dividiones 16/16=16?
Yo uso MPLAB IDE v6.5, y trabajo con,los pic de la familia 16F87X (16f876-16f873-16f877).
GRACIAS POR LA RESPUESTA, LO AGRADECERÉ DEMASIADO
-
Aqui tienes el enlace:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011000
Son para los PICs que utilizas y vienen todas las rutinas que necesitas en asm.
-
Necesito multiplicar un número de 16 bit por otro de 8 bit. Para ello, descargue de la página de microchip unas rutina para tal caso y está el siguiente(multiplica 16bit por 16 bit y da como resultado 32bit):
;
;*******************************************************************
; Double Precision Multiplication
;
; ( Optimized for Code Size : Looped Code )
;
;*******************************************************************;
; Multiplication: ACCb(16 bits)*ACCa(16 bits) -> ACCb,ACCc (32 bits)
; (a) Load the 1st operand in location ACCaLO & ACCaHI (16 bits)
; (b) Load the 2nd operand in location ACCbLO & ACCbHI (16 bits)
; (c) CALL D_mpy
; (d) The 32 bit result is in location (ACCbHI,ACCbLO,ACCcHI,ACCcLO)
;
; Performance :
; Program Memory : 033
; Clock Cycles : 333
;
; Note : The above timing is the worst case timing, when the
; register ACCb = FFFF. The speed may be improved if
; the register ACCb contains a number ( out of the two
; numbers ) with less number of 1s.
; The performance specs are for Unsigned arithmetic (i.e,
; with “SIGNED equ FALSE“).
;
; The performance specs are for Unsigned arithmetic (i.e,
; with “SIGNED equ FALSE“).
;
;
; Program: DBL_MPYS.ASM
; Revision Date:
; 1-13-97 Compatibility with MPASMWIN 1.40
;
;*******************************************************************;
;ACCaLO equ 0x10
;ACCaHI equ 0x11
;ACCbLO equ 0x12
;ACCbHI equ 0x13
;ACCcLO equ 0x14
;ACCcHI equ 0x15
;ACCdLO equ 0x16
;ACCdHI equ 0x17
;temp equ 0x18
;sign equ 0x19
;Flags equ 0x1F
;
TRUE equ 1
FALSE equ 0
MSB equ 7
SIGNED equ TRUE ; Set This To ‘TRUE’ if the routines
; for Multiplication & Division needs
; to be assembled as Signed Integer
; Routines. If ‘FALSE’ the above two
; routines ( D_mpy & D_div ) use
; unsigned arithmetic.
;*******************************************************************
;
;RUTINA PARA MULTIPLICAR, SUMAR Y RESTAR.
;
;*******************************************************************
;-------------------------------------------------------------------
;SE NECESITA:
;
;11 POCICIONES DE RAM LIBRES PARA:
; ACCaLO
; ACCaHI
; ACCbLO
; ACCbHI
; ACCcLO
; ACCcHI
; ACCdLO
; ACCdHI
; temp
; sign
; Flags
;
;NOTA: Si ACCb vale FFFF, hay que poner SIGNED equ FALSE (más arriba)
; por defecto está seteado TRUE.
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;Para RESTAR llamar a RESTA y devuelve el resultado
;en ACCb. La resta es ACCb - ACCa = ACCb
;
;Para saber si es negativo chequear el bit C del STATUS.
;Si es 1, el resultado es positivo, si es 0 el resultado es negativo.
;
;PASOS A SEGUIR:
;
;1- CARGAR EL MINUENDO EN ACCbHI Y ACCbLO
;2- CARGAR EL SUSTRAENDO EN ACCaHI Y ACCaLO
;3- LLAMAR A LA SUBRUTINA RESTA1
;4- SE OBTUVO EL RESULTADO EN ACCbHI, ACCbLO
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;Para SUMAR llamar a D_add y devuelve el resultado
;en ACCb.
;
;PASOS A SEGUIR:
;
;1- CARGAR EL PRIMER NÚMERO EN ACCbHI Y ACCbLO
;2- CARGAR EL SEGUNDO NÚMERO EN ACCaHI Y ACCaLO
;3- LLAMAR A LA SUBRUTINA D_add
;4- SE OBTUVO EL RESULTADO EN ACCbHI, ACCbLO.
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;Para MULTIPLICAR llamar a la rutina D_mpyS y devuelve el resultado
;en ACCbHI,ACCbLO,ACCcHI,ACCcLO
;
;PASOS A SEGUIR:
;
;1- CARGAR EL PRIMER NÚMERO EN ACCaHI Y ACCaLO
;2- CARGAR EL SEGUNDO NÚMERO EN ACCbHI Y ACCbLO
;3- LLAMAR A LA SUBRUTINA D_mpyS
;4- SE OBTUVO EL RESULTADO EN ACCbHI,ACCbLO,ACCcHI,ACCcLO
;-------------------------------------------------------------------
;-------------------------------------------------------------------
;*******************************************************************
;
RESTA1 CALL neg_A
;
;*******************************************************************
; Double Precision Addition ( ACCb + ACCa -> ACCb )
;
D_add bcf Flags,C ;Clear temp Carry bit
movf ACCaLO,W ; Addition ( ACCb + ACCa -> ACCb )
addwf ACCbLO, F ;add lsb
btfsc STATUS,C ;add in carry
incf ACCbHI, F
btfsc STATUS,C
bsf Flags,C
movf ACCaHI,W
addwf ACCbHI, F ;add msb
btfsc Flags,C
bsf STATUS,C
retlw 0
;*******************************************************************
; Double Precision Multiply ( 16x16 -> 32 )
; ( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word
; in ACCb ( ACCbHI,ACCbLO ) and low word in ACCc ( ACCcHI,ACCcLO ).
;
D_mpyS ;results in ACCb(16 msb’s) and ACCc(16lsb’s)
;
IF SIGNED
CALL S_SIGN
ENDIF
;
call setup
mloop rrf ACCdHI, F ;rotate d right
rrf ACCdLO, F
btfsc STATUS,C ;need to add?
call D_add
rrf ACCbHI, F
rrf ACCbLO, F
rrf ACCcHI, F
rrf ACCcLO, F
decfsz temp, F ;loop until all bits checked
goto mloop
;
IF SIGNED
btfss sign,MSB
retlw 0
comf ACCcLO, F ; negate ACCa ( -ACCa -> ACCa )
incf ACCcLO, F
btfsc STATUS,Z
decf ACCcHI, F
comf ACCcHI, F
btfsc STATUS,Z
neg_B comf ACCbLO, F ; negate ACCb
incf ACCbLO, F
btfsc STATUS,Z
decf ACCbHI, F
comf ACCbHI, F
retlw 0
ELSE
retlw 0
ENDIF
;
;*******************************************************************
;
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
;
;*******************************************************************
;
neg_A comf ACCaLO, F ; negate ACCa ( -ACCa -> ACCa )
incf ACCaLO, F
btfsc STATUS,Z
decf ACCaHI, F
comf ACCaHI, F
retlw 0
;
;*******************************************************************
; 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, F ; negate ACCb
incf ACCbLO, F
btfsc STATUS,Z
decf ACCbHI, F
comf ACCbHI, F
;
chek_A btfss ACCaHI,MSB ; if MSB set go & negate ACCa
retlw 0
goto neg_A
;
ENDIF
La cosa es que no me da el resultado correcto. Quiero hacer 0x1f4 (500) por 0xf4 (244) y en vez de darme 0x1DC90 me da 0xA1DC90.
He cambiado la siguiente línea SIGNED equ TRUE ; Set This To ‘TRUE’ if the routines por SIGNED equ FALSE y obtengo el mismo resultado.
Lamentablemente, mi ingles es muy pobre y no logro entender casi nada y no se a que se debe este error.
La rutina de dónde saqué el pdf se llama AN526 (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011000). Y adjunto la librería.
Muchas gracias.
-
No logro encontrar el problema, asi que subo el programa.
-
D_add
bcf Flags,C ;Clear temp Carry bit
movf ACCaLO,W ; Addition ( ACCb + ACCa -> ACCb )
addwf ACCbLO, F ;add lsb
btfsc STATUS,C ;add in carry
incf ACCbHI, F
btfsc STATUS,Z ;;; AQUI ESTA EL ERROR ES CON Z NO CON C YA ESTA PROBADO AGRADÉCEME PORFA
bsf Flags,C
movf ACCaHI,W
addwf ACCbHI, F ;add msb
btfsc Flags,C
bsf STATUS,C
retlw 0