网上到的资料,支持多串口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
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);    //关闭指针
}