cnos 发表于 2023-12-14 15:40:24

高效的uint转bcd子程序,把uint转成0000-65535.


分享一些好用的代码,挣点积分。
这个方法比用除法取模快很多。

void bin2bcd(unsigned int x,unsigned char *dst)
//整数转BCD码子程序,分离各个数字位
//参数1:要转换的整数,类型是unsigned int
//参数2:转换得到的结果要存到的地方(数组)
//输入参数:需要转换的整数,保存结果的数组
{
unsigned char i,j,k;
k = x;
x = x >> 2;
i = x >> 8;
j = (i + i + i) << 1;
if (i > 41)
    {
      i++;
      j+=6;
      }
j = j + x;
if ((unsigned char)x > j )
    {
      i++;
      j+=6;
      }
if (j > 249)
    {
      i++;
      j+=6;
      }
dst = i / 10;//分离得到的万(10000)位
dst = B;//分离得到的千(1000)位
dst = j / 25;//分离得到的百(100)位
dst = (B<<2 | k&3) / 10;//分离得到的十(10)位
dst = B;//分离得到的个(1)位
}

cnos 发表于 2023-12-14 15:59:54

编译完只占用这点资源
Program Size: data=16.0 xdata=0 code=204
转换一次仅花费159个指令周期。

#include <reg52.h>
void bin2bcd(unsigned int x,unsigned char *dst)
//整数转BCD码子程序,分离各个数字位
//参数1:要转换的整数,类型是unsigned int
//参数2:转换得到的结果要存到的地方(数组)
//输入参数:需要转换的整数,保存结果的数组
{
unsigned char i,j,k;
k = x;
x = x >> 2;
i = x >> 8;
j = (i + i + i) << 1;
if (i > 41)
    {
      i++;
      j+=6;
      }
j = j + x;
if ((unsigned char)x > j )
    {
      i++;
      j+=6;
      }
if (j > 249)
    {
      i++;
      j+=6;
      }
dst = i / 10;//分离得到的万(10000)位
dst = B;//分离得到的千(1000)位
dst = j / 25;//分离得到的百(100)位
dst = (B<<2 | k&3) / 10;//分离得到的十(10)位
dst = B;//分离得到的个(1)位
}
void main()
{
        unsigned char bcd_digit;
        unsigned int x;
        x=54215;
        bin2bcd(x,bcd_digit);
        while(1)
        {
                ;
        }
}

LAOXU 发表于 2023-12-14 19:18:49

这个代码思路确实新颖不错, 我改写的 51 可重入 printf 打印函数,int 类型输出, 原型就是用这个代码, 改写的

LAOXU 发表于 2023-12-14 19:19:24


$NOMOD51

NAME        INTASCPUSH

SP                DATA        081H
DPL                DATA        082H
DPH                DATA        083H

ACC                DATA        0E0H
B                DATA        0F0H
PSW                DATA        0D0H
F0                BIT        0D0H.5

?PR?_INTASCPUSH?INTASCPUSH               SEGMENT CODE
        PUBLIC        _IntAscPush
;
; char IntAscPush(unsigned int x)

        RSEG?PR?_INTASCPUSH?INTASCPUSH
_IntAscPush:
; {                                        in       x;   // x(R6,R7)
;   unsigned char i,j,len;        // i(R6), j(R5), len(R4)
;   unsigned char data *p;        // p(R1)
;                                   out;                // R1(SP缓冲区首址),len(R7)
;
                        POP                DPH
                        MOV        R1,SP
                        POP                DPL
;         j = (x>>8<<6 | (unsigned char)x>>2); // j(R5)
                        MOV        A,R6
                        SWAP         A
                        RLC        A
                        RLC        A
                        ANL        A,#0C0H
                        MOV        R5,A
                        MOV        A,R7
                        RRC        A
                        RRC        A
                        ANL        A,#03FH
                        ORL        A,R5
                        MOV        R5,A
;   i = x>>10;                          // i(R6),   i = (b15,b14,b13,b12,b11,b10)>>10
                        MOV        A,R6
                        RRC        A
                        RRC        A
                        ANL        A,#03FH
                        MOV        R6,A
;   if (i > 41)      i++;       
                        SETB         C
                        SUBB         A,#41
                        JC           $+3
                        INC        R6
;   j += (i+i+i)*2;               // j(R5),   j = i*6 + ((b9,b8,b7,b6,b5,b4,b3,b2)>>2)
                        MOV        A,R6
                        ADD        A,R6
                        ADD        A,R6
                        ADD        A,ACC
                        ADD        A,R5
                        MOV        R5,A
;   if (CY == 1) {i++; j += 6;}
                        JNC        $+6
                        INC        R6
                        ADD        A,#6
                        MOV        R5,A
;   if (j > 249) {i++; j += 6;}
                        MOV        A,R5
                        SETB         C
                        SUBB         A,#249
                        JC           $+7
                        INC        R6
                        MOV        A,#6
                        ADD        A,R5
                        MOV        R5,A
;         len=0,                          // len(R4)
                        MOV        R4,#0
                        MOV        A,R6
                        MOV        B,#10
                        DIV        AB
                        MOV        @R1,A
;   *p = i / 10;            //万位
;   if(*p!=0)                {p++; len++;}
                        JZ           INTASCPUSH_1
                        ADD         A,#'0'
                        PUSH        ACC
                        INC        R1
                        INC        R4
INTASCPUSH_1:
;   *p = B;               //千位
                        MOV        A,B
                        MOV        @R1,A
;         if(len || (*p!=0))        { p++; len++;}
                        ORL        A,R4
                        JZ                INTASCPUSH_2
                        MOV        A,@R1
                        ADD         A,#'0'
                        PUSH        ACC
                        INC        R1
                        INC        R4
INTASCPUSH_2:
;   *p = j / 25;            //百位
                        MOV        A,R5
                        MOV        B,#25
                        DIV        AB
                        MOV        @R1,A
;         if(len || (*p!='0'))        { p++; len++;}
                        JZ                INTASCPUSH_3
                        MOV        A,@R1
                        ADD         A,#'0'
                        PUSH        ACC
                        INC        R1
                        INC        R4
INTASCPUSH_3:
;   *p = (B*4 | (unsigned char)x%4) / 10;//十位
                        MOV        A,R7
                        ANL        A,#03H
                        MOV        R7,A                  
                        MOV        A,B
                        ADD        A,ACC
                        ADD        A,ACC
                        ORL        A,R7
                        MOV        B,#10
                        DIV        AB
                        MOV        @R1,A
;         if(len || (*p!='0'))        { p++; len++;}
                        JZ                INTASCPUSH_4
                        MOV        A,@R1
                        ADD         A,#'0'
                        PUSH        ACC
                        INC        R1
                        INC        R4
INTASCPUSH_4:
;   *p = B;               //个位
                        MOV        A,B
                        ADD         A,#'0'
                        PUSH        ACC
;   p++; len++;
                        INC        R1
                        INC        R4
                        CLR                A
                        PUSH        ACC
;         return len;
                        MOV        A,R1
                        CLR                C
                        SUBB        A,R4
                        MOV        R1,A
                        MOV        A,R4
                        MOV        R7,A
; }
                        PUSH        DPL
                        PUSH        DPH
                        RET       
; END OF _IntAscPush

                        END


页: [1]
查看完整版本: 高效的uint转bcd子程序,把uint转成0000-65535.