网上到的资料,支持多串口printf,但编译提示: ..\SYSTEM\usart\usart.c(64): error: #77-D: this declaration has no storage class or type specifier PUTCHAR_POTOTYPE 该如何操作? #include <stdarg.h> #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc (int ch, FILE *f) #endif PUTCHAR_POTOTYPE { USART_SendData(USART1, (u8) ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); return ch; } void USART3_printf(char *fmt, ...) { char buffer[CMD_BUFFER_LEN+1]; u8 i=0; va_list arg_ptr; va_start(arg_ptr,fmt); vsnprintf(buffer,CMD_BUFFER_LEN+1,fmt,arg_ptr); while((i<CMD_BUFFER_LEN) && buffer[i]) { USART_SendData(USART3, (u8)buffer[i++]); while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); } va_end(arg_ptr); } | |||
2012/07/15 19:11 | |||
[1楼] 正点原子 等级: 站长 注册时间:2010/12/02 10:41 printf函数是如何实现的回复数: 43927 主题数: 356 酷贴数:25 论坛积分:47495 来自: 湖南 离线 | 这等于你自己重构了一个... printf一个就够了吧,其他可以直接用写DR的方式.没发现printf不够用过... | ||
我的淘宝小店:shop62103354.taobao 回复 | |||
2012/07/15 22:24 | |||
[2楼] licgang 等级: 注册时间:2012/06/19 11:08 回复数: 20 主题数: 5 论坛积分:35 离线 | 现在是要用2个串口,如果不用printf函数的话,程序处理上比较麻烦,输出的格式有点多 | ||
回复 | |||
2012/07/15 23:06 | |||
[3楼] 正点原子 等级: 站长 注册时间:2010/12/02 10:41 回复数: 43927 主题数: 356 酷贴数:25 论坛积分:47495 来自: 湖南 离线 | 哦,那你得能支持2个printf的实现方法. | ||
我的淘宝小店:shop62103354.taobao 回复 | |||
2012/08/05 11:20 | |||
[4楼] licgang 等级: 注册时间:2012/06/19 11:08 回复数: 20 主题数: 5 论坛积分:35 离线 | 这两天有空研究了下printf函数,参照网上资料自己写了个模拟printf函数,这样可以方便实现多串口printf了 其实printf函数最关键的就是可变参数的获取了,这里要用到stdarg.h库,经过测试基本没有问题了。 void myitoa(int data,char *buf ) { int temp,j=0,i=0; while(data) //反序生成数字,可自己取个数字测试,如123,反序字符数组中的值为321 { buf[i++] = data%10+'0';//将转换后的数字字符存放在字符数组中 data = data/10; //删除已经转换的数字,为取下一个数字做好准备 } buf[i--]='\0'; //转换完后还需要在字符数组后面加一个字符串结束标志'/0',代表是一个字符串 while( j < i ) //刚刚转换好的字符串是逆序的必须把它反转过来 { temp = buf[j]; buf[j] = buf[i]; buf[i] = temp; i--,j++; } } //------------------------COM3 printf------------------------------// void DBGprintf(const char *format, ...) { va_list ap; char c,nc; va_start(ap, format); //从右到左将参数入栈,ap指向format while (c = *format++) { if(c == '%'&&(nc = *format++) != '\0') { switch(nc) { case 'c': //输出1个字符 { char ch = va_arg(ap, int); //调用后栈位置+1 DBG_SendASC(ch); //com3发送字符 break; } case 's': //输出字符串 { char *p = va_arg(ap, char *); DBG_SendStr((u8 *)p); //com3发送字符串 break; } case 'd': { int data = va_arg(ap,int); char buf[16]; myitoa(data,buf); DBG_SendStr((u8 *)buf); break; } default: DBG_SendASC(nc); } }else {DBG_SendASC(c);} } va_end(ap); //关闭指针 } | ||
回复 | |||
2012/08/05 11:24 | |||
[5楼] 正点原子 等级: 站长 注册时间:2010/12/02 10:41 回复数: 43927 主题数: 356 酷贴数:25 论坛积分:47495 来自: 湖南 离线 | 可以写成形如: myprintf(u8 uartx,const char *format, ...) 其中,uartx,就是要输出的串口,比如1,2,3,4,5对应串口1~5. 后见面的两个参数就是标准的printf参数了. 这样使用起来更方便. | ||
我的淘宝小店:shop62103354.taobao 回复 | |||
2012/08/05 11:54 | |||
[6楼] licgang 等级: 注册时间:2012/06/19 11:08 回复数: 20 主题数: 5 论坛积分:35 离线 | 后面是要这样写方便些,贴出代码来主要是让大家看下,顺便测试看有没有什么问题,目前测试都还正常 刚才测试打印INT整数,发现STM32int是32位的,上面程序默认的INT类型是有符号的,超出0x7fffffff,输出不正常。 这个要对程序做些修改才行,这点使用的时候要注意了 | ||
网上到的资料,支持多串口printf,但编译提示:
..\SYSTEM\usart\usart.c(64): error: #77-D: this declaration has no storage class or type specifier
..\SYSTEM\usart\usart.c(64): error: #77-D: this declaration has no storage class or type specifier
PUTCHAR_POTOTYPE 该如何操作?
#include <stdarg.h>
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc (int ch, FILE *f)
#endif
PUTCHAR_POTOTYPE
{
USART_SendData(USART1, (u8) ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
return ch;
}
void USART3_printf(char *fmt, ...)
{
char buffer[CMD_BUFFER_LEN+1];
u8 i=0;
va_list arg_ptr;
va_start(arg_ptr,fmt);
vsnprintf(buffer,CMD_BUFFER_LEN+1,fmt,arg_ptr);
while((i<CMD_BUFFER_LEN) && buffer[i])
{
USART_SendData(USART3, (u8)buffer[i++]);
while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);
}
va_end(arg_ptr);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```~~~~~~~~~~~~~~~~~~~~
这两天有空研究了下printf函数,参照网上资料自己写了个模拟printf函数,这样可以方便实现多串口printf了
其实printf函数最关键的就是可变参数的获取了,这里要用到stdarg.h库,经过测试基本没有问题了。
void myitoa(int data,char *buf )
{
int temp,j=0,i=0;
while(data) //反序生成数字,可自己取个数字测试,如123,反序字符数组中的值为321
{
buf[i++] = data%10+'0';//将转换后的数字字符存放在字符数组中
data = data/10; //删除已经转换的数字,为取下一个数字做好准备
}
buf[i--]='\0'; //转换完后还需要在字符数组后面加一个字符串结束标志'/0',代表是一个字符串
while( j < i ) //刚刚转换好的字符串是逆序的必须把它反转过来
{
temp = buf[j];
buf[j] = buf[i];
buf[i] = temp;
i--,j++;
}
}
//------------------------COM3 printf------------------------------//
void DBGprintf(const char *format, ...)
{
va_list ap;
char c,nc;
va_start(ap, format); //从右到左将参数入栈,ap指向format
while (c = *format++)
{
if(c == '%'&&(nc = *format++) != '\0')
{
switch(nc)
{
case 'c': //输出1个字符
{
char ch = va_arg(ap, int); //调用后栈位置+1
DBG_SendASC(ch); //com3发送字符
break;
}
case 's': //输出字符串
{
char *p = va_arg(ap, char *);
DBG_SendStr((u8 *)p); //com3发送字符串
break;
}
case 'd':
{
int data = va_arg(ap,int);
char buf[16];
myitoa(data,buf);
DBG_SendStr((u8 *)buf);
break;
}
default:
DBG_SendASC(nc);
}
}else
{DBG_SendASC(c);}
}
va_end(ap); //关闭指针
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论