你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

自定义函数,替代printf函数

[复制链接]
lusonghua 发布时间:2015-7-13 17:29
大家在调试时一般用了不少printf函数吧,在keil里怎么用printf,以及怎么重定向输出到串口上大家应该都比较熟悉了。
$ p0 h% J( d3 l3 H/ [$ q5 s; Y" J但在使用printf函数时大家还是小心一些,前几天在调试程序时碰到了在循环里使用printf函数调试导致程序堵死,折腾了好几天,后来问黑金的版主才知道问题出在printf函数上,注释掉就可以了。
+ l5 s% z# ^3 F5 j7 i
4 P& R1 ~8 B, C# R这里我贴上一些代码,用自定义的函数替代printf,希望对大家有些帮助。
& x7 a8 d; {0 _5 X, n( K3 `7 @$ _( P; J; F5 a- i1 M
void cli_puts(char* sz)
, x/ l; b' n, c9 A' p0 z. y{# p( n8 s% i, g: ^3 |" m' B
/* 这里添加在某串口输出字符串的代码 */
/ G" A: }. e; k6 O2 Z( D' `; G! |9 W    char c;% o, k8 C2 t/ h3 c2 _5 D# c
    while ((c = *sz++) != 0) {5 r6 A& H! C7 P
         while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
2 K8 h/ }) k% k. v         USART_SendData(UART5, (uint16_t)c);, d6 [( q7 Z# @' U" P2 q) E9 P
    }! o! M* m+ v! D
}
7 b9 @* S( _2 l3 Y; A: D$ N5 J) X5 D: C
void cli_echo(const char* fmt, ...)
' I( f; V( h; r& s7 Z{
1 Y5 ]6 Q1 m8 Q- Zstatic char sz[1024] = { 0, };
0 p, @- M0 G$ H+ F0 X+ r4 n1 o8 d/* 组合使用可变参数以及vsprintf,实现printf */: a. l2 F& F% X& P
va_list ap;, I# K3 `5 A* a. J2 C: J
/ Q: R: [5 f6 v$ O1 J4 I- g+ B  Y
va_start(ap, fmt);
, F* B' H. h* ]2 J4 b7 o vsprintf(sz, fmt, ap);
$ t; W/ ]% e2 y1 R6 n' |4 r/ o cli_puts(sz);
# g$ s/ ], P( g& t$ {+ Y va_end(ap);2 a3 e7 N/ X& I& d" T" p
}; r! R4 W# w" H% N2 Z6 L# C1 L

6 \# }+ I) L/ ~3 g1 ?上述cli_echo函数即可以替代printf函数的功能。1 C; O. a3 E. F3 |/ N$ w- F* B; L
3 f4 q: b" r+ \
7 ?5 ^9 z! a+ k; K  E1 E* T$ N
0 ^$ C7 {$ P- Q* N! D  m% B1 V
收藏 1 评论20 发布时间:2015-7-13 17:29

举报

20个回答
嘉木香 回答时间:2017-4-5 16:06:10
老师教的串口调试的用法:4 ?1 {( J1 `6 S. D1 }* U+ k
前提:STDIO.H,自建的发送字符串函数;% T6 K. K8 {4 t1 I
使用方式:
; t3 i4 {! u, v步骤:1.调用sprintf()函数,此函数用法与printf()基本一致,两者输出不同,Printf()函数直接硬件输出,sprintf()输出到其形参字符串中;
6 }& b. b2 l% Y# c& K. b0 ~2.输出sprintf()中的形参字符串;# h2 x: L+ `) ]! D9 ^0 \+ @
附STDIO.H中printf(),sprint()的定义,区别之处以加粗倾倒发红
) A/ P; h2 _, s0 h- [5 J- m# X
extern int printf   (const char *, ...);
& e4 H8 I4 g( ], E: vextern int sprintf  (char *, const char *, ...);

$ H# [" e/ K: {3 g, W, _6 }
gavinliang 回答时间:2017-4-5 16:32:28
void cli_echo(const char* fmt, ...). a! v% \: O6 m( x
{
& m4 [/ k, a; J+ G, ystatic char sz[1024] = { 0, };9 [) C/ D; }' B. I& G
/* 组合使用可变参数以及vsprintf,实现printf */+ k6 C- V7 a( A
va_list ap;  R, t# b4 a- r& r2 b2 r' Z+ `
, A) h  c# [/ Z( U! A
va_start(ap, fmt);, }# K& C% M2 A# ]
vsprintf(sz, fmt, ap); ) a) {" I( Z8 D6 o( ]3 d
cli_puts(sz);" B0 {; i& D: Q
va_end(ap);
: a' K) i& j3 s, }}% S$ o$ i, z  i- M; Y3 A( F
/ ^0 e$ v3 n; g- T% G
这个没看明白。知道是格式组合,但具体 每一个函数怎么实现的?
嘉木香 回答时间:2017-4-5 16:09:05
补充一下,这个方法比重定向更为方便,而且不受输出数量限制;相比较自己编写而言,又极大化的利用了标准库,个人及其喜欢。
笑鸟007 回答时间:2015-7-13 18:33:30
好厉害!!!
mark0668 回答时间:2015-7-13 19:06:24
某些代码是会和printf有冲口 ,具说是用了内置内存管理发生冲突的.今天我也遇到了.
wyxy163@126.com 回答时间:2015-7-13 19:14:49
提示: 作者被禁止或删除 内容自动屏蔽
jiaswang 回答时间:2015-7-14 08:35:09
一直没用过printf在keil里……
stary666 回答时间:2015-7-14 12:08:29
看看,,,,,,,
HenryChen 回答时间:2015-7-14 17:58:02
学习一下,
天涯水乡 回答时间:2015-7-14 18:04:33
不错,顶一下
Rlews 回答时间:2015-7-14 22:57:01
学习学习~~
moyanming2013 回答时间:2015-7-14 23:26:57
哈哈,变相的好做法,不过可以不用自己再写个cli_puts()函数了,直接把sz用print输出即可吧
Tension 回答时间:2015-7-15 11:59:16
之前用SWD调试时,用printf()得比较多,现在已经转到更快的方式了。
不撸僧 回答时间:2015-7-15 14:13:20
一直用printf 挺好用的 还没发现问题
yanhaijian 回答时间:2015-7-15 15:59:39
只要对fputc、fgetc这两个函数进行重定义就可以了。
gavinliang 回答时间:2017-4-5 13:57:42
一直在使用printf()函数,没发现有什么问题,只是编译时,占比较多空间,这是最不好的。
12下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版