找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2328|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

精減版本Printf函數(shù) 適合小容量MCU

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
#
ID:137590 發(fā)表于 2021-10-17 18:07 | 只看該作者 |只看大圖 回帖獎勵 |正序瀏覽 |閱讀模式
單片機(jī)源程序如下:
  1. #include <stdarg.h>
  2. //名稱:適用于mega8等小容量MCU的sprintf函數(shù)//
  3. //簡介:主要針對小容量MCU flash ram有限,使用標(biāo)準(zhǔn)springf函數(shù)占用空間過大,莫名堆棧溢出問題//
  4. //函數(shù)僅支持16位無符號整形和字符串的轉(zhuǎn)換,如果要轉(zhuǎn)換float型,請使用//
  5. //額外提供的 將float轉(zhuǎn)換為字符串的函數(shù)//


  6. void sprintfx(char * str,flash char * fmtstr,...)
  7. {
  8.         va_list argptr;
  9.         char * cp;
  10.         unsigned char k,loop=0,loopstr=0,loops,active;
  11.         unsigned int utmp,m;
  12.         va_start(argptr,fmtstr);
  13.         while (fmtstr[loop])
  14.         {
  15.                 k=fmtstr[loop];
  16.                 if(k!='%')
  17.                 {
  18.                         str[loopstr]=k;
  19.                         loopstr++;
  20.                 }
  21.                 else
  22.                 {
  23.                         loop++;                //指向%號的下一個字符,確定變量類型//
  24.                         k=fmtstr[loop];
  25.                         switch(k)
  26.                         {
  27.                                 case 'u':
  28.                                         utmp=*(unsigned int*)(argptr);
  29.                                         va_arg(argptr,int);
  30.                                         if(utmp==0)
  31.                                         {
  32.                                                 str[loopstr]=0x30;
  33.                                                 loopstr++;
  34.                                                 break;
  35.                                         }
  36.                                         m=10000;
  37.                                         active=0;        //暫無有效位//
  38.                                         for(loops=0;loops<5;loops++)        //unsigned int 最大65535 占5位//
  39.                                         {
  40.                                                 if(utmp>=m)
  41.                                                 {
  42.                                                         active=1;        //得到有效位//
  43.                                                 }
  44.                                                 if(active)
  45.                                                 {
  46.                                                         str[loopstr]=(unsigned char)(utmp/m)+0x30;
  47.                                                         loopstr++;
  48.                                                         utmp=utmp%m;
  49.                                                 }
  50.                                                 m=m/10;
  51.                                         }
  52.                                 break;
  53.                                 
  54.                                 case 's':
  55.                                         utmp=*((unsigned int *)(argptr));
  56.                                         cp=(char *)(utmp);
  57.                                         va_arg(argptr,char *);        
  58.                                         loops=0;
  59.                                         while(cp[loops])
  60.                                         {
  61.                                                 str[loopstr]=cp[loops];
  62.                                                 loops++;
  63.                                                 loopstr++;
  64.                                         }
  65.                                 break;

  66.                                 default:
  67.                                 break;
  68.                         };
  69.                         
  70.                 }
  71.                 loop++;
  72.         };
  73.         str[loopstr]=0;
  74.         va_end(argptr);
  75. }


  76. //將float轉(zhuǎn)換為字符串//
  77. //用法:fdat待轉(zhuǎn)換的float變量、maxlen最大轉(zhuǎn)換完的長度(包含小數(shù)點及其小數(shù))取值最大不要超過16//
  78. //pre小數(shù)點后保留的位數(shù)取值不要超過4、xbuf轉(zhuǎn)換結(jié)果存放的緩沖區(qū)//
  79. //注意:float的整數(shù)部分只支持到65535。程序沒有對各個變量的取值進(jìn)行合理性判別//
  80. void sprintf_float(float fdat,unsigned char maxlen,unsigned char pre,char *xbuf)
  81. {
  82.         char buf[18];
  83.         unsigned char loop=11,startpos,len;        //循環(huán)變量、開始位置、長度//
  84.         unsigned char sn=0;                        //數(shù)值的正負(fù) 兼顧endpos//
  85.         unsigned int lint;                        //整數(shù)部分//

  86.         //最大轉(zhuǎn)換長度18個//
  87.         if(maxlen>18)
  88.         {
  89.                 return;
  90.         }
  91.         ///////////////////小數(shù)點前的部分//////////////////////////
  92.         if(fdat<0)
  93.         {
  94.                 sn=1;
  95.                 fdat=0-fdat;
  96.         }
  97.         lint=(unsigned int)(fdat);
  98.         while(loop)
  99.         {
  100.                 buf[loop]=lint%10+0x30;
  101.                 lint=lint/10;
  102.                 loop--;
  103.                 if(lint==0)
  104.                 {
  105.                         break;
  106.                 }
  107.         }
  108.         if(sn==1)
  109.         {
  110.                 buf[loop]='-';
  111.         }
  112.         else
  113.         {
  114.                 loop++;
  115.         }
  116.         startpos=loop;
  117.         len=12-startpos;//整數(shù)部分長度//
  118.         if(len>=maxlen)        //如果整數(shù)位(包括負(fù)號)長度已經(jīng)大于限定長度,強(qiáng)制添0//
  119.         {
  120.                 buf[(unsigned char)(startpos+maxlen)]=0;
  121.                 sn=startpos+maxlen;
  122.         }
  123.         else
  124.         {
  125.                 if((maxlen-len)>=2)
  126.                 {
  127.                         buf[12]='.';
  128.                         //////////////////分解小數(shù)部分////////////////////////
  129.                         len=maxlen-len-1;        //小數(shù)點后長度//
  130.                         if(pre<len)                //如果精度要求低于剩余長度,按照精度要求計算//
  131.                         {
  132.                                 len=pre;
  133.                         }
  134.                         lint=(unsigned int)(fdat);
  135.                         fdat=fdat-(float)(lint);
  136.                         for(loop=13;loop<(13+len);loop++)
  137.                         {
  138.                                 fdat=fdat*10;
  139.                                 lint=((unsigned int)(fdat));
  140.                                 fdat=fdat-(float)(lint);
  141.                                 buf[loop]=(char)(lint)+0x30;
  142.                         }
  143.                         while(loop<(startpos+maxlen))
  144.                         {
  145.                                 buf[loop]=' ';
  146.                                 loop++;
  147.                         }
  148.                         buf[loop]=0;
  149.                         sn=loop;
  150.                 }
  151.                 else
  152.                 {
  153.                         buf[12]=' ';
  154.                         buf[13]=0;
  155.                         sn=13;
  156.                 }
  157.         }
  158.         //////////////////基0搬移數(shù)據(jù)//////////////////////
  159.         for(loop=0;loop<=(sn-startpos);loop++)
  160.         {
  161.                 xbuf[loop]=buf[startpos+loop];
  162.         }
  163. }





  164. //用法示例程序//
  165. /*
  166. char buf[64];
  167. int  adr=60035;
  168. char s1[]="12";
  169. char s2[]="456789";
  170. char s3[10];
  171. float fv=1513.28;

  172. void main(void)
  173. {
  174.         sprintf_float(fv,8,2,s3);
  175.         sprintfx(buf,"adr=%u s1=%s s2=%s fv=%s",adr,s1,s2,s3);
  176.         while(1)
  177.         {
  178.         
  179.         }
  180. }

  181. */
復(fù)制代碼


以上4個文件下載:
精減版本printf.rar (2.49 KB, 下載次數(shù): 22)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏8 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表