标题:
精减版本Printf函数 适合小容量MCU
[打印本页]
作者:
wxmlx
时间:
2021-10-17 18:07
标题:
精减版本Printf函数 适合小容量MCU
单片机源程序如下:
#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, 下载次数: 40)
下载附件
2021-10-18 03:38 上传
以上4个文件下载:
精减版本printf.rar
(2.49 KB, 下载次数: 21)
2021-10-17 18:07 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1