assemblyatmega32

converting 16-bit number into digits for led display


I'm designing a calculator on atmega328p using assembly language, after performing the calculation I need to separate the result into digits to display them on LED matrix. Till now I wrote a code that does that with an 8-bit number (one register) and it's working correctly. However, when I start using two register for the high and low part of the number I'm not able to come up with a code that does the same.

the code for working with 8-bit number is attached below:

ldi r19, 0
HUNDS:
cpi resL, 100    ;compare low part of the result register with 100
brlo TENS
subi resL, 100
inc r19
rjmp HUNDS

TENS:         
st x+, r19    ;store hundreds counter in buffer for screen display (will be displayed on first screen block)
ldi r19, 0    ;reset counter for tens

TENS_Test:
cpi resL, 10
brlo UNITS
subi resL ,10
inc r19
rjmp TENS_Test

UNITS:
st x+, r19     ; store tens counter
st x+, resL    ; store units digit

Solution

  • if you want follow your approach, then one loop looks like this

             ldi zl, low(10000)
             ldi zh,high(10000)
    
             ldi r19, 0
    loop:
             cp  resL, zl
             cpc resH, zh
             brlo endLoop
             sub resL, zl
             sbc resH, zh
             inc r19
             rjmp loop
    endLoop:
    

    But this is not good approach. Better is use division by 10 and save remainders in reverse order. You don't need reinvent division routines. You can find it in Atmel application note AVR200: Multiply and Divide Routines.

    description is here

    source is here