單片機源程序如下:
- #include <stdarg.h>
- //名稱:適用于mega8等小容量MCU的sprintf函數//
- //簡介:主要針對小容量MCU flash ram有限,使用標準springf函數占用空間過大,莫名堆棧溢出問題//
- //函數僅支持16位無符號整形和字符串的轉換,如果要轉換float型,請使用//
- //額外提供的 將float轉換為字符串的函數//
- void sprintfx(char * str,flash char * fmtstr,...)
- {
- va_list argptr;
- char * cp;
- unsigned char k,loop=0,loopstr=0,loops,active;
- unsigned int utmp,m;
- va_start(argptr,fmtstr);
- while (fmtstr[loop])
- {
- k=fmtstr[loop];
- if(k!='%')
- {
- str[loopstr]=k;
- loopstr++;
- }
- else
- {
- loop++; //指向%號的下一個字符,確定變量類型//
- k=fmtstr[loop];
- switch(k)
- {
- case 'u':
- utmp=*(unsigned int*)(argptr);
- va_arg(argptr,int);
- if(utmp==0)
- {
- str[loopstr]=0x30;
- loopstr++;
- break;
- }
- m=10000;
- active=0; //暫無有效位//
- for(loops=0;loops<5;loops++) //unsigned int 最大65535 占5位//
- {
- if(utmp>=m)
- {
- active=1; //得到有效位//
- }
- if(active)
- {
- str[loopstr]=(unsigned char)(utmp/m)+0x30;
- loopstr++;
- utmp=utmp%m;
- }
- m=m/10;
- }
- break;
-
- case 's':
- utmp=*((unsigned int *)(argptr));
- cp=(char *)(utmp);
- va_arg(argptr,char *);
- loops=0;
- while(cp[loops])
- {
- str[loopstr]=cp[loops];
- loops++;
- loopstr++;
- }
- break;
- default:
- break;
- };
-
- }
- loop++;
- };
- str[loopstr]=0;
- va_end(argptr);
- }
- //將float轉換為字符串//
- //用法:fdat待轉換的float變量、maxlen最大轉換完的長度(包含小數點及其小數)取值最大不要超過16//
- //pre小數點后保留的位數取值不要超過4、xbuf轉換結果存放的緩沖區//
- //注意:float的整數部分只支持到65535。程序沒有對各個變量的取值進行合理性判別//
- void sprintf_float(float fdat,unsigned char maxlen,unsigned char pre,char *xbuf)
- {
- char buf[18];
- unsigned char loop=11,startpos,len; //循環變量、開始位置、長度//
- unsigned char sn=0; //數值的正負 兼顧endpos//
- unsigned int lint; //整數部分//
- //最大轉換長度18個//
- if(maxlen>18)
- {
- return;
- }
- ///////////////////小數點前的部分//////////////////////////
- if(fdat<0)
- {
- sn=1;
- fdat=0-fdat;
- }
- lint=(unsigned int)(fdat);
- while(loop)
- {
- buf[loop]=lint%10+0x30;
- lint=lint/10;
- loop--;
- if(lint==0)
- {
- break;
- }
- }
- if(sn==1)
- {
- buf[loop]='-';
- }
- else
- {
- loop++;
- }
- startpos=loop;
- len=12-startpos;//整數部分長度//
- if(len>=maxlen) //如果整數位(包括負號)長度已經大于限定長度,強制添0//
- {
- buf[(unsigned char)(startpos+maxlen)]=0;
- sn=startpos+maxlen;
- }
- else
- {
- if((maxlen-len)>=2)
- {
- buf[12]='.';
- //////////////////分解小數部分////////////////////////
- len=maxlen-len-1; //小數點后長度//
- if(pre<len) //如果精度要求低于剩余長度,按照精度要求計算//
- {
- len=pre;
- }
- lint=(unsigned int)(fdat);
- fdat=fdat-(float)(lint);
- for(loop=13;loop<(13+len);loop++)
- {
- fdat=fdat*10;
- lint=((unsigned int)(fdat));
- fdat=fdat-(float)(lint);
- buf[loop]=(char)(lint)+0x30;
- }
- while(loop<(startpos+maxlen))
- {
- buf[loop]=' ';
- loop++;
- }
- buf[loop]=0;
- sn=loop;
- }
- else
- {
- buf[12]=' ';
- buf[13]=0;
- sn=13;
- }
- }
- //////////////////基0搬移數據//////////////////////
- for(loop=0;loop<=(sn-startpos);loop++)
- {
- xbuf[loop]=buf[startpos+loop];
- }
- }
- //用法示例程序//
- /*
- char buf[64];
- int adr=60035;
- char s1[]="12";
- char s2[]="456789";
- char s3[10];
- float fv=1513.28;
- void main(void)
- {
- sprintf_float(fv,8,2,s3);
- sprintfx(buf,"adr=%u s1=%s s2=%s fv=%s",adr,s1,s2,s3);
- while(1)
- {
-
- }
- }
- */
復制代碼
51hei.png (3.02 KB, 下載次數: 64)
下載附件
2021-10-18 03:38 上傳
以上4個文件下載:
精減版本printf.rar
(2.49 KB, 下載次數: 22)
2021-10-17 18:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|