单片机源程序如下:
- #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)
- {
-
- }
- }
- */
复制代码
以上4个文件下载:
精减版本printf.rar
(2.49 KB, 下载次数: 22)
|