Entero binario sin signo de 32 bits a BCD de 8 bits en AVR ASM para ATtiny. ¿Cómo hacerlo más eficiente?

Escribí un programa en AVR ASMpara convertir 32-bitnúmeros binarios sin firmar a 8 digitdecimales basados ​​en shift-add-3. (Sé que 32-bittiene más de 8 dígitos, pero solo necesito 8).

La 32-bitentrada está en R16-R19(bajo-alto).

La 8 digitsalida está en R20-R24(bajo-alto), 2 números / byte, uno en el nibble inferior, uno en el nibble superior.

Mi problema: se necesitan ~1500 ciclos para calcular un 16-bitnúmero y ~2000 ciclos para calcular un 32-bit.

¿Alguien puede sugerirme un método más rápido y profesional para esto? Ejecutar un procedimiento de ciclo 2000 en un ATtiny at 32,768 Khzno es algo con lo que me sienta cómodo.

Mapa de uso de memoria:

Mapa de memoria para BinaryToBCD

Definiciones:

.def    a0  =   r16
.def    a1  =   r17
.def    a2  =   r18
.def    a3  =   r19

.def    b0  =   r20
.def    b1  =   r21
.def    b2  =   r22
.def    b3  =   r23

.def    i   =   r24
.def    j   =   r25

El código:

BinaryToBCD:
    clr     b0
    clr     b1
    clr     b2
    clr     b3
    ldi     i,  32
    sts     0x0068, i       ;(SRAM s8)

BinaryToBCD_1:
    clc
    rol     a0
    rol     a1
    rol     a2
    rol     a3
    rol     b0
    rol     b1
    rol     b2
    rol     b3

    lds     i, 0x0068       ;(SRAM s8)
    dec     i
    sts     0x0068, i       ;(SRAM s8)
    brne    BinaryToBCD_2
    ret

BinaryToBCD_2:
    cpi     b0,     0
    breq    BinaryToBCD_3
    mov     i,      b0
    rcall   Add3ToNibbles
    mov     b0,     i

BinaryToBCD_3:
    cpi     b1,     0
    breq    BinaryToBCD_4
    mov     i,      b1
    rcall   Add3ToNibbles
    mov     b1,     i

BinaryToBCD_4:
    cpi     b2,     0
    breq    BinaryToBCD_5
    mov     i,      b2
    rcall   Add3ToNibbles
    mov     b2,     i

BinaryToBCD_5:
    cpi     b3,     0
    breq    BinaryToBCD_1
    mov     i,      b3
    rcall   Add3ToNibbles
    mov     b3,     i
    rjmp    BinaryToBCD_1


Add3ToNibbles:
    mov     j,      i
    andi    j,      0b00001111
    cpi     j,      5
    in      j,      SREG
    sbrs    j,      0
    subi    i,      -3

    mov     j,      i
    swap    j
    andi    j,      0b00001111
    cpi     j,      5
    in      j,      SREG
    sbrs    j,      0
    subi    i,      -48
    ret
¿Qué tal una tabla de consulta y explotar el hecho de que es triangular?
¿Por qué no usar osciladores internos más rápidos?
Cuéntame más sobre la tabla y la "triangularidad", no sé a qué te refieres. No se puede usar un Osc más rápido, porque este chip también administra la hora y la fecha. 32768 es la precisión más alta, con esto solo necesito un desbordamiento de 16 * 2 bits en el temporizador.
@GáborDani Lo que quise decir fue tener una matriz de números decimales con un byte por dígito por cada 2^n, como (3,2,7,6,8),(1,6,3,8,4),( 0,8,1,9,2). Luego, revisa los bits individuales del número binario y agrega los números a una matriz de 8 bytes (un byte para cada dígito). A medida que pasa del bit 31 al 0, los decimales se acortan, por lo que se requieren menos adiciones (eso es lo que quise decir con triangularidad).
trataría de escribirlo en c y vería la salida del compilador (no olvide activar la optimización) para quizás aprender algunos trucos para aplicar en mi propio código
No responder a la q real. pero como sugirió Golaz, debería ser posible ejecutar ATTiny a una frecuencia de reloj más alta (usando el oscilador interno) y ejecutar un temporizador a 32k para rastrear el tiempo real; Si puede decirnos el número de parte, podríamos asegurarlo.

Respuestas (2)

Esto se basa en el enfoque de Venny (Venny lo llamó triangulación), expresado en una "pseudo-C":

uint32 x; // input variable to convert

w = { 2, 1, 4, 7, 4, 8, 3, 6, 4, 8 }; // 2^31
r = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // initial result = 0

for (i = 31; i >= 0; i --)
{
   if ( 2^i  AND x )  // is x's bit i up?
      add(r, w);      // if yes, 1 ASCII ADD and 9 ASCII ADD w/CARRY MAX
   divide(w, 2)       // 10 SHIFT RIGHT MAX
}

Las rutinas sumar y dividir no son una explicación necesaria, en mi opinión.