搜索
bottom↓
回复: 97

一个速度较快的 int 数转换为BCD的程序【恢复】

[复制链接]

出0入0汤圆

发表于 2008-11-20 16:51:06 | 显示全部楼层 |阅读模式
在LED显示或者LCD显示中,经常要用到字符的显示,这时就要把数值转换为BCD数。经常用到的是除法以及求余,这个方法太慢,为了一个显示,把整个程序的速度拖得很慢是不是不划算。另外网上也有51的汇编代码,但是本人不太用汇编, C语言来得直观方便。

unsigned int t;

char buffer[5]={0,0,0,0,0};



void HexToBCD(unsigned int t)

{

        char i=0;

        unsigned int j=0;

         for(i=0,j=0;j<t-10000;i++,j+=10000)

        {}

        buffer[4]=i;    //万位

        t=t-j;

        for(i=0,j=0;j<t-1000;i++,j+=1000)

        {}

        buffer[3]=i;    //千位

        t=t-j;

        for(i=0,j=0;j<t-100;i++,j+=100)

        {}

        buffer[2]=i;    //百位

        t=t-j;

        for(i=0,j=0;j<t-10;i++,j+=10)

        {}

        buffer[1]=i;   //十位

        buffer[0]=t-j; //个位

}





void main()

{

        unsigned int x;

        x=45535;

        HexToBCD(x);        

        while(1);

}



点击此处下载 ourdev_505534.rar(文件大小:10K) (原文件名:HexToBCD.rar) 

本贴被 dd123 编辑过,最后修改时间:2008-11-20,16:55:32.

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2008-11-20 17:16:13 | 显示全部楼层
有创意,顶一个

出0入0汤圆

发表于 2008-11-20 17:20:17 | 显示全部楼层
不是我打击楼主,其实你用了unsigned int  j,在获取万千百十个位时候,有可能进行多次加法,并且还要使用unsigned int 数据进行判断,速度也不是快很多,不信可以调试看看。如果是unsigned char类型数据则令当别论。

出0入0汤圆

发表于 2008-11-20 17:40:18 | 显示全部楼层
1.同时求余数和商,应该使用除法库函数,这样只算一次除法。

  不要直接用/和%,这会算两次除法。



2.每算一次除法,除法位数减半。





  比如要将一个16进制数(用16位2进制数表示)转换成4位10进制数,

  

  第一步,一次16位除法,得到10进制数高两位位和低两位,

  第二步,两次8位除法, 得到十进制数全部8位。



共:一次16位除法,两次8位除法。





另:

外关于除法库函数,标准C语言只提供了三个,div和ldiv,和lldiv.都是有符号除法。

对于AVRGCC,实际上8位,16位,32位,64位有符号,无符号除法库函数都有。

只是非标准C要求的除法库函数没有显式包含在头文件里。

 



本贴被 ATmega32 编辑过,最后修改时间:2008-11-21,15:20:42.

出0入0汤圆

发表于 2008-11-20 17:49:36 | 显示全部楼层
用减法代替除法。

出0入0汤圆

发表于 2008-11-20 17:52:32 | 显示全部楼层
还是查表最快

出0入0汤圆

发表于 2008-11-20 22:53:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-11-20 23:10:32 | 显示全部楼层
真的需要快,就查表,如果没有那种要求,就算吧,别计较太多了

出0入0汤圆

 楼主| 发表于 2008-11-21 06:42:54 | 显示全部楼层
回【2楼】 lzf713 

请教用unsigned char 实现无符号整型的转换方法。



回【3楼】 ATmega32 上官金虹

在8位机里面,多次用除法和乘法对转换速度的影响是不是很大呢?我的原则是,能不用乘除法时则尽量不用乘除法。



回【7楼】 avenbbs 

如果用查表的方法,对于65535这样的数,需要建一个多大的表?



真诚请教与探讨。

出0入0汤圆

发表于 2008-11-21 07:17:37 | 显示全部楼层
【3楼】 ATmega32 上官金虹

1.同时求余数和商,应该使用除法库函数,这样只算一次除法。 

  不要直接用/和%,这会算两次除法。 

对于AVRGCC,实际上8位,16位,32位,64位有符号,无符号除法库函数都有。 

只是非标准C要求的除法库函数没有显式包含在头文件里。 

=====================================================================

上官你好:这个具体如何来做?

我现在是用/和%来实现的,估计会算两次除法。

比如这段程序:



uint temp1= 1234;



a = temp1/1000;        //千位

b = (temp%1000)/100;   //百位                

c = (temp%100)/10 ;    //十位                        

d = temp1%10 ;             //个位                



用你的方法,应该可以更简化吧。

出0入0汤圆

发表于 2008-11-21 07:58:03 | 显示全部楼层
我也象楼上这样用的

出0入0汤圆

发表于 2008-11-21 08:57:57 | 显示全部楼层
#include <stdlib.h>

#include <stdint.h>



typedef struct  udiv8_t   

{  

uint8_t quot;  

uint8_t rem;  

}udiv8_t;  



typedef struct  div8_t   

{  

int8_t quot;  

int8_t rem;  

}div8_t;  



typedef struct  udiv16_t   

{uint16_t quot;  

uint16_t rem;  

}udiv16_t;  



#define  div16_t        div_t  





typedef struct  udiv32_t   

{  

uint32_t quot;  

uint32_t rem;  

}udiv32_t;  



#define  div32_t         ldiv_t  





extern div8_t div8(int8_t,int8_t) __asm__("__divmodqi4") __ATTR_CONST__ ;  

extern udiv8_t udiv8(uint8_t,uint8_t) __asm__("__udivmodqi4") __ATTR_CONST__ ;  

extern div16_t div16(int16_t,int16_t) __asm__("__divmodhi4") __ATTR_CONST__ ;  

extern udiv16_t udiv16(uint16_t,uint16_t) __asm__("__udivmodhi4") __ATTR_CONST__ ;  

extern div32_t div32(int32_t,int32_t) __asm__("__divmodsi4") __ATTR_CONST__ ;  

extern udiv32_t udiv32(uint32_t,uint32_t) __asm__("__udivmodsi4") __ATTR_CONST__ ;  







unsigned char data[4] ;



int main() 

{  

  unsigned int temp= 1234;

  udiv16_t qr16;

  udiv8_t  qr8;



  qr16=udiv16(temp,100);

  

  qr8=udiv8(qr16.quot,10);

  data[3]=qr8.quot;

  data[2]=qr8.rem;



  qr8=udiv8(qr16.rem,10);

  data[1]=qr8.quot;

  data[0]=qr8.rem;



  while(1);

}  





int main() 

{  

  92:        1f 93               push        r17

 unsigned int temp= 1234;

  udiv16_t qr16;

  udiv8_t  qr8;



  qr16=udiv16(temp,100);

  94:        64 e6               ldi        r22, 0x64        ; 100

  96:        70 e0               ldi        r23, 0x00        ; 0

  98:        82 ed               ldi        r24, 0xD2        ; 210

  9a:        94 e0               ldi        r25, 0x04        ; 4

  9c:        0e 94 6f 00         call        0xde        ; 0xde <__udivmodhi4>   //第一次除法,16位无符号

  a0:        26 2f               mov        r18, r22

  a2:        18 2f               mov        r17, r24

  

  qr8=udiv8(qr16.quot,10);

  a4:        6a e0               ldi        r22, 0x0A        ; 10

  a6:        82 2f               mov        r24, r18

  a8:        0e 94 63 00         call        0xc6        ; 0xc6 <__udivmodqi4>  //第二次除法,8位无符号

  data[3]=qr8.quot;

  ac:        80 93 63 00         sts        0x0063, r24

  data[2]=qr8.rem;

  b0:        90 93 62 00         sts        0x0062, r25



  qr8=udiv8(qr16.rem,10);

  b4:        6a e0               ldi        r22, 0x0A        ; 10

  b6:        81 2f               mov        r24, r17

  b8:        0e 94 63 00         call        0xc6        ; 0xc6 <__udivmodqi4>   //第三次除法,8位无符号

  data[1]=qr8.quot;

  bc:        80 93 61 00         sts        0x0061, r24

  data[0]=qr8.rem;

  c0:        90 93 60 00         sts        0x0060, r25

  c4:        ff cf               rjmp        .-2              ; 0xc4 <main+0x32>

出0入0汤圆

发表于 2008-11-21 09:08:35 | 显示全部楼层
unsigned char data[4] ;

unsigned int temp= 1234;



int main() 

{  



data[3] = temp/1000;        //千位 

data[2] = (temp%1000)/100;   //百位                 

data[1] = (temp%100)/10 ;    //十位                         

data[0] = temp%10 ;          //个位        



  while(1);

}  





int main() 

{  

  92:        20 91 60 00         lds        r18, 0x0060

  96:        30 91 61 00         lds        r19, 0x0061

  9a:        c9 01               movw        r24, r18

  9c:        68 ee               ldi        r22, 0xE8        ; 232

  9e:        73 e0               ldi        r23, 0x03        ; 3

  a0:        0e 94 72 00         call        0xe4        ; 0xe4 <__udivmodhi4>  第一次除法,16位无符号

  a4:        60 93 65 00         sts        0x0065, r22







data[3] = temp/1000;        //千位 

data[2] = (temp%1000)/100;   //百位                 

  a8:        c9 01               movw        r24, r18

  aa:        68 ee               ldi        r22, 0xE8        ; 232

  ac:        73 e0               ldi        r23, 0x03        ; 3

  ae:        0e 94 72 00         call        0xe4        ; 0xe4 <__udivmodhi4>    第二次除法,16位无符号

  b2:        64 e6               ldi        r22, 0x64        ; 100

  b4:        70 e0               ldi        r23, 0x00        ; 0

  b6:        0e 94 72 00         call        0xe4        ; 0xe4 <__udivmodhi4>    第三次除法,16位无符号

  ba:        60 93 64 00         sts        0x0064, r22

data[1] = (temp%100)/10 ;    //十位                         

  be:        c9 01               movw        r24, r18

  c0:        64 e6               ldi        r22, 0x64        ; 100

  c2:        70 e0               ldi        r23, 0x00        ; 0

  c4:        0e 94 72 00         call        0xe4        ; 0xe4 <__udivmodhi4>    第四次除法,16位无符号

  c8:        6a e0               ldi        r22, 0x0A        ; 10

  ca:        70 e0               ldi        r23, 0x00        ; 0

  cc:        0e 94 72 00         call        0xe4        ; 0xe4 <__udivmodhi4>    第五次除法,16位无符号

  d0:        60 93 63 00         sts        0x0063, r22

data[0] = temp%10 ;          //个位        

  d4:        c9 01               movw        r24, r18

  d6:        6a e0               ldi        r22, 0x0A        ; 10

  d8:        70 e0               ldi        r23, 0x00        ; 0

  da:        0e 94 72 00         call        0xe4        ; 0xe4 <__udivmodhi4>    第六次除法,16位无符号

  de:        80 93 62 00         sts        0x0062, r24

  e2:        ff cf               rjmp        .-2              ; 0xe2 <main+0x50>

本贴被 ATmega32 编辑过,最后修改时间:2008-11-21,09:09:37.

出0入0汤圆

发表于 2008-11-21 09:15:26 | 显示全部楼层
上官大侠在C上的造诣真的不一般啊!请推荐几本关于C的好书,谢谢!

出0入0汤圆

发表于 2008-11-21 09:20:54 | 显示全部楼层
void HexToBCD(unsigned int t) 

{ 

        char i=0; 

        unsigned int j=0; 

         for(i=0,j=0;j<t-10000;i++,j+=10000) 

        {} 

        buffer[4]=i;    //万位 

        t=t-j; 

        for(i=0,j=0;j<t-1000;i++,j+=1000) 

        {} 

        buffer[3]=i;    //千位 

        t=t-j; 

        for(i=0,j=0;j<t-100;i++,j+=100) 

        {} 

        buffer[2]=i;    //百位 

        t=t-j; 

        for(i=0,j=0;j<t-10;i++,j+=10) 

        {} 

        buffer[1]=i;   //十位 

        buffer[0]=t-j; //个位 

} 





------------------------------------------------------



BUG

出0入0汤圆

发表于 2008-11-21 09:55:36 | 显示全部楼层
15楼的程序和楼主的其实没多大差别,只是将i改成char型,且还有化简空间,如下可以少一个中间变量j和少几次算.



void HexToBCD(unsigned int t) 

{ 

        char i=0; 

        for(i=0;t>=10000;i++,t-=10000) 

        {} 

        buffer[4]=i;    //万位 

        for(i=0;t>=1000;i++,t-=1000) 

        {} 

        buffer[3]=i;    //千位 

        for(i=0;t>=-100;i++,t-=100) 

        {} 

        buffer[2]=i;    //百位 

        for(i=0;t>=10;i++,t-=10) 

        {} 

        buffer[1]=i;    //十位 

        buffer[0]=t;    //个位 

} 

出0入0汤圆

发表于 2008-11-21 10:00:13 | 显示全部楼层
我只是指出它有BUG

出0入0汤圆

发表于 2008-11-21 10:01:41 | 显示全部楼层
15楼的程序和楼主的其实没多大差别,只是将i改成char型,且还有化简空间,如下可以少一个中间变量j和少几次算. 



void HexToBCD(unsigned int t)  

{  

        char i=0;  

        for(i=0;t>=10000;i++,t-=10000)  

        {}  

        buffer[4]=i;    //万位  

        for(i=0;t>=1000;i++,t-=1000)  

        {}  

        buffer[3]=i;    //千位  

        for(i=0;t>=-                  100;i++,t-=100)  

        {}  

        buffer[2]=i;    //百位  

        for(i=0;t>=10;i++,t-=10)  

        {}  

        buffer[1]=i;    //十位  

        buffer[0]=t;    //个位  

}  





----------------------------------------------------



同样又是BUG

本贴被 foreverwolfer 编辑过,最后修改时间:2008-11-21,10:11:30.

出0入0汤圆

发表于 2008-11-21 10:37:48 | 显示全部楼层
呵呵挺热闹的。也贴一段我写的,比直接用/和%快很多,如有BUG请指正。大家有更好的也贴上来吧:)



// 调用参数 (显示缓冲首地址, 要显示的16位整数); 例: Hex_BCD(DispBuf, temp)

void Hex_BCD(unsigned char *p, unsigned int i)

{

    unsigned char n;

    for (n=0; i>=10000; ++n)

    {

        i -= 10000;                // 万位

    }

    *p++ = n;

    for (n=0; i>=1000; ++n)

    {

        i -= 1000;

    }

    *p++ = n;                      // 千位

    for (n=0; i>=100; ++n)

    {

        i -= 100;

    }

    *p++ = n;                      // 百位

    for (n=0; i>=10; ++n)

    {

        i -= 10;

    }

    *p++ = n;                      // 十位

    *p++ = i;                      // 个位

}

出0入0汤圆

发表于 2008-11-21 10:52:07 | 显示全部楼层
//使用例子



unsigned char DispBuf[6];



void main (void)

{

    unsigned int temp=0xFFFF;

    //。。。。

    while (1)

    {

        //。。。。

        Hex_BCD(DispBuf, temp);   // 将temp转为十进制显示

    }

}



楼上"万位"注释没放正:)

出0入0汤圆

发表于 2008-11-21 11:26:18 | 显示全部楼层
【14楼】 418425051 阿宽

《C primer Plus》和C99标准文档。



我C语言其实也很一般。



本贴被 ATmega32 编辑过,最后修改时间:2008-11-21,17:35:04.

出0入0汤圆

发表于 2008-11-21 12:29:55 | 显示全部楼层
呵呵,更正16楼笔误,t>=-100,多了个负号。Keil仿真,用最大值 65535,函数执行时长为352周期。



3楼方法只一次int除法是142周期,可见16楼的没什么优势

本贴被 cowboy 编辑过,最后修改时间:2008-11-21,12:34:08.

出0入0汤圆

 楼主| 发表于 2008-11-21 12:58:12 | 显示全部楼层
完整的程序如下:

//最大转换数为 65535

unsigned int t;

char buffer[5]={0,0,0,0,0};



void HexToBCD(unsigned int t)

{

        char i=0;

        unsigned int j=0;

    if(t>=10000)

        {

            for(i=0,j=0;j<=t-10000;i++,j+=10000)

           {}

           buffer[4]=i;    //万位

           t=t-j;

        }

        if(t>=1000)

        {

           for(i=0,j=0;j<=t-1000;i++,j+=1000)

           {}

           buffer[3]=i;    //千位

           t=t-j;

        }

        if(t>=100)

        {

           for(i=0,j=0;j<=t-100;i++,j+=100)

           {}

           buffer[2]=i;    //百位

           t=t-j;

        }

        if(t>=10)

        {

           for(i=0,j=0;j<=t-10;i++,j+=10)

           {}

           buffer[1]=i;   //十位

           buffer[0]=t-j; //个位

        }

        else buffer[0]=t;

}





void main()

{

        unsigned int x;

        x=65535;

        HexToBCD(x);        

        while(1);

}



运行周期与时间测试:(ICCAVR6.3)---函数运行周期最大为315,时间为40us



 (原文件名:001.jpg) 





 (原文件名:002.jpg) 

出0入0汤圆

 楼主| 发表于 2008-11-21 14:21:57 | 显示全部楼层
参照 【16楼】 cowboy 的程序,改如下,运行时间为30us,运行周期为240



unsigned t;

char buffer[5]={0,0,0,0,0};



void HexToBCD(unsigned int t)

{

   char i;

   if(t>=10000)

   {

      for(i=0;t>=10000;i++,t-=10000)

      {}

      buffer[4]=i;         //万位

   }

   if(t>=1000)

   {

      for(i=0;t>=1000;i++,t-=1000)

      {}

      buffer[3]=i;         //千位

   }

   if(t>=100)

   {

      for(i=0;t>=100;i++,t-=100)

      {}

      buffer[2]=i;         //百位

   }

   if(t>=10)

   {

      for(i=0;t>=10;i++,t-=10)

      {}

      buffer[1]=i;         //十位

      buffer[0]=t;         //个位

   }

   else buffer[0]=t;       //个位

}



void main()

{

   unsigned int x;

   x=65535;

   HexToBCD(x);

   while(1);

}

出0入0汤圆

发表于 2008-11-21 14:39:24 | 显示全部楼层
【24楼】 dd123 ,没必要用那几个if判断语句了,在for里面已隐含了这个判断,你这样改,反而有错,当某位为0时,buffer[n]值不更新.

似乎没必要这样再搞下去,按【3楼】 ATmega32 上官金虹方法最快,即一次16位除法,两次8位除法.

出0入0汤圆

发表于 2008-11-21 14:45:06 | 显示全部楼层
谢谢上官及楼上诸位!学习一下。
看了12/13楼上官的对比,看来差别很大,我把程序改一下看看。

本贴被 999999 编辑过,最后修改时间:2008-11-21,14:48:07.

出0入0汤圆

 楼主| 发表于 2008-11-21 16:00:49 | 显示全部楼层
我没有装GCC软件,所以无法验证 上官金虹 程序的快慢。

上面我重改过的程序确实是画蛇添足,把if语句及最后1个else语句去掉一样运行。

另外,
 cowboy 在【22楼】说:  3楼方法只一次int除法是142周期,可见16楼的没什么优势
又在【25楼】说:按【3楼】 ATmega32 上官金虹方法最快,即一次16位除法,两次8位除法。

是不是验证了一下?但据上面 上官司金虹 的测试,有399个时钟周期,不知快在哪里?

出0入0汤圆

发表于 2008-11-21 16:01:27 | 显示全部楼层
楼上,你把函数写个这种格式,
void HexToBCD(unsigned char *p,unsigned int t) 
并确保函数没有被优化成内联函数,再来比较。

本贴被 ATmega32 编辑过,最后修改时间:2008-11-21,16:23:15.

出0入0汤圆

发表于 2008-11-21 16:13:04 | 显示全部楼层
typedef union {
        __u8  byte[2];
        __u16 bank;
}__u16_bank_t;

typedef union {
        __u8  byte[4];
        __u32 bank;
}__u32_bank_t;

//16进制到压缩BCD码
__u16 tools_hex_to_bcd(__u8 * buffer, __u16 data_word)
{
        __u32_bank_t TempA;
        __u32_bank_t TempB;
        __u8 i,Temp;

        TempA.bank = data_word;
        TempB.bank = 0;

        for(i = 0;i < 16;i ++) {
                TempA.bank <<= 1;
                if (TempA.byte[2] & 0x01) {
                        TempB.bank <<= 1;
                        TempB.bank |= 0x01;
                }
                else TempB.bank <<= 1;

                Temp = TempB.byte[0] + 0x03;
                if (i < 15) {
                        if (Temp & 0x08) TempB.byte[0] = Temp;
                        Temp = TempB.byte[0] + 0x30;
                        if (Temp & 0x80) TempB.byte[0] = Temp;

                        Temp = TempB.byte[1] + 0x03;
                        if (Temp & 0x08) TempB.byte[1] = Temp;
                        Temp = TempB.byte[1] + 0x30;
                        if (Temp & 0x80) TempB.byte[1] = Temp;

                        Temp = TempB.byte[2] + 0x03;
                        if (Temp & 0x08) TempB.byte[2] = Temp;
                        Temp = TempB.byte[2] + 0x30;
                        if (Temp & 0x80) TempB.byte[2] = Temp;
                }
        }


        return TempB.bank;
}

出0入0汤圆

发表于 2008-11-21 16:29:05 | 显示全部楼层

 (原文件名:QQ截图未命名.jpg) 

程序修改前后是有区别,再次谢谢上官


本贴被 999999 编辑过,最后修改时间:2008-11-21,16:30:46.

出0入0汤圆

发表于 2008-11-21 16:53:59 | 显示全部楼层
调试了【21楼】 ATmega32 上官金虹 的程序发现出错


 (原文件名:div.JPG) 

buf1是上官金虹的程序结果
buf2是我19楼的程序结果

本贴被 shinehjx 编辑过,最后修改时间:2008-11-21,16:57:48.

出0入0汤圆

发表于 2008-11-21 16:54:23 | 显示全部楼层
void HEX_TO_BCD1(unsigned char *p,unsigned int  data)  
{ 

  udiv16_t divmod16;  
  udiv8_t  divmod8;  

  divmod16=udiv16(data,100);  
    
  divmod8=udiv8(divmod16.quot,10);  
  p[3]=divmod8.quot;  
  p[2]=divmod8.rem;  

  divmod8=udiv8(divmod16.rem,10);  
  p[1]=divmod8.quot;  
  p[0]=divmod8.rem;  
} 


-------------------------------------------------

  加入p[4]后比较才公平点

出0入0汤圆

发表于 2008-11-21 17:15:46 | 显示全部楼层
上官金虹 的程序是要求data要少于10000

出0入0汤圆

发表于 2008-11-21 17:38:32 | 显示全部楼层
我仿真的结果显示,并不是ATmega32 上官金虹的方法快,而是减法较快

楼主的程序和我19楼的程序基本一样的(我只是运用了指针),都可能简化成如下
void HexToBCD(unsigned int t) 
{ 
   unsigned char i; 
   for(i=0;t>=10000;i++,t-=10000);
   buffer[4]=i;         //万位 
   for(i=0;t>=1000;i++,t-=1000);
   buffer[3]=i;         //千位 
   for(i=0;t>=100;i++,t-=100);
   buffer[2]=i;         //百位 
   for(i=0;t>=10;i++,t-=10); 
   buffer[1]=i;         //十位 
   buffer[0]=t;         //个位 
} 

再变为用指针的格式(使用指针自加的方法较为灵活,当显示多个整数或改变显示位置时会更为方便)
void HexToBCD(unsigned char *p,unsigned int t)
{ 
   unsigned char i; 
   for(i=0;t>=10000;i++,t-=10000);
   *p++=i;         //万位 
   for(i=0;t>=1000;i++,t-=1000);
   *p++=i;         //千位 
   for(i=0;t>=100;i++,t-=100);
   *p++=i;         //百位 
   for(i=0;t>=10;i++,t-=10); 
   *p++=i;         //十位 
   *p=t;         //个位 
}

调试图片

 (原文件名:1.JPG) 


 (原文件名:2.JPG) 


 (原文件名:3.JPG) 


 (原文件名:结果.JPG) 

工程文件,有兴趣的朋友试下ourdev_507099.rar(文件大小:14K) (原文件名:test.rar) 

------修改原因:补上图片及文件


本贴被 shinehjx 编辑过,最后修改时间:2008-11-21,17:45:58.

出0入4汤圆

发表于 2008-11-21 18:40:23 | 显示全部楼层
关注~

出0入0汤圆

发表于 2008-11-21 20:22:40 | 显示全部楼层
的确是减法快,看来我是井底只蛙了。


对于无符号除法

如果被除数和除数的值相差不大,即除得的商值比较小,那么用减法更快。
如果被除数和除数的值相差很大,即除得的商值比较大,那么用除法更快。

临界值肯能就在10左右。

本贴被 ATmega32 编辑过,最后修改时间:2008-11-22,09:10:48.

出0入0汤圆

发表于 2008-11-21 20:40:01 | 显示全部楼层
发一个,大家看看快步快
//==========一个十六进制的INT型转换为一个压缩的BCD码INT型=========
unsigned int IntHEXToIntBCD( unsigned int temp )  
{
        unsigned char a,b;
    unsigned int c;    
    a = temp % 10;
    a += ( ( ( temp / 10 ) % 10 ) << 4 );
    temp = temp / 100;
    b = temp % 10;
    b += ( ( ( temp / 10 ) % 10 ) << 4 ); 
    c = b;
    c = ( c << 8 );
    c += a;   
    return( c ); 
}

出0入0汤圆

发表于 2008-11-21 23:13:54 | 显示全部楼层
呵呵,又想到一个更快的方法,用类似A/D转换的逐次逼近法,只需最多11次无符号整型减法就完成。
void HexToBCD(unsigned int t)  
{  
  unsigned char i=0;
/*if (t>=40000) {i=4; t-=40000;}   //如果t<=9999,则这部分可不用。
  if (t>=20000) {i+=2;t-=20000;}
  if (t>=10000) {i++; t-=10000;}
  buffer[4]=i;                     
  i=0;
*/
  if (t>=8000) {i=8; t-=8000;}
  if (t>=4000) {i+=4;t-=4000;}
  if (t>=2000) {i+=2;t-=2000;}
  if (t>=1000) {i++; t-=1000;}
  buffer[3]=i;
  i=0;
  if (t>=800) {i=8; t-=800;}
  if (t>=400) {i+=4;t-=400;}
  if (t>=200) {i+=2;t-=200;}
  if (t>=100) {i++; t-=100;}
  buffer[2]=i;
  i=0;
  if (t>=80) {i=8; t-=80;}
  if (t>=40) {i+=4;t-=40;}
  if (t>=20) {i+=2;t-=20;}
  if (t>=10) {i++; t-=10;}
  buffer[1]=i;
  buffer[0]=t;
}

出0入0汤圆

发表于 2008-11-22 09:16:50 | 显示全部楼层
学习了。

楼上的程序应该是最快的了。

出0入0汤圆

发表于 2008-11-22 09:30:04 | 显示全部楼层
写个汇编的更快!
呵呵!

出0入0汤圆

发表于 2008-11-22 10:04:29 | 显示全部楼层
38楼 cowboy 的方法有创意,综合也较快,AVR 8M下调试由0~65535连续转换,耗时 1027.26ms

34楼的方法耗时 1628.71ms

出0入0汤圆

发表于 2008-11-22 10:17:57 | 显示全部楼层
那仿真软件用的啥啊?

出0入0汤圆

发表于 2008-11-22 10:47:35 | 显示全部楼层
进一步提速,可在t<200时,用一 char型变量代替t进行运算,估计可再快10%~20%
别,象51有硬件乘除法,则个位和十位数不必用比较求行,用8位除法更快.

出0入0汤圆

 楼主| 发表于 2008-11-22 10:54:32 | 显示全部楼层
【38楼】 cowboy 把减法运算转换发挥到极至了。是呵,当t<200时完全可以改用char类型运算了。

出0入0汤圆

发表于 2008-11-22 11:51:29 | 显示全部楼层
按43楼cowboy的方法提速成功,由原来的 1027.26ms 缩为 969.92ms

// 测试程序
unsigned char buf[5];
unsigned int temp;
void HexToBCD(unsigned char *p, unsigned int t);

int main()  
{  
 temp = 0;
 while(1)
 {
  HexToBCD(buf,temp);
  if (temp == 0xFFFF)
  {
    while(1);
   }
  ++temp;
 }
}   

void HexToBCD(unsigned char *p, unsigned int t)   
{   
  unsigned char i=0; 
  unsigned char s; 
  if (t>=40000) {i=4; t-=40000;}   //如果t<=9999,则这部分可不用。 
  if (t>=20000) {i+=2;t-=20000;} 
  if (t>=10000) {i++; t-=10000;} 
  *p++=i;;                      
  i=0; 
  if (t>=8000) {i=8; t-=8000;} 
  if (t>=4000) {i+=4;t-=4000;} 
  if (t>=2000) {i+=2;t-=2000;} 
  if (t>=1000) {i++; t-=1000;} 
  *p++=i; 
  i=0; 
  if (t>=800) {i=8; t-=800;} 
  if (t>=400) {i+=4;t-=400;} 
  if (t>=200) {i+=2;t-=200;} 
  s=t;
  if (s>=100) {i++; s-=100;} 
  *p++=i; 
  i=0; 
  if (s>=80) {i=8; s-=80;}
  if (s>=40) {i+=4;s-=40;} 
  if (s>=20) {i+=2;s-=20;} 
  if (s>=10) {i++; s-=10;} 
  *p++=i; 
  *p=s; 
} 

出0入0汤圆

发表于 2008-11-22 12:35:32 | 显示全部楼层
越来越好了,很牛,应该穿条裤子了!

出0入0汤圆

发表于 2008-11-22 18:23:26 | 显示全部楼层
对。。穿裤子了!

出0入0汤圆

发表于 2008-11-23 00:31:24 | 显示全部楼层
平时经常会用到,标记一下。

出0入0汤圆

发表于 2008-11-23 01:23:11 | 显示全部楼层
都说AVR好,连个硬件乘/除法器都没有。
又说51怎么怎么不爽,好歹人家还有个硬件乘/除法器。
直接用/和%运算得了,好移植。

出0入0汤圆

发表于 2008-11-23 05:03:31 | 显示全部楼层
好热闹...

出0入0汤圆

发表于 2008-11-23 10:04:03 | 显示全部楼层
HEXTOBCD最快之争吗,呵呵
结果是谁胜出?

出0入0汤圆

发表于 2008-11-23 10:09:30 | 显示全部楼层
好, 记下!

出0入0汤圆

发表于 2008-11-23 10:59:29 | 显示全部楼层
有用,先收藏!

出0入0汤圆

发表于 2008-11-23 13:47:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-11-23 15:33:11 | 显示全部楼层
55楼xuyiyi 许意义,你对你程序的速度测试过没有?【45楼】 shinehjx 测试结果为:转换一次约15US(8MHZ CLK,122T)我用51的ASM优化上述程序,在51环境中程序运行时间是 77~107机器周期(若用AVR的汇编估计可在80周期以下),我认为是比较快了。我用51的ASM,移位法转换,要用200周期以上,速度跟上面程序根本没法比,我没装AVR的编译,所以试不了,你不妨试试你程序的执行速度!

本贴被 cowboy 编辑过,最后修改时间:2008-11-23,15:41:16.

出0入0汤圆

 楼主| 发表于 2008-11-23 16:17:17 | 显示全部楼层
程序运行的快慢首先取决于计算方法--算法,C语言中好的算法不一定比差的算法汇编慢,有时比汇编还要快。

出0入0汤圆

发表于 2008-11-23 20:49:12 | 显示全部楼层
我也用过类似方法,比除法及求余要快吧.

出0入0汤圆

发表于 2008-12-6 12:34:01 | 显示全部楼层
子程序处理速度快慢,我认为不应以平以平均速度来衡量,应该以任意输入参数中最慢的一次为准,这样才能保证对于任意输入参数,都能在规定的时间内处理完毕,这样才可以估算系统对其它事件的响应速度。以楼上HexToBCD程序为例,当输入参数 t = 7777 时,处理时间最长。优化后的HexToBCD1程序中增加 goto 语句,确实可以使某些特别的输入参数(如9999)处理速度有所提升,但对于输入参数 t = 7777,却没有任何改善,也就是说程序最长的处理时间没有改善,因而这样优化,似乎意义不大。 

出0入0汤圆

发表于 2008-12-6 20:28:24 | 显示全部楼层
算法呀。。。。。。。

出0入0汤圆

发表于 2009-1-16 14:10:47 | 显示全部楼层
没得说,楼上的都是好汉,比我想得好太多啦,抄袭~!~

出0入0汤圆

发表于 2009-1-17 11:34:16 | 显示全部楼层
眼花...

前辈们推动了中国电子发展的新辉煌...

致敬... 学习 

出0入0汤圆

发表于 2009-3-5 21:52:55 | 显示全部楼层
Hex to bcd转换的算法比较 作者[晓奇]©
--- 晓奇工作室---

C语言主程序部分
// 左移移位法作hex to bcd转换的算法程序,加上这一段调用演示,以察看运行结果
// 12M晶振时汇编算法运行时间大约为1339ns,C语言减法转换时间大约897ns
// 不同的输入数据在C语言的减法转换时间略有不同,最大时间59999时为1231ns
// 所以C语言的减法运算还是略快一些。
// http://www.xiao-qi.com/晓奇工作室收集整理,Keil C51下调试运行通过

#include <reg51.h>

unsigned char bcdData[3];
unsigned int ihexs;
unsigned char disp_buffer[5];

extern void hex_bcd(unsigned int iHex);     // 声明外部函数
void hextobcd(unsigned int hexs,unsigned char j);

void main(void){
    ihexs = 59999;
    hex_bcd(ihexs);
    hextobcd(ihexs,5);
    while(1);
}
   
/***************************
   hex to bcd 转换程序
***************************/
void hextobcd(unsigned int hexs,unsigned char j) {

unsigned int va;
unsigned char i;
    va = 10000;                             //最大数级万位
    for     (i=j-1;i;i--) {
        disp_buffer = 0;                 //目标数组清零
        while ((hexs>=va)&&(va>9)) {
            hexs -= va;                     //减除数
            disp_buffer++;               //商位加1
        }
        va /= 10;                           //除数除10,指向低一位
    }
    disp_buffer[0]=hexs;                    //最后个位数
}

汇编语言模块,建立另一个文件
NAME HEX_BCD
;*************************************************************************
; Hex to 压缩BCD码的转换(每4位代表一位bcd码)
; 输入Hex:R6R7     返回地址:bcdData
;*bcdData = BCD(R6R7)
; http://www.xiao-qi.com/晓奇工作室收集整理,Keil C51下调试运行通过
;*************************************************************************
?PR?_HEX_BCD?HEX_BCD SEGMENT CODE   ; 码段定义叙述,需要对本文件内的所有
?PR?_BCD_ADJ?HEX_BCD SEGMENT CODE   ; 码段定义叙述,需要对本文件内的所有
PUBLIC _HEX_BCD
EXTRN   DATA(bcdData)

RSEG  ?PR?_HEX_BCD?HEX_BCD
_HEX_BCD:CLR     A                   ;目标数据清零初始化
        MOV     bcdData, A
        MOV     bcdData+1, A
        MOV     bcdData+2, A
        MOV     R2, #15             ; 共进行15次循环移位运算
H_B0:   MOV     A, R7               ; 低8位
        RLC     A                   ; 大循环左移
        MOV     R7, A               ; 回存
        MOV     A, R6               ; 高8位
        RLC     A                   ; 大循环左移
        MOV     R6, A               ; 回存。至此已获得当前数据的最高位

        MOV     A, bcdData+2        ; 目标数最低8位
        RLC     A                   ; 移入原数据的最高位
        ACALL   _BCD_ADJ            ; 压缩BCD码的十进制调整
        MOV     bcdData+2, A        ; 存回
        MOV     A, bcdData+1        ; 目标数中间8位
        RLC     A                   ; 移入进位位
        ACALL   _BCD_ADJ            ; 压缩BCD码的十进制调整
        MOV     bcdData+1, A        ; 存回
        MOV     A, bcdData          ; 目标数最高8位
        RLC     A                   ; 移入进位位
        ACALL   _BCD_ADJ            ; 压缩BCD码的十进制调整
        MOV     bcdData, A          ; 存回
        DJNZ    R2, H_B0            ; 继续下一轮循环

; 目标数据再左移一位,将原数据的最后一位放入,这样总共进行了16次循环移位
        MOV     A, R6
        RLC     A
        MOV     A, bcdData+2
        RLC     A
        MOV     bcdData+2, A
        MOV     A, bcdData+1
        RLC     A
        MOV     bcdData+1, A
        MOV     A, bcdData
        RLC     A
        MOV     bcdData, A
        RET

;*************************************************************************
; 压缩BCD码的十进制调整,基本思路:逢十进一,在这里因为还保留着最后一次左
; 移, 所以进位判别的0AH(0A0H)变成相对右移了一位的05H(050H), 而强迫进行进位
; 的方法是加上一个数字3(左移一位后就是6)。程序保护PSW
; 输入返回均使用Acc累加器
;*************************************************************************
RSEG  ?PR?_BCD_ADJ?HEX_BCD

_BCD_ADJ:
    PUSH    PSW
        PUSH    ACC
        CJNE    A, #50H, $+3    ; 高4位。做一个比较产生状态标志
        JC      B1              ; 如果小于#50H, 不用进位处理
        POP     ACC             ; 取原数据作修改
        ADD     A, #30H         ; 加上#30h,留待下一轮左移时产生进位
        PUSH    ACC             ; 存回原数据
  B1:   ANL     A, #0FH         ; 仅考虑低4位
        CJNE    A, #5, $+3      ; 做一个比较产生状态标志
        JC      B2              ; 如果小于#5H, 不用进位处理
        POP     ACC             ; 取原数据作修改
        ADD     A, #3           ; 加上#3h,留待下一轮左移时产生进位
        PUSH    ACC             ; 存回原数据
  B2:   POP     ACC             ; 恢复现场
        POP     PSW
        RET
end
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
[nobody]&copy;的快速算法,速度更快。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
?PR?_HEX_BCD?HEX_BCD SEGMENT CODE         
PUBLIC _HEX_BCD
RSEG  ?PR?_HEX_BCD?HEX_BCD
_HEX_BCD:
        CLR     A           ;BCD码初始化
        MOV     R3,A
        MOV     R4,A
        MOV     R5,A
        MOV     R2,#10H     ;转换双字节十六进制整数
HB3:
        MOV     A,R7        ;从高端移出待转换数的一位到CY中
        RLC     A
        MOV     R7,A
        MOV     A,R6
        RLC     A
        MOV     R6,A
        MOV     A,R3        ;BCD码带进位自身相加,相当于乘2
        ADDC    A,R3
        DA      A           ;十进制调整
        MOV     R3,A
        MOV     A,R4
        ADDC    A,R4
        DA      A
        MOV     R4,A
        MOV     A,R5
        ADDC    A,R5
        MOV     R5,A        ;双字节十六进制数的万位数不超过6,不用调整
        DJNZ    R2,HB3      ;处理完16bit
        mov     a,r3
        mov     r7,a
        mov     a,r4
        mov     r6,a
        mov     r4,#0
        RET
end

调用方法:
extern unsigned int hex_bcd(unsigned int iHex);     /*声明外部函数*/

extern unsigned long hex_bcd(unsigned int iHex);    /*声明外部函数*/

出0入0汤圆

发表于 2009-3-5 22:10:15 | 显示全部楼层
unsigned  int code div[5]={10000,1000,100,10,1};
unsigned char  LED[5];


void HEX_bcd(void){
unsigned char j;
unsigned int  k;

   k=ex;//外部data.
   for(j=0;j<5;j++){
   while((int)k>=div[j]){LED[j]+=1;(int)k-=div[j];};//查表法,不用div=10000; div/=10;

  }
}
如何。

出0入0汤圆

发表于 2009-3-5 22:36:49 | 显示全部楼层
【66楼】 yjbin
// 12M晶振时汇编算法运行时间大约为1339ns,C语言减法转换时间大约897ns

笔误吧, ns 应为 us, 用汇编,超过100us 就别讨论了, 早有牛人做到 60 us 以下.

出0入0汤圆

发表于 2009-10-29 23:14:25 | 显示全部楼层

出0入0汤圆

发表于 2009-12-15 17:36:14 | 显示全部楼层
信号找到这帖子!

出0入0汤圆

发表于 2009-12-22 21:22:15 | 显示全部楼层
以前没怎么注意过执行时间这个问题,长见识了

出0入0汤圆

发表于 2009-12-22 21:59:25 | 显示全部楼层
强帖,值得研究

出0入0汤圆

发表于 2009-12-22 23:11:08 | 显示全部楼层
值得收藏,曾经为这个问题困扰过。

出0入0汤圆

发表于 2009-12-22 23:13:25 | 显示全部楼层
学习了。

出0入0汤圆

发表于 2009-12-24 09:28:12 | 显示全部楼层
很好的放算法,加上几个GOTO会更好
void HexToBCD(unsigned char *p, unsigned int t)     
{     
  unsigned char i=0;   
  unsigned char s;   
  if (t>=40000) {i =4;t-=40000;}   //如果t<=9999,则这部分可不用。   
  if (t>=20000) {i+=2;t-=20000;}   
  if (t>=10000) {i++; t-=10000;}   
  *p++=i;;                        
  i=0;   
  if (t>=8000) {i =8;t-=8000;goto compare1000;}   
  if (t>=4000) {i+=4;t-=4000;}   
  if (t>=2000) {i+=2;t-=2000;}   
  compare1000:
  if (t>=1000) {i++; t-=1000;}   
  *p++=i;   
  i=0;   
  if (t>=800) {i =8;t-=800;goto compare1000;}   
  if (t>=400) {i+=4;t-=400;}   
  if (t>=200) {i+=2;t-=200;}
  compare100:  
  s=(unsigned char)t;  
  if (s>=100) {i++; s-=100;}   
  *p++=i;   
  i=0;   
  if (s>=80) {i =8;s-=80;goto compare10;}  
  if (s>=40) {i+=4;s-=40;}   
  if (s>=20) {i+=2;s-=20;}  
  compare10:
  if (s>=10) {i++; s-=10;}   
  *p++=i;   
  *p=s;   
}

出0入16汤圆

发表于 2009-12-24 10:38:05 | 显示全部楼层
前辈们继续讨论,吾等受益匪浅

出0入0汤圆

发表于 2009-12-24 11:08:00 | 显示全部楼层
MARK H2B

出0入0汤圆

发表于 2010-1-5 18:36:16 | 显示全部楼层
回的第一个贴,留念下

出0入0汤圆

发表于 2010-1-13 17:05:08 | 显示全部楼层
很有效率

出0入0汤圆

发表于 2010-1-13 23:39:31 | 显示全部楼层
记号,备用

出0入0汤圆

发表于 2010-1-14 00:06:21 | 显示全部楼层
用过任意16位二进制转十进制最快的是标准51的用76T,24MHZ时是38us,用C8051等不超过8us。C程序的哦!

出0入0汤圆

发表于 2010-1-14 00:43:45 | 显示全部楼层
真热闹,学习的气氛非常浓。我也有个想法,不知道用“&”运算可不可以优化?

出0入0汤圆

发表于 2010-1-14 09:56:42 | 显示全部楼层
mark, 学习了!

出0入0汤圆

发表于 2010-1-14 11:46:02 | 显示全部楼层
先作记号。

出0入0汤圆

发表于 2010-1-14 12:12:23 | 显示全部楼层
51,keil软仿了一下。优化设置默认,12M晶振。X=45536

楼主的程序需要168字节空间。38楼cowboy 的需要436字节空间。

楼主的程序转换时间为480us。38楼cowboy 的转换时间为193us。

大家各取所需吧。

出0入0汤圆

发表于 2010-1-14 13:01:06 | 显示全部楼层
记号

出0入0汤圆

发表于 2010-1-14 14:33:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-2 14:48:47 | 显示全部楼层
收藏

出0入0汤圆

发表于 2010-3-2 15:30:34 | 显示全部楼层
一味的求快是不行的,说白了是时间和空间的关系~~不同场合要用不同的版本~

出0入0汤圆

发表于 2010-10-23 10:27:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-23 12:20:15 | 显示全部楼层
马克

出0入0汤圆

发表于 2010-10-24 16:04:47 | 显示全部楼层
哈哈,好,收下学习!

出0入0汤圆

发表于 2011-1-26 15:32:19 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-24 17:37:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-24 20:53:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-27 13:05:56 | 显示全部楼层
Mark!

出0入0汤圆

发表于 2011-7-9 00:20:04 | 显示全部楼层
各位的讨论精彩!很有用,mark!

出0入0汤圆

发表于 2011-7-9 15:42:51 | 显示全部楼层
长见识了  向各位高手致敬!

出0入0汤圆

发表于 2011-7-9 16:16:38 | 显示全部楼层
看下

出50入0汤圆

发表于 2012-2-1 14:22:55 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-1-16 03:17:26 | 显示全部楼层
怎么我看到的都是乱码呀,几乎旧贴都是这样,很可惜,
显示的乱码下面这样:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(Temp&nbsp;&&nbsp;0x08)&nbsp;TempB.byte[0]&nbsp;=&nbsp;Temp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Temp&nbsp;=&nbsp;TempB.byte[0]&nbsp;+&nbsp;0x30;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(Temp&nbsp;&&nbsp;0x80)&nbsp;TempB.byte[0]&nbsp;=&nbsp;Temp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Temp&nbsp;=&nbsp;TempB.byte[1]&nbsp;+&nbsp;0x03;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(Temp&nbsp;&&nbsp;0x08)&nbsp;TempB.byte[1]&nbsp;=&nbsp;Temp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Temp&nbsp;=&nbsp;TempB.byte[1]&nbsp;+&nbsp;0x30;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&

出0入0汤圆

发表于 2013-4-11 17:01:28 来自手机 | 显示全部楼层
谢谢楼主......
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 03:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表