Binario a BCD – Recorre y Suma+3

June 21, 2007 at 4:25 pm | Posted in Ensamblador, Rutinas, Tutorial | 41 Comments

Numero Binario de 8 bits a BCD mediante el algoritmo Recorre y Suma+3

En la entrada anterior se encuentra una rutina para convertir un numero Binario de 8 bits a BCD empleando un metodo de division po restas sucesivas. En esta ocasion presento una rutina para lograr la misma conversion de Binario a BCD empleando el algoritmo Recorre y Suma+3.

El algoritmo funciona de la siguiente manera:

  • Recorre 1 bit a la izquierda el numero binario.
  • Si se han hecho 8 corrimientos, el numero BCD se encuentra en las columnas CENTENAS, DECENAS y UNIDADES.
  • Si el valor binario de cualquiera de las columnas BCD es 5 o mayor, se suma 3 al valor en esta columna BCD.
  • Si se desea convertir un byte despues de haber efectuado 8 corrimientos la conversion ha finalizado, para 2 bytes se necesitarian 16 y asi sucesivamente.

Lea el artículo completo en el blog Circuitos electronicos.

41 Comments »

RSS feed for comments on this post. TrackBack URI

  1. Esta muy interesante y muy sencilla esta rutina de conversión mucho más sencilla que otras que he visto.

  2. Si, la verdad es que esta rutina es muy sencilla, yo la conocí el mismo día que hice este tutorial. Encontré en internet una rutina de conversión binario a bcd implementada en un fpga usando vhdl, investigué sobre esa rutina y la implementé en un pic, así fue como salió esta rutina.

  3. hola, enhorabuena por la pagina, esta bastante interesante, he probado el codigo de para convertir de BIN a BCD y va perfecto! pero yo necesitaria convertir un numero de 2 bytes (por ej: 20000 = 4E20) a BCD, ve visto que hay que hacer 16 rotaciones pero no se muy bien como enlazar los dos bytes… me podriais decir como puedo hacerlo???
    un saludo

  4. todo controlao, ya lo tengo resuelto…

  5. hola una pregunta soy novatoen programacion!! asi q no se q es lo q hace la siguient instruccion no se si puedan explicarme

    goto $+2

    de antemano gracias!!

  6. El caracter “$” hace referencia a la línea en la que se encuentra el programa, por ejemplo un “goto $” dejaría ciclado el programa siempre en la misma línea. “goto $+2” le indica al programa que salte 2 líneas hacia adelante.

  7. ok muchas gracias!!
    cual quier otra duda en progra puedo preguntar ak?
    jejejejej nos vemos luego!1

  8. don una pregunta mas!! BCDH y BCDL como se cargan con los valores o podrias explicarme como funcionan por q no se en q momento toman valoresdel binario ingresado en BIN gracias por tu atencion!!

  9. Antes de mandar llamar la rutina el numero que deseas convertir lo debes cargar en la variable BIN, por ejemplo si quieres convertir 135 a BCD lo que tendrias que hacer es algo asi:

    movlw b’10000111′
    call BIN2BCD_RS3

    Después tienes el resultado de la conversión en 2 bytes, BCDH y BCDL, si quisieras desplegar esos datos supongamos por el puerto B se tendria que hacer lo siguiente después de regresar de la rutina de conversion:

    movf BCDH,w
    movwf PORTB
    swapf BCDL,w
    andlw 0x0F
    movwf PORTB
    movf BCDL,w
    andlw 0x0F
    movwf PORTB

    Asi despliegas primero el “1”, después el “3” y por ultimo el “5”.
    Espero que te haya quedado mas claro como funciona la rutina.

  10. ok muchas gracias y disculpe las molestias!!

  11. No es ninguna molestia link, para eso estamos

  12. soy yo de nuevo molestando jajaja perdon pero no se cual es esta intruccion “swapf BCDL,w” disculapa y gracias de antemano!!

  13. y tambien quieor saber si a la hora de etiquetar mis variables tambien tengo q declarar a BCDH y BCDL si es asi hay alguna direccion precisa o puedeser en cualquier direccion merefiero a las de uso generas!1

  14. SWAPF es una instrucción que sirve para cambiar de posición (swap) los nibbles de un registro, de ese modo el nibble alto pasa a el lugar del nibble bajo y viceversa. Te recomiendo que revises el post Conjunto de instrucciones del PIC 16F628 para que alcares todas tus dudas sobre las instrucciones.
    Sobre tu otra pregunta, BCDH y BCDL si las debes delcarar junto con tus demás variables en cualquier dirección que quieras de los registros de uso general.

  15. Gate_Rs, tengo el mimso problema, puedes explica como lo resolviste? o alguien puede explicar como enlazar 2 bytes de 8bits para hacer conversiones de mas alla de 255, osea hasta 65,535…..

    HELP!

  16. mm el algoritmo no hace lo que deberia, no obtiene las centenas, de todos modos ya lo resolvi, pero muy buen programa.De hecho aprendi bien para que se ocula RLF. excelente.

  17. Disculpa, por que dices que no obtiene las centenas? Yo esa rutina la he usado muchas veces y siempre funciona, por ejemplo si el numero que quiero convertir es 0xFF obtengo en BCDH un 0x02 y en BCDL un 0x55. Podrias decirme donde esta el error?
    Tal vez al momento de publicar esto cambie algo en la rutina y no me di cuenta, lo revisare aunque estoy seguro que esta rutina si funciona, agradeceria si puedes indicar donde esta el error.

  18. Hola Quisiera saber por qué razón es necesario saber si el numero es mayor o igual a 5 y por que le suman 3

    Gracias

  19. Hola, si quieres saber exáctamente como funciona el algoritmo lo puedes hacer consultando el siguiente enlace:
    http://www.engr.udayton.edu/faculty/jloomis/ece314/notes/devices/binary_to_BCD/bin_to_BCD.html

  20. Disculpa, la informaciòn del link ya la habìa leído, pero sigo sin entender porque se evalúa desde 5 y porque es necesario sumarle 3. Siempre se debe hacer ese proceso?, es un estándar o algo así?

    Gracias.

  21. Si, es algo asi como un estandar, es algo que ya esta establecido en el algoritmo, en el enlace que cito viene bien explicado eso, yo solamente implemente el algoritmo en el ensamblador MPASM para los 16F siguiendo la regla de recorrer, checar y sumar 3.

  22. ok, muchas gracias!!!

  23. hola necesito saber como hacer para que conectar un display en un simulator ide es de cuatro digitos multiplexado y debe tener dos para la parte entera y dos para la parte decimal gracias

  24. Hola necesito hacer la conversión para 16 bits, la realice y me sirve solo para 8 bits, tengo una duda cuando hay dos o mas columnas que me dan 5 o mayor, a cual le suma tres, a la mayor, menor peso o a todas. Gracias a y pues estoy programando freescale hc08. gracias.

  25. ANDRES, para realizar la conversion de 16 bits se sigue el mismo proceso que para 8, primero se evalua la columna de menor peso (el nibble menos significativo), si fuera 5 se le suma 3 y después se siguen evaluando las demás columnas, pero siempre realizando la suma inmediatamente de encontrar un 5 en una columna. Espero que te haya aclarado un poco tu duda.

  26. n0o entiendo

  27. interesante el programa, pero necesito saber como usar el microcontrolador atmel 80c52 como decodificador de binario a bcd

  28. Gracias, me sirvio de mucho, nuevamente gracias

  29. codigo para programar en C

  30. publica el de dos bytes ='( porfaaaaaaaa

  31. Probe tu rutina, pero para numeros mayores a 99 es necesario agregar la instruccion

    rlf BCDH,f

    Despues de hacer el corrimiento en BCDL (quiza se te paso por alto). Como no encontre comentarios al respecto, hago esta anotación año y medio tarde!!! Me sorprende porque algunos dicen que funciono OK.

    Para ANGHE, basta tener BINH, BINL como entradas, cargar 16 en CUENTA y considerar que con 16 bits puedes tener hasta 65536, por lo que deberas tener
    3 bytes de salida (recuerda que la salida es BCD): BCDH2, BCDH, BCDL.

  32. hola, alguien me puede explicar detalladamente con base a lo anterior, como hacer la conversion de 16 bits. No necesariamnete el codigo (si lo tienen mucho mejor), solamente con palabras, ¿que es lo que debo adicionar o que es lo que debo quitar?.

    Gracias.

  33. Cuántas kipi has visto hoy en el metro?
    Saludos, desde la tierra de kipi

  34. Necesito hacer una calculadora (Suma, resta y multiplicacion) de 2 numeros BCD de 2 bits, estas operaciones tambien se deben hacer con signo.
    Si alguien me puede ayudar, se lo agradeceria xq es para un proyecto de la Universidad.

  35. hola que tal, tengo un problema al momento de convertir de binario a bcd en tu programa, yo primero convierto de codigo gray a binario y despues con tu programo quiero convertirlo a BCD y no hallo por que no carga correctamente los valores a BCDH y BCDl
    me seria muy grata tu ayuda si pudieras checar mi codigo y decirme por que no me funciona correctamente tu codigo :$

    inicio
    clrf portb
    clrf portA
    bsf status,rp0
    movlw b’00010000′
    movwf portA
    movlw h’ff’
    movwf portB
    bcf status,rp0

    lee btfss portA,4
    goto lee
    goto captura

    captura movf portb,w
    movwf original
    movf original,w
    andlw b’10000000′
    movwf carga1
    clrf c
    rrf carga1,w
    movwf acarreo
    movf original,w
    ;andlw b’11000000′
    movwf suma
    movf suma,w
    xorwf acarreo,w
    andlw b’11000000′
    movwf acum
    clrf portB
    ; 2do bit
    movf acum,w
    andlw b’01000000′
    movwf carga2
    clrf c
    rrf carga2,w ;
    movwf acarreo2
    movf original,w
    ;andlw b’00100000′
    movwf suma2
    movf suma2,w
    xorwf acarreo2,w
    andlw b’00100000′
    addwf acum,w
    movwf acum2
    clrf portB
    ; para bit 3
    movf acum2,w
    andlw b’00100000′
    movwf carga3
    clrf c
    rrf carga3,w ;
    movwf acarreo3
    movf original,w
    ;andlw b’00010000′
    movwf suma3
    movf suma3,w
    xorwf acarreo3,w
    andlw b’00010000′
    addwf acum2,w
    movwf acum3
    clrf portB
    ; bit 4
    movf acum3,w
    andlw b’00010000′
    movwf carga4
    clrf c
    rrf carga4,w ;
    movwf acarreo4
    movf original,w
    ;andlw b’000001000′
    movwf suma4
    movf suma4,w
    xorwf acarreo4,w
    andlw b’00001000′
    addwf acum3,w
    movwf acum4
    clrf portB
    ; bit 5
    movf acum4,w
    andlw b’00001000′
    movwf carga5
    clrf c
    rrf carga5,w ;
    movwf acarreo5
    movf original,w
    ;andlw b’11111100′
    movwf suma5
    movf suma5,w
    xorwf acarreo5,w
    andlw b’00000100′
    addwf acum4,w
    movwf acum5
    clrf portB
    ; bit 6
    movf acum5,w
    andlw b’00000100′
    movwf carga6
    clrf c
    rrf carga6,w ;
    movwf acarreo6
    movf original,w
    ;andlw b’11111110′
    movwf suma6
    movf suma6,w
    xorwf acarreo6,w
    andlw b’00000010′
    addwf acum5,w
    movwf acum6
    clrf portB
    ;bit 7
    movf acum6,w
    andlw b’00000010′
    movwf carga7
    clrf c
    rrf carga7,w ;
    movwf acarreo7
    movf original,w
    ;andlw b’11111111′
    movwf suma7
    movf suma7,w
    xorwf acarreo7,w
    andlw b’00000001′
    addwf acum6,w
    movwf acum7

    bsf status,rp0 ; cambio de banco para configurar salidas
    movlw b’00010000′
    movwf portA
    movlw b’00000000′
    movwf portB
    bcf status,rp0

    movf acum7,w
    movwf portB
    movf acum7,w
    movwf BIN
    clrf portb
    clrf portA
    call BIN8_BCD3
    movf BCDH,w
    movwf portA
    movf BCDL,w
    movwf PortB
    goto inicio

    ;Convertir binario a Bcd

    BIN8_BCD3
    clrf BCDH
    clrf BCDL
    BCD_HIGH
    movlw .100
    subwf BIN,f
    btfss STATUS,C
    goto SUMA_100
    incf BCDH,f
    goto BCD_HIGH
    SUMA_100
    movlw .100
    addwf BIN,f
    movlw 0x0F
    movwf BCDL
    BCD_LOW movlw .10
    subwf BIN,f
    btfss STATUS,C
    goto SUMA_10
    incf BCDL
    movlw 0x0F
    iorwf BCDL
    goto BCD_LOW
    SUMA_10 movlw .10
    addwf BIN,f
    movlw 0xF0
    andwf BCDL,f
    movf BIN,w
    iorwf BCDL,f
    return

    end

  36. De casualidad Tendrás algun Codigo en MPASM de Un Numero Binario de 10 bits a BCD¿??

  37. buenas este algoritmo tambien me sirve para hacer un contador de 0 a 59??

  38. Buenas compa una pregunta sobre el codigo, como podria cambiar la linea goto $+2 con otro tipo de instruccion que a lo mejor pueda hacer lo mismo que indicas sobre la referencia de linea del programa. Lo que pasa es que estoy tratando de probar tu codigo en una pequeña aplicacion “PICMICRO SIMULATOR & ensambler” de Android para ASM, y el detalle esta en que me marca error precisamete en esa linea goto $+2 no se porque. Ya que apenas estoy probando en este tipo de programacion la cual no se mucho, o mejor diho nada….(ˆ_ˆ)!!!!

    • Carlo, el símbolo “$” hace referencia a la línea de código en la que está escrita de modo que lo que tenemos ahí es un goto que hace que el contador de programa salte 2 líneas hacia adelante, hacia la línea “movlw b’00001111′”.

      Quizá la herramienta que utilizas no soporta ese símbolo así que lo que puedes hacer es cambiar ese goto para que apunte a una etiqueta. Sería hacer un cambio más o menos así:

              goto     SALTO
              goto     TERMINA_CONVERSION
      SALTO
              movlw    b'00001111'

      Pruebalo y ve si funciona.

      P.D. Seguramente wordpress quitará el poco formato que puede tener este fragmento de código pero aún así espero que te quede clara la idea.

      P.P.D. No se si viste la fecha de publicación del post pero tiene ya más de 9 años! Me acabas de regalar un muy buen viaje al pasado!

      Suerte!

      • Si me di cuenta!!! que el post es de hace años pero nunca esta demas desenpolvar las cosas jejeje.

        Con respecto a la linea ya hice el arreglo que me mencionas, pero en el funcionamiento noto algo extraño lo mas seguro es que sea yo que este mal. Pero al correr el codigo en la aplicacion paso a paso puedo notar que al llegar a la linea que dice call SUMA0x03 esta va a la respectiva rutina de sumarle 3 en caso de que algun valor sea mayor que 5, luego regresa a las lineas que siguen mas abajo. Sin embargo esta el detalle y es que nunca alcanza a tomar la linea de call SUMA0x30 el cual hace que vaya a la siguiente rutina en caso de ser necesario, aparte de que todo el tiempo se mantiene en la rutina de conversion, cuando en verdad lo que pienso es que si ya se termino la operacion de separar el numero en digitos este no deberia de seguir haciendo la conversion. O me equivoco, salvo que se haiga hecho para conversiones continuas del digito de entrada. Te muestro lo que tengo.

        include “p16f84.inc”

        CUENTA ;Esto lo agregue porque la aplicacion me da error con
        BCD_TEMP ; referencia a estas variables ya que me las pone como
        BCDH ; Undefined symbol ‘CUENTA, BCD_TEMP, BCDH, BCDL’
        BCDL
        ENDC

        BIN EQU 255 ;AQUI CARGO EL VALOR DE 255 A LA VARIABLE BIN

        ; AÑADIDO
        call BIN2BCD_RS3 ;LLAMO A LA FUNCION
        ; DESPLEGAR RESULTADO POR EL PUERTO B
        ;movf BCDH,w
        ;movwf PORTB
        ;swapf BCDL,w
        ;andlw 0x0F
        ;movwf PORTB
        ;movf BCDL,w
        ;andlw 0x0F
        ;movwf PORTB ;ESTO LO COPIE DE UN COMENTARIO ANTERIOR
        ;Pero veo que el puerto B siempre aparece como FF
        BIN2BCD_RS3
        clrf BCDH
        clrf BCDL
        movlw 0x08
        movwf CUENTA

        CONVERSION1
        bcf STATUS,C
        rlf BIN,f
        rlf BCDL,f
        decfsz CUENTA,f
        goto SALTO
        goto TERMINA_CONVERSION
        SALTO
        movlw b’00001111′
        andwf BCDL,w
        movwf BCD_TEMP
        movlw 0x05
        subwf BCD_TEMP,w
        btfsc STATUS,C
        call SUMA0x03
        movlw b’11110000′
        andwf BCDL,w
        movwf BCD_TEMP
        movlw 0x50
        subwf BCD_TEMP,w
        btfsc STATUS,C
        call SUMA0x30
        goto CONVERSION1
        TERMINA_CONVERSION
        return

        ;*******************************
        ;Subrutina que se encarga de
        ;sumar 3 al nible bajo de BCDL
        ;*******************************
        SUMA0x03
        movlw 0x03
        addwf BCDL,f
        btfss STATUS,C
        return
        rlf BCDH,f
        return

        ;*******************************
        ;Subrutina que se encarga de
        ;sumar 3 al nible alto de BCDL
        ;*******************************
        SUMA0x30
        movlw 0x30
        addwf BCDL,f
        btfss STATUS,C
        return
        rlf BCDH,f
        return

        A ver si me sacas la duda, y en que puedo estar mal

      • Sin duda el problema está en como estás definiendo BIN. Con la directiva EQU lo que haces es hacer que BIN sea una constante que siempre es 255. Lo que debes hacer es definirla como variable dentro del bloque CBLOCK y ENDC.

        Después antes de llamar la rutina BIN2BCD_RS3 tienes que cargar el número que deseas convertir en la variable BIN, algo así:

                movlw    d'255'
                movwf    BIN
                call     BIN2BCD_RS3
        

        Hace tiempo que no programo un PIC pero seguramente eso es lo que se ocupa. Pruébalo y verás que tal.


Leave a reply to micropic Cancel reply

Create a free website or blog at WordPress.com.
Entries and comments feeds.