-3

What is algorithm of converting 8 bit binary to 16 bit BCD?

for example:

how can i do this?

1111 1111 (binary) -> 0000 0010 0101 0101

2 Answers2

2

The fastest computational method would be a modification of the "bin2BCD8" routine as described in AVR204. Subtract 100 until the number is less than 100, incrementing a single byte counter (in an even register) each time. Then do the same for 10, with the counter in the register after the hundreds counter. Use SWAP to move the tens counter to the high nibble, add the units remainder, and return the 16-bit register value.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 2
    That is not the fastest, be careful stating such things ;) A lookup table is probably faster, but costs memory. – Jester Mar 13 '15 at 19:01
  • @Jester: Fair enough. Amended. – Ignacio Vazquez-Abrams Mar 13 '15 at 19:02
  • Not even that is true. The atmega16 has a hardware multiplier, so I bet you can do better than looping (on average). Well, maybe not, but it's a close call. Would have to compare actual implementations :) – Jester Mar 13 '15 at 19:28
0

You can jump to find_hundreds (after clearing CL and CH) to convert a single 8-bit value stored in FL (AVR 8-bit instruction set).

.DEF FL = r17
.DEF FH = r18
.DEF CL = r19
.DEF CH = r20

; input:
;     FH:FL registers holding hex value
; output:
;     FH:FL registers holding converted BCD value
hex_to_bcd:
    ldi CL, 0
    ldi CH, 0
find_thousands:
    subi FL, low(1000)
    sbci FH, high(1000)
    brmi thousands_found ; branch if minus
    subi CH, -16
    rjmp find_thousands;
thousands_found:
    subi FL, low(-1000)
    sbci FH, high(-1000)
find_hundreds:
    subi FL, low(100)
    sbci FH, high(100)
    brmi hundreds_found 
    subi CH, -1
    rjmp find_hundreds;
hundreds_found:
    subi FL, low(-100)
    sbci FH, high(-100)
find_tens:
    subi FL, low(10)
    sbci FH, high(10)
    brmi tens_found      
    subi CL, -16
    rjmp find_tens;
tens_found:
    subi FL, low(-10)
    sbci FH, high(-10)
find_ones:
    subi FL, low(1)
    sbci FH, high(1)
    brmi ones_found 
    subi CL, -1
    rjmp find_ones;
ones_found:
    subi FL, low(-1)
    sbci FH, high(-1)
    mov FL, CL
    mov FH, CH
MMR
  • 1
  • Once you've reduce the number below 100, can't you skip the high-half `sbci`? The high half of every number below 128 is 0, so `sbci r18, 0` with no borrow is just a waste of instructions. (So is `subi FL, -1` after `ones_found:`, right before you overwrite FL and FH.) Also, can't you arrange things (including initial counter values) so you can `subi CH, -16` *before* FL, so you can use the opposite of `brmi` as the loop branch, instead of needing a separate `rjmp`. Like maybe `ldi CL, 0xEF`, if I have that right: the high nibble will get 2 extra increments, one from carry-out in the low. – Peter Cordes Apr 23 '21 at 13:16