Autor Tema: Loco con la conversión de un hexadecimal a BCD  (Leído 2315 veces)

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

Desconectado madriles75

  • PIC10
  • *
  • Mensajes: 6
Loco con la conversión de un hexadecimal a BCD
« en: 23 de Junio de 2005, 22:44:00 »
Buenas a todos. Estoy realizando el proyecto fin de carrera con un PIC 16F877, y llevo atascado más de dos semanas con la conversión a BCD de un número hexadecimal.

He encontrado dos códigos que deberían hacerlo, pero ninguno de los dos me hace lo que debería, y ya me estoy volviendo loco Enfurruñado, no tengo donde consultar dudas y los días pasan.

Os pongo los códigos, y gracias de antemano.

Versión 1

highbcd
      andlw   0x0F   ;Enmascara la parte baja del nibble (una vez intercambiado)
      addwf   PCL,F   ;Salta a la tabla
      dt      0x00,0x16,0x32,0x48,0x64,0x80,0x96

hex2bcd
      movwf   Temporal_1
      swapf   Temporal_1,W
      call      highbcd
      movwf   BCDlo
      andlw   0xF0
      movwf   BCDhi
      movlw   0x0F
      andwf   BCDlo,F
      movlw   9
      movwf   Temporal_2

      movf   Temporal_1,W
      andlw   0x0F
      addwf   BCDlo,W
      subwf   Temporal_2,F
      btfss   STATUS,C
      addlw   6

      movwf   BCDlo
      movlw   9
      movwf   Temporal_2
      movlw   0xF0
      andwf   BCDlo,W
      subwf   Temporal_2,F
      clrw
      btfss   STATUS,C
      movlw   6
      addwf   BCDlo,W
      addwf   BCDhi,W
      return

Versión 2

hex2bcd
      movwf   Temporal_1
      clrw
      btfsc   Temporal_1,4
      addlw   0x16
      btfsc   Temporal_1,5
      addlw   0x36
      addlw   0x06
      btfss   STATUS,1         ;skpdc
      addlw   -0x06
      btfsc   Temporal_1,6
      addlw   0x64
      addlw   0x06
      btfss   STATUS,1         ;skpdc
      addlw   -0x06
      movwf   Temporal_2
      movf   Temporal_1,0
      andlw   0x0F
      addwf   Temporal_2,0
      btfsc   STATUS,1         ;skpndc
      addlw   0x06
      addlw   0x06
      btfss   STATUS,1         ;skpdc
      addlw   -0x06

;Ahora toca separar los nibbles      
      
      movwf   Temporal_1
      movwf   ContW
      swapf   Temporal_1,W
      andlw   0x0F
      movwf   BCDhi
      movf   Temporal_1,W
      andlw   0xF0
      movwf   BCDlo
      return


Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Loco con la conversión de un hexadecimal a BCD
« Respuesta #1 en: 24 de Junio de 2005, 03:12:00 »
Aqui te dejo una rutina que funciona a la perfección de cosecha propia:

Codigo:
;HEX2BDC: Transforma el código en Hexadecimal que viene en el w,
;en dos bcd   que se retornan LSB=BP0, MSB=BP1

hex2bcd   movwf   contador1
   clrf   contador2
   comf   contador1,f
h2bcd1   movf   contador1,w
   addlw   0x0a
   btfsc   status,0
   goto   h2bcd2
   movwf   contador1
   incf   contador2,f
   goto   h2bcd1
h2bcd2   comf   contador1,w
   movwf   BP0
   movf   contador2,w
   movwf   BP1
   return   


Esta es de microchip y transforma un número de 16 bits en 5 dígitos BCD:

Codigo:
;********************************************************************
;                  Binary To BCD Conversion Routine
;      This routine converts a 16 Bit binary Number to a 5 Digit
; BCD Number.
;       The 16 bit binary number is input in locations H_byte and
; L_byte with the high byte in H_byte.
;       The 5 digit BCD number is returned in R0, R1 and R2 with R0
; containing the MSB in its right most nibble.
;
;   Performance :
;               Program Memory  :       35
;               Clock Cycles    :       885
;
;*******************************************************************;
;

B2_BCD  bcf     status,c   ;Borra el carry
   movlw   .16
   movwf   contador1
   clrf    R0
   clrf    R1
   clrf    R2
loop16  rlf     L_byte,f
   rlf     H_byte,f
   rlf     R2,f
   rlf     R1,f
   rlf     R0,f
   decfsz  contador1,f
   goto    adjDEC
   return

adjDEC  movlw   R2
   movwf   fsr
   call    adjBCD
   movlw   R1
   movwf   fsr
   call    adjBCD
   movlw   R0
   movwf   fsr
   call    adjBCD
   goto    loop16

adjBCD  movlw   3
   addwf   indf,W
   movwf   temp
   btfsc   temp,3          ; test if result > 7
   movwf   indf
   movlw   30
   addwf   indf,W
   movwf   temp
   btfsc   temp,7          ; test if result > 7
   movwf   indf            ; save as MSD
   return

Desconectado madriles75

  • PIC10
  • *
  • Mensajes: 6
RE: Loco con la conversión de un hexadecimal a BCD
« Respuesta #2 en: 25 de Junio de 2005, 20:34:00 »
Muchas gracias antoniof, utilicé tu versión, pero no me funcionó, aunque al final, de tanto darle vueltas, y entre unos y otros códigos, conseguí hacer una rutina que me funciona. Me convierte de hexadecimal a BCD en el rango 00-59.

El código es este:

hex2bcd
      movwf   Temporal_1         ;Copiamos el número que vamos a convertir a Temporal_1
      andlw   0xF0            ;Enmascaramos el nibble bajo y operamos con el alto
      movwf   Temporal_2         ;Copia de W para siguientes comparaciones
      swapf   Temporal_2,1               ;Preparamos el nibble para sus comparaciones

;Las comparaciones de nibble son las siguientes:
;0x00 ---> BCDhi=0
;0x01 ---> BCDhi=16
;0x02 ---> BCDhi=32
;0x03 ---> BCDhi=48

      sublw    0x00            ;Comparamos con cero
      btfsc   STATUS,Z         
      goto    Es_0            ;Si es cero,
      movf   Temporal_2,0      ;Si no es cero, volvemos a comparar
      sublw    0x01            ;Comparamos con uno
      btfsc   STATUS,Z         
      goto    Es_1            ;Si es uno
      movf   Temporal_2,0      ;Si no es uno, volvemos a comparar
      sublw    0x02            ;Comparamos con dos
      btfsc   STATUS,Z         
      goto    Es_2            ;Si es dos
      movf   Temporal_2,0      ;Si no es dos, volvemos a comparar      
      sublw    0x03            ;Comparamos con cero
      btfsc   STATUS,Z         
      goto    Es_3            ;Si es tres
;Si no es tres, nos hemos pasado de rosca
Es_0
      movwf   BCDhi            ;Si es cero, BCDhi es 0h
      goto    SigueBCD         ;Otropaso
Es_1
      movlw   0x16            ;Si es uno, BCDhi es 16h
      movwf   BCDhi            
      goto    SigueBCD         ;Otropaso
Es_2
      movlw   0x32            ;Si es dos, BCDhi es 32h
      movwf   BCDhi            
      goto    SigueBCD         ;Otropaso
Es_3
      movlw   0x48            ;Si es tres, BCDhi es 48h
      movwf   BCDhi   
      movf   Temporal_1,W      ;Los puntos debiles de este algoritmo
      andlw   0x0F            ;Comprobamos si es 38h o 39h
      movwf   ContW
      sublw   0x08
      btfsc   STATUS,Z
      goto   Es_38
      goto   Mas
Mas
      movf   ContW,W
      sublw   0x09
      btfsc   STATUS,Z
      goto   Es_39
      goto    SigueBCD         ;Otropaso
;Ahora analizamos el nibble bajo
Es_38
      movlw   0x56
      movwf   ContW
      goto   AcabarBCD
Es_39
      movlw   0x57
      movwf   ContW
      goto   AcabarBCD
SigueBCD
      movf   Temporal_1,W      ;Vamos a sacar el nibble bajo ahora
      andlw   0x0F            ;Enmascaramos es nibble alto y trabajamos con el bajo
      movwf   BCDlo            ;Lo copiamos en BCDlo            
      addlw   0x06            ;Le sumamos 6h para ajustar
      btfss   STATUS,1         ;Si hubo acarreo (bit DC), es preciso el ajuste
      addlw   -0x06            ;Si no hubo acarreo (bit DC), es preciso reajustar
      addwf   BCDhi,0            ;Sumamos el nibble bajo con el alto, el rdo queda en W
;Ahora, debemos ajustar el resultado, en caso de ser necesario
      movwf   ContW            ;Pasamos el resultado a ContW
      andlw   0x0F            ;Sacamos el nibble bajo
      movwf   BCDlo            ;Lo copiamos en BCDlo            
      addlw   0x06            ;Le sumamos 6h para ajustar
      btfss   STATUS,1         ;Si hubo acarreo (bit DC), es preciso el ajuste
      goto    AcabarBCD
      goto    AjustarBCD         ;Saltamos al ajuste
AjustarBCD
      movf   ContW,W            ;Realizamos el ajuste
      addlw   0x06
      movwf   ContW            ;pasamos el resultado ajustado ya a ContW
AcabarBCD
      movf   ContW,W            ;Cada nibble a su variable
      andlw   0x0F            ;Nibble bajo
      movwf   BCDlo
      movf   ContW,W
      andlw   0xF0            ;Nibble alto
      movwf   BCDhi
      swapf   BCDhi,1
      return

Gracias y un saludo desde Madrid, aunque mi madre es de un pueblo de Badajoz.

Seguiré dando la lata con más dudas, pues este proyecto se sale de lo habitual en mi carrera, y no tengo otro lugar donde resolver dudas.

Lo dicho, que muchas gracias.

Desconectado madriles75

  • PIC10
  • *
  • Mensajes: 6
RE: Loco con la conversión de un hexadecimal a BCD
« Respuesta #3 en: 25 de Junio de 2005, 22:02:00 »
También es mala suerte!!!! ahora que consigo que me funcione la conversión, va el relojito y me retrasa. Llevo 7 segundos de retraso en 23 minutos.

Cagontó!!!!  ArdiendoArdiendoArdiendo

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Loco con la conversión de un hexadecimal a BCD
« Respuesta #4 en: 26 de Junio de 2005, 13:19:00 »
Supongo que el reloj lo harás con el TMR0, porque por software cualquier ampliación del programa retrasará la cuenta


 

anything