OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3856|回复: 10

visual studio 中printf重定向的问题

[复制链接]

2

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2017-10-13
在线时间
39 小时
发表于 2017-10-13 19:36:41 | 显示全部楼层 |阅读模式
10金钱
用VS+visualGDB+stm32cubeMX有一段时间了,
实际也做了两个项目,
但是有一个问题一直困扰着我,
就是printf不能用.
按照原子哥在keil中的代码,
尝试了网上说的好多种方法都不行.
现在在用机智云的服务做物联网的项目,
因为要用printf打印wifi状态,
机智云自动生成的代码也是在keil环境的,
又用了两天keil,越用越难受...
好多地方代码补全不起作用,
有时候删除前面的字母还会卡住.
相同的变量,函数居然不会高亮....还不如notepad++......

有没有大神在VS里面实现了printf了啊,跪求解脱....

最佳答案

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

23

主题

114

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2014-3-9
在线时间
103 小时
发表于 2017-10-13 19:36:42 | 显示全部楼层
krguang 发表于 2017-11-3 10:31
问题解决了.
http://www.openedv.com/forum.php?mod=redirect&goto=findpost&ptid=231872&pid=750613&from ...

这个城主66666啊
魔法王子
回复

使用道具 举报

2

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2017-10-13
在线时间
39 小时
 楼主| 发表于 2017-10-14 22:24:58 | 显示全部楼层
今天又尝试了几次还是不行,只好把整个printf实现了,代码在下面,各种输出都正常.
[mw_shl_code=c,true]#include <stdarg.h>   
#include "usart.h"

/*
* 将整形数字转换成字符,如 0 转换成 '0'
*/

char number2char(int num)
{
        char ch;

        switch (num)
        {
        case 0: ch = '0'; break;
        case 1: ch = '1'; break;
        case 2: ch = '2'; break;
        case 3: ch = '3'; break;
        case 4: ch = '4'; break;
        case 5: ch = '5'; break;
        case 6: ch = '6'; break;
        case 7: ch = '7'; break;
        case 8: ch = '8'; break;
        case 9: ch = '9'; break;
        case 10: ch = 'A'; break;
        case 11: ch = 'B'; break;
        case 12: ch = 'C'; break;
        case 13: ch = 'D'; break;
        case 14: ch = 'E'; break;
        case 15: ch = 'F'; break;

        default: ch = '0'; break;
        }

        return ch;
}


/*
* 将整数 ch 按照十进制/十六进制转换成字符
*/
char * convert_func(char *str, unsigned int ch, int num)
{
        char *pstr = str;
        int ww,qw,bw, sw, gw;
        int hw2,lw2,hw1, lw1;

        switch (num)
        {
        case 10:
                if (ww = ch / 10000)
                        *pstr++ = number2char(ww);

                if (qw = (ch / 1000 % 10))
                        *pstr++ = number2char(qw);
                else if (ww)
                        *pstr++ = number2char(0);

                if (bw = (ch / 100) % 10)
                        *pstr++ = number2char(bw);
                else if (qw)
                        *pstr++ = number2char(0);

                if (sw = (ch / 10) % 10)
                        *pstr++ = number2char(sw);
                else if (bw)
                        *pstr++ = number2char(0);

                if (gw = ch % 10)
                        *pstr++ = number2char(gw);
                else
                        *pstr++ = number2char(0);


                break;
        case 16:
                *pstr++ = '0';
                *pstr++ = 'x';

                if(hw2=ch/0x1000)
                        *pstr++ = number2char(hw2);
               
                if(hw2 = (ch / 0x100)%0x10)
                        *pstr++ = number2char(hw2);
                else if (hw2)
                        *pstr++ = number2char(0);


                if (hw1 = (ch / 0x10)%0x10)
                        *pstr++ = number2char(hw1);
                else
                        *pstr++ = number2char(0);

                if (lw1 = ch % 0x10)
                        *pstr++ = number2char(lw1);
                else
                        *pstr++ = number2char(0);

                break;
        default:
                break;
        }


        return pstr;
}


int my_vsprintf(char *buf, const char *fmt, va_list args)
{
        int i;
        char * str;
        char *s;
        unsigned char ch;


        for (str = buf; *fmt; ++fmt)
        {
                if (*fmt == '\n') // 如果是换行符,转换成回车符+换行符
                {
                        *str++ = '\r';
                        *str++ = '\n';
                        continue;
                }

                if (*fmt != '%') // 如果是'%',保存进str,如果不是,越过取下一个字符,见switch (*fmt)
                {
                        *str++ = *fmt;
                        continue;
                }

                fmt++;


                switch (*fmt)  // 这样只能解析%c, %s, %x, %X, %d. 像 %02d 这种可以自己扩展
                {
                case 'c':
                        *str++ = (unsigned char)va_arg(args, int);  // 返回args所指向参数,然后args指向下一个参数,由va_start(ap,fmt); 将args指向第二个参数,然后逐个往后取,下同
                        break;


                case 's':
                        s = va_arg(args, char *);
                        while (*s != '\0')
                                *str++ = *s++;

                        break;


                case 'd':
                        str = convert_func(str, va_arg(args, int), 10);
                        break;

                case 'x':
                        str = convert_func(str, va_arg(args, int), 16);
                        break;

                default:
                        break;
                }
        }

        *str = '\0';

        return str - buf;
}

void sendstring(unsigned char *string)
{
        while (*string)
        {
                HAL_UART_Transmit(&huart1, string, 1, 0xff);
                string++;
        }
}

void Uart_printf(const char *fmt, ...)
{
        va_list ap;   //va_list 是一个字符指针,可以理解为指向当前参数的一个指针,取参必须通过这个指针进行
        unsigned char string[128];

        va_start(ap, fmt);//让ap指向可变参数表里面的第一个参数
        my_vsprintf(string, fmt, ap);
        va_end(ap);
        sendstring(string);
}[/mw_shl_code]
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-10-15 00:22:14 | 显示全部楼层
帮顶
回复

使用道具 举报

2

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2017-10-13
在线时间
39 小时
 楼主| 发表于 2017-10-16 19:02:01 | 显示全部楼层

原子哥,你有用VS写过STM32么?
感觉比keil好用太多太多。。。。
回复

使用道具 举报

33

主题

1628

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6679
金钱
6679
注册时间
2015-8-25
在线时间
1036 小时
发表于 2017-10-16 19:05:44 | 显示全部楼层
krguang 发表于 2017-10-16 19:02
原子哥,你有用VS写过STM32么?
感觉比keil好用太多太多。。。。

个人有个人的习惯,有人就习惯keil
He who fights with monsters should look to it that he himself does not become a monster, when you gaze long into the abyss, the abyss also gazes into you.
过于执着就会陷入其中,迷失自己,困住自己。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-10-17 00:42:41 | 显示全部楼层
krguang 发表于 2017-10-16 19:02
原子哥,你有用VS写过STM32么?
感觉比keil好用太多太多。。。。

没有
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2017-10-13
在线时间
39 小时
 楼主| 发表于 2017-11-3 10:31:51 | 显示全部楼层
问题解决了.
http://www.openedv.com/forum.php ... 3&fromuid=90222

加入这个层主大神的代码就好了
回复

使用道具 举报

23

主题

114

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2014-3-9
在线时间
103 小时
发表于 2017-11-3 16:31:27 | 显示全部楼层
你那个wifi好像是用来定位的吧,模块是不是还有连接2G网络
回复

使用道具 举报

2

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2017-10-13
在线时间
39 小时
 楼主| 发表于 2017-11-3 20:06:28 | 显示全部楼层
huang_liquan 发表于 2017-11-3 16:31
你那个wifi好像是用来定位的吧,模块是不是还有连接2G网络

我在做一个项目,用GPRS 模块或者WiFi 模块把医院的温湿度,空调机组起停,水阀加湿器开度之类的数据显示在手机上。也可以简单控制下。
我看你好像有用vscode写stm32?我特别想在macOS 下写,但是网上找了好多方法都超级麻烦,要自己写makefile?
不知道你有啥简单的方法不?
回复

使用道具 举报

23

主题

114

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2014-3-9
在线时间
103 小时
发表于 2017-11-6 11:06:00 | 显示全部楼层
krguang 发表于 2017-11-3 20:06
我在做一个项目,用GPRS 模块或者WiFi 模块把医院的温湿度,空调机组起停,水阀加湿器开度之类的数据显示 ...

我那个模板不好用吗
魔法王子
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 05:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表